This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-dbutils.git
The following commit(s) were added to refs/heads/master by this push: new e260afd Javadoc @see tags do not need to use a FQCN for classes in java.lang e260afd is described below commit e260afd43121791e270fbb5c510151522711c724 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Mon Aug 29 07:11:16 2022 -0400 Javadoc @see tags do not need to use a FQCN for classes in java.lang --- .../apache/commons/dbutils/BasicRowProcessor.java | 550 ++--- .../dbutils/wrappers/SqlNullCheckedResultSet.java | 2 +- .../dbutils/wrappers/StringTrimmedResultSet.java | 216 +- .../wrappers/SqlNullCheckedResultSetTest.java | 2106 ++++++++++---------- 4 files changed, 1437 insertions(+), 1437 deletions(-) diff --git a/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java b/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java index da52524..fdfd0da 100644 --- a/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java +++ b/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java @@ -1,275 +1,275 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.dbutils; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * Basic implementation of the {@code RowProcessor} interface. - * - * <p> - * This class is thread-safe. - * </p> - * - * @see RowProcessor - */ -public class BasicRowProcessor implements RowProcessor { - - /** - * The default BeanProcessor instance to use if not supplied in the - * constructor. - */ - private static final BeanProcessor defaultConvert = new BeanProcessor(); - - /** - * The Singleton instance of this class. - */ - private static final BasicRowProcessor instance = new BasicRowProcessor(); - - protected static Map<String, Object> createCaseInsensitiveHashMap(final int cols) { - return new CaseInsensitiveHashMap(cols); - } - - /** - * Returns the Singleton instance of this class. - * - * @return The single instance of this class. - * @deprecated Create instances with the constructors instead. This will - * be removed after DbUtils 1.1. - */ - @Deprecated - public static BasicRowProcessor instance() { - return instance; - } - - /** - * Use this to process beans. - */ - private final BeanProcessor convert; - - /** - * BasicRowProcessor constructor. Bean processing defaults to a - * BeanProcessor instance. - */ - public BasicRowProcessor() { - this(defaultConvert); - } - - /** - * BasicRowProcessor constructor. - * @param convert The BeanProcessor to use when converting columns to - * bean properties. - * @since DbUtils 1.1 - */ - public BasicRowProcessor(final BeanProcessor convert) { - this.convert = convert; - } - - /** - * Convert a {@code ResultSet} row into an {@code Object[]}. - * This implementation copies column values into the array in the same - * order they're returned from the {@code ResultSet}. Array elements - * will be set to {@code null} if the column was SQL NULL. - * - * @see org.apache.commons.dbutils.RowProcessor#toArray(java.sql.ResultSet) - * @param rs ResultSet that supplies the array data - * @throws SQLException if a database access error occurs - * @return the newly created array - */ - @Override - public Object[] toArray(final ResultSet rs) throws SQLException { - final ResultSetMetaData meta = rs.getMetaData(); - final int cols = meta.getColumnCount(); - final Object[] result = new Object[cols]; - - for (int i = 0; i < cols; i++) { - result[i] = rs.getObject(i + 1); - } - - return result; - } - - /** - * Convert a {@code ResultSet} row into a JavaBean. This - * implementation delegates to a BeanProcessor instance. - * @see org.apache.commons.dbutils.RowProcessor#toBean(java.sql.ResultSet, java.lang.Class) - * @see org.apache.commons.dbutils.BeanProcessor#toBean(java.sql.ResultSet, java.lang.Class) - * @param <T> The type of bean to create - * @param rs ResultSet that supplies the bean data - * @param type Class from which to create the bean instance - * @throws SQLException if a database access error occurs - * @return the newly created bean - */ - @Override - public <T> T toBean(final ResultSet rs, final Class<? extends T> type) throws SQLException { - return this.convert.toBean(rs, type); - } - - /** - * Convert a {@code ResultSet} into a {@code List} of JavaBeans. - * This implementation delegates to a BeanProcessor instance. - * @see org.apache.commons.dbutils.RowProcessor#toBeanList(java.sql.ResultSet, java.lang.Class) - * @see org.apache.commons.dbutils.BeanProcessor#toBeanList(java.sql.ResultSet, java.lang.Class) - * @param <T> The type of bean to create - * @param rs ResultSet that supplies the bean data - * @param type Class from which to create the bean instance - * @throws SQLException if a database access error occurs - * @return A {@code List} of beans with the given type in the order - * they were returned by the {@code ResultSet}. - */ - @Override - public <T> List<T> toBeanList(final ResultSet rs, final Class<? extends T> type) throws SQLException { - return this.convert.toBeanList(rs, type); - } - - /** - * Convert a {@code ResultSet} row into a {@code Map}. - * - * <p> - * This implementation returns a {@code Map} with case insensitive column names as keys. Calls to - * {@code map.get("COL")} and {@code map.get("col")} return the same value. Furthermore this implementation - * will return an ordered map, that preserves the ordering of the columns in the ResultSet, so that iterating over - * the entry set of the returned map will return the first column of the ResultSet, then the second and so forth. - * </p> - * - * @param rs ResultSet that supplies the map data - * @return the newly created Map - * @throws SQLException if a database access error occurs - * @see org.apache.commons.dbutils.RowProcessor#toMap(java.sql.ResultSet) - */ - @Override - public Map<String, Object> toMap(final ResultSet rs) throws SQLException { - final ResultSetMetaData rsmd = rs.getMetaData(); - final int cols = rsmd.getColumnCount(); - final Map<String, Object> result = createCaseInsensitiveHashMap(cols); - - for (int i = 1; i <= cols; i++) { - String columnName = rsmd.getColumnLabel(i); - if (null == columnName || 0 == columnName.length()) { - columnName = rsmd.getColumnName(i); - } - result.put(columnName, rs.getObject(i)); - } - - return result; - } - - - /** - * A Map that converts all keys to lowercase Strings for case insensitive - * lookups. This is needed for the toMap() implementation because - * databases don't consistently handle the casing of column names. - * - * <p>The keys are stored as they are given [BUG #DBUTILS-34], so we maintain - * an internal mapping from lowercase keys to the real keys in order to - * achieve the case insensitive lookup. - * - * <p>Note: This implementation does not allow {@code null} - * for key, whereas {@link LinkedHashMap} does, because of the code: - * <pre> - * key.toString().toLowerCase() - * </pre> - */ - private static final class CaseInsensitiveHashMap extends LinkedHashMap<String, Object> { - - private CaseInsensitiveHashMap(final int initialCapacity) { - super(initialCapacity); - } - - /** - * The internal mapping from lowercase keys to the real keys. - * - * <p> - * Any query operation using the key - * ({@link #get(Object)}, {@link #containsKey(Object)}) - * is done in three steps: - * <ul> - * <li>convert the parameter key to lower case</li> - * <li>get the actual key that corresponds to the lower case key</li> - * <li>query the map with the actual key</li> - * </ul> - * </p> - */ - private final Map<String, String> lowerCaseMap = new HashMap<>(); - - /** - * Required for serialization support. - * - * @see java.io.Serializable - */ - private static final long serialVersionUID = -2848100435296897392L; - - /** {@inheritDoc} */ - @Override - public boolean containsKey(final Object key) { - final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH)); - return super.containsKey(realKey); - // Possible optimisation here: - // Since the lowerCaseMap contains a mapping for all the keys, - // we could just do this: - // return lowerCaseMap.containsKey(key.toString().toLowerCase()); - } - - /** {@inheritDoc} */ - @Override - public Object get(final Object key) { - final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH)); - return super.get(realKey); - } - - /** {@inheritDoc} */ - @Override - public Object put(final String key, final Object value) { - /* - * In order to keep the map and lowerCaseMap synchronized, - * we have to remove the old mapping before putting the - * new one. Indeed, oldKey and key are not necessaliry equals. - * (That's why we call super.remove(oldKey) and not just - * super.put(key, value)) - */ - final Object oldKey = lowerCaseMap.put(key.toLowerCase(Locale.ENGLISH), key); - final Object oldValue = super.remove(oldKey); - super.put(key, value); - return oldValue; - } - - /** {@inheritDoc} */ - @Override - public void putAll(final Map<? extends String, ?> m) { - for (final Map.Entry<? extends String, ?> entry : m.entrySet()) { - final String key = entry.getKey(); - final Object value = entry.getValue(); - this.put(key, value); - } - } - - /** {@inheritDoc} */ - @Override - public Object remove(final Object key) { - final Object realKey = lowerCaseMap.remove(key.toString().toLowerCase(Locale.ENGLISH)); - return super.remove(realKey); - } - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.dbutils; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * Basic implementation of the {@code RowProcessor} interface. + * + * <p> + * This class is thread-safe. + * </p> + * + * @see RowProcessor + */ +public class BasicRowProcessor implements RowProcessor { + + /** + * The default BeanProcessor instance to use if not supplied in the + * constructor. + */ + private static final BeanProcessor defaultConvert = new BeanProcessor(); + + /** + * The Singleton instance of this class. + */ + private static final BasicRowProcessor instance = new BasicRowProcessor(); + + protected static Map<String, Object> createCaseInsensitiveHashMap(final int cols) { + return new CaseInsensitiveHashMap(cols); + } + + /** + * Returns the Singleton instance of this class. + * + * @return The single instance of this class. + * @deprecated Create instances with the constructors instead. This will + * be removed after DbUtils 1.1. + */ + @Deprecated + public static BasicRowProcessor instance() { + return instance; + } + + /** + * Use this to process beans. + */ + private final BeanProcessor convert; + + /** + * BasicRowProcessor constructor. Bean processing defaults to a + * BeanProcessor instance. + */ + public BasicRowProcessor() { + this(defaultConvert); + } + + /** + * BasicRowProcessor constructor. + * @param convert The BeanProcessor to use when converting columns to + * bean properties. + * @since DbUtils 1.1 + */ + public BasicRowProcessor(final BeanProcessor convert) { + this.convert = convert; + } + + /** + * Convert a {@code ResultSet} row into an {@code Object[]}. + * This implementation copies column values into the array in the same + * order they're returned from the {@code ResultSet}. Array elements + * will be set to {@code null} if the column was SQL NULL. + * + * @see org.apache.commons.dbutils.RowProcessor#toArray(java.sql.ResultSet) + * @param rs ResultSet that supplies the array data + * @throws SQLException if a database access error occurs + * @return the newly created array + */ + @Override + public Object[] toArray(final ResultSet rs) throws SQLException { + final ResultSetMetaData meta = rs.getMetaData(); + final int cols = meta.getColumnCount(); + final Object[] result = new Object[cols]; + + for (int i = 0; i < cols; i++) { + result[i] = rs.getObject(i + 1); + } + + return result; + } + + /** + * Convert a {@code ResultSet} row into a JavaBean. This + * implementation delegates to a BeanProcessor instance. + * @see org.apache.commons.dbutils.RowProcessor#toBean(java.sql.ResultSet, Class) + * @see org.apache.commons.dbutils.BeanProcessor#toBean(java.sql.ResultSet, Class) + * @param <T> The type of bean to create + * @param rs ResultSet that supplies the bean data + * @param type Class from which to create the bean instance + * @throws SQLException if a database access error occurs + * @return the newly created bean + */ + @Override + public <T> T toBean(final ResultSet rs, final Class<? extends T> type) throws SQLException { + return this.convert.toBean(rs, type); + } + + /** + * Convert a {@code ResultSet} into a {@code List} of JavaBeans. + * This implementation delegates to a BeanProcessor instance. + * @see org.apache.commons.dbutils.RowProcessor#toBeanList(java.sql.ResultSet, Class) + * @see org.apache.commons.dbutils.BeanProcessor#toBeanList(java.sql.ResultSet, Class) + * @param <T> The type of bean to create + * @param rs ResultSet that supplies the bean data + * @param type Class from which to create the bean instance + * @throws SQLException if a database access error occurs + * @return A {@code List} of beans with the given type in the order + * they were returned by the {@code ResultSet}. + */ + @Override + public <T> List<T> toBeanList(final ResultSet rs, final Class<? extends T> type) throws SQLException { + return this.convert.toBeanList(rs, type); + } + + /** + * Convert a {@code ResultSet} row into a {@code Map}. + * + * <p> + * This implementation returns a {@code Map} with case insensitive column names as keys. Calls to + * {@code map.get("COL")} and {@code map.get("col")} return the same value. Furthermore this implementation + * will return an ordered map, that preserves the ordering of the columns in the ResultSet, so that iterating over + * the entry set of the returned map will return the first column of the ResultSet, then the second and so forth. + * </p> + * + * @param rs ResultSet that supplies the map data + * @return the newly created Map + * @throws SQLException if a database access error occurs + * @see org.apache.commons.dbutils.RowProcessor#toMap(java.sql.ResultSet) + */ + @Override + public Map<String, Object> toMap(final ResultSet rs) throws SQLException { + final ResultSetMetaData rsmd = rs.getMetaData(); + final int cols = rsmd.getColumnCount(); + final Map<String, Object> result = createCaseInsensitiveHashMap(cols); + + for (int i = 1; i <= cols; i++) { + String columnName = rsmd.getColumnLabel(i); + if (null == columnName || 0 == columnName.length()) { + columnName = rsmd.getColumnName(i); + } + result.put(columnName, rs.getObject(i)); + } + + return result; + } + + + /** + * A Map that converts all keys to lowercase Strings for case insensitive + * lookups. This is needed for the toMap() implementation because + * databases don't consistently handle the casing of column names. + * + * <p>The keys are stored as they are given [BUG #DBUTILS-34], so we maintain + * an internal mapping from lowercase keys to the real keys in order to + * achieve the case insensitive lookup. + * + * <p>Note: This implementation does not allow {@code null} + * for key, whereas {@link LinkedHashMap} does, because of the code: + * <pre> + * key.toString().toLowerCase() + * </pre> + */ + private static final class CaseInsensitiveHashMap extends LinkedHashMap<String, Object> { + + private CaseInsensitiveHashMap(final int initialCapacity) { + super(initialCapacity); + } + + /** + * The internal mapping from lowercase keys to the real keys. + * + * <p> + * Any query operation using the key + * ({@link #get(Object)}, {@link #containsKey(Object)}) + * is done in three steps: + * <ul> + * <li>convert the parameter key to lower case</li> + * <li>get the actual key that corresponds to the lower case key</li> + * <li>query the map with the actual key</li> + * </ul> + * </p> + */ + private final Map<String, String> lowerCaseMap = new HashMap<>(); + + /** + * Required for serialization support. + * + * @see java.io.Serializable + */ + private static final long serialVersionUID = -2848100435296897392L; + + /** {@inheritDoc} */ + @Override + public boolean containsKey(final Object key) { + final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH)); + return super.containsKey(realKey); + // Possible optimisation here: + // Since the lowerCaseMap contains a mapping for all the keys, + // we could just do this: + // return lowerCaseMap.containsKey(key.toString().toLowerCase()); + } + + /** {@inheritDoc} */ + @Override + public Object get(final Object key) { + final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH)); + return super.get(realKey); + } + + /** {@inheritDoc} */ + @Override + public Object put(final String key, final Object value) { + /* + * In order to keep the map and lowerCaseMap synchronized, + * we have to remove the old mapping before putting the + * new one. Indeed, oldKey and key are not necessaliry equals. + * (That's why we call super.remove(oldKey) and not just + * super.put(key, value)) + */ + final Object oldKey = lowerCaseMap.put(key.toLowerCase(Locale.ENGLISH), key); + final Object oldValue = super.remove(oldKey); + super.put(key, value); + return oldValue; + } + + /** {@inheritDoc} */ + @Override + public void putAll(final Map<? extends String, ?> m) { + for (final Map.Entry<? extends String, ?> entry : m.entrySet()) { + final String key = entry.getKey(); + final Object value = entry.getValue(); + this.put(key, value); + } + } + + /** {@inheritDoc} */ + @Override + public Object remove(final Object key) { + final Object realKey = lowerCaseMap.remove(key.toString().toLowerCase(Locale.ENGLISH)); + return super.remove(realKey); + } + } + +} diff --git a/src/main/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSet.java b/src/main/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSet.java index e2dd7fe..5bfc1f5 100644 --- a/src/main/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSet.java +++ b/src/main/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSet.java @@ -374,7 +374,7 @@ public class SqlNullCheckedResultSet implements InvocationHandler { * {@code getNull*} method if the {@code ResultSet} returned * {@code null}. * - * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) + * @see java.lang.reflect.InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[]) * @param proxy Not used; all method calls go to the internal result set * @param method The method to invoke on the result set * @param args The arguments to pass to the result set diff --git a/src/main/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSet.java b/src/main/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSet.java index d202e10..634c7d4 100644 --- a/src/main/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSet.java +++ b/src/main/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSet.java @@ -1,108 +1,108 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.dbutils.wrappers; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.sql.ResultSet; - -import org.apache.commons.dbutils.ProxyFactory; - -/** - * Wraps a {@code ResultSet} to trim strings returned by the - * {@code getString()} and {@code getObject()} methods. - * - * <p> - * Usage Example: - * This example shows how to decorate ResultSets so processing continues as - * normal but all Strings are trimmed before being returned from the - * {@code ResultSet}. - * </p> - * - * <pre> - * ResultSet rs = // somehow get a ResultSet; - * - * // Substitute wrapped ResultSet with additional behavior for real ResultSet - * rs = StringTrimmedResultSet.wrap(rs); - * - * // Pass wrapped ResultSet to processor - * List list = new BasicRowProcessor().toBeanList(rs); - * </pre> - */ -public class StringTrimmedResultSet implements InvocationHandler { - - /** - * The factory to create proxies with. - */ - private static final ProxyFactory factory = ProxyFactory.instance(); - - /** - * Wraps the {@code ResultSet} in an instance of this class. This is - * equivalent to: - * <pre> - * ProxyFactory.instance().createResultSet(new StringTrimmedResultSet(rs)); - * </pre> - * - * @param rs The {@code ResultSet} to wrap. - * @return wrapped ResultSet - */ - public static ResultSet wrap(final ResultSet rs) { - return factory.createResultSet(new StringTrimmedResultSet(rs)); - } - - /** - * The wrapped result. - */ - private final ResultSet rs; - - /** - * Constructs a new instance of {@code StringTrimmedResultSet} - * to wrap the specified {@code ResultSet}. - * @param rs ResultSet to wrap - */ - public StringTrimmedResultSet(final ResultSet rs) { - this.rs = rs; - } - - /** - * Intercept calls to the {@code getString()} and - * {@code getObject()} methods and trim any Strings before they're - * returned. - * - * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) - * @param proxy Not used; all method calls go to the internal result set - * @param method The method to invoke on the result set - * @param args The arguments to pass to the result set - * @return string trimmed result - * @throws Throwable error - */ - @Override - public Object invoke(final Object proxy, final Method method, final Object[] args) - throws Throwable { - - Object result = method.invoke(this.rs, args); - - if (result instanceof String - && (method.getName().equals("getObject") - || method.getName().equals("getString"))) { - result = ((String) result).trim(); - } - - return result; - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.dbutils.wrappers; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.sql.ResultSet; + +import org.apache.commons.dbutils.ProxyFactory; + +/** + * Wraps a {@code ResultSet} to trim strings returned by the + * {@code getString()} and {@code getObject()} methods. + * + * <p> + * Usage Example: + * This example shows how to decorate ResultSets so processing continues as + * normal but all Strings are trimmed before being returned from the + * {@code ResultSet}. + * </p> + * + * <pre> + * ResultSet rs = // somehow get a ResultSet; + * + * // Substitute wrapped ResultSet with additional behavior for real ResultSet + * rs = StringTrimmedResultSet.wrap(rs); + * + * // Pass wrapped ResultSet to processor + * List list = new BasicRowProcessor().toBeanList(rs); + * </pre> + */ +public class StringTrimmedResultSet implements InvocationHandler { + + /** + * The factory to create proxies with. + */ + private static final ProxyFactory factory = ProxyFactory.instance(); + + /** + * Wraps the {@code ResultSet} in an instance of this class. This is + * equivalent to: + * <pre> + * ProxyFactory.instance().createResultSet(new StringTrimmedResultSet(rs)); + * </pre> + * + * @param rs The {@code ResultSet} to wrap. + * @return wrapped ResultSet + */ + public static ResultSet wrap(final ResultSet rs) { + return factory.createResultSet(new StringTrimmedResultSet(rs)); + } + + /** + * The wrapped result. + */ + private final ResultSet rs; + + /** + * Constructs a new instance of {@code StringTrimmedResultSet} + * to wrap the specified {@code ResultSet}. + * @param rs ResultSet to wrap + */ + public StringTrimmedResultSet(final ResultSet rs) { + this.rs = rs; + } + + /** + * Intercept calls to the {@code getString()} and + * {@code getObject()} methods and trim any Strings before they're + * returned. + * + * @see java.lang.reflect.InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[]) + * @param proxy Not used; all method calls go to the internal result set + * @param method The method to invoke on the result set + * @param args The arguments to pass to the result set + * @return string trimmed result + * @throws Throwable error + */ + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) + throws Throwable { + + Object result = method.invoke(this.rs, args); + + if (result instanceof String + && (method.getName().equals("getObject") + || method.getName().equals("getString"))) { + result = ((String) result).trim(); + } + + return result; + } + +} diff --git a/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java b/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java index 0269fe2..600b3e0 100644 --- a/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java +++ b/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java @@ -1,1053 +1,1053 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.dbutils.wrappers; - -import java.io.ByteArrayInputStream; -import java.io.CharArrayReader; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.net.MalformedURLException; -import java.net.URL; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Ref; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Map; - -import org.apache.commons.dbutils.BaseTestCase; -import org.apache.commons.dbutils.ProxyFactory; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * Test cases for {@code SqlNullCheckedResultSet} class. - */ -public class SqlNullCheckedResultSetTest extends BaseTestCase { - - private SqlNullCheckedResultSet rs2 = null; - - /** - * Sets up instance variables required by this test case. - */ - @Override - public void setUp() throws Exception { - super.setUp(); - - rs2 = - new SqlNullCheckedResultSet( - ProxyFactory.instance().createResultSet( - new SqlNullUncheckedMockResultSet())); - - rs = ProxyFactory.instance().createResultSet(rs2); // Override superclass field - } - - /** - * Tests the getAsciiStream implementation. - */ - public void testGetAsciiStream() throws SQLException { - - assertNull(rs.getAsciiStream(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getAsciiStream("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final InputStream stream = new ByteArrayInputStream(new byte[0]); - rs2.setNullAsciiStream(stream); - assertNotNull(rs.getAsciiStream(1)); - assertEquals(stream, rs.getAsciiStream(1)); - assertNotNull(rs.getAsciiStream("column")); - assertEquals(stream, rs.getAsciiStream("column")); - - } - - /** - * Tests the getBigDecimal implementation. - */ - public void testGetBigDecimal() throws SQLException { - - assertNull(rs.getBigDecimal(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getBigDecimal("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final BigDecimal bd = new BigDecimal(5.0); - rs2.setNullBigDecimal(bd); - assertNotNull(rs.getBigDecimal(1)); - assertEquals(bd, rs.getBigDecimal(1)); - assertNotNull(rs.getBigDecimal("column")); - assertEquals(bd, rs.getBigDecimal("column")); - - } - - /** - * Tests the getBinaryStream implementation. - */ - public void testGetBinaryStream() throws SQLException { - - assertNull(rs.getBinaryStream(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getBinaryStream("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final InputStream stream = new ByteArrayInputStream(new byte[0]); - rs2.setNullBinaryStream(stream); - assertNotNull(rs.getBinaryStream(1)); - assertEquals(stream, rs.getBinaryStream(1)); - assertNotNull(rs.getBinaryStream("column")); - assertEquals(stream, rs.getBinaryStream("column")); - - } - - /** - * Tests the getBlob implementation. - */ - public void testGetBlob() throws SQLException { - - assertNull(rs.getBlob(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getBlob("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final Blob blob = new SqlNullCheckedResultSetMockBlob(); - rs2.setNullBlob(blob); - assertNotNull(rs.getBlob(1)); - assertEquals(blob, rs.getBlob(1)); - assertNotNull(rs.getBlob("column")); - assertEquals(blob, rs.getBlob("column")); - - } - - /** - * Tests the getBoolean implementation. - */ - public void testGetBoolean() throws SQLException { - - assertEquals(false, rs.getBoolean(1)); - assertTrue(rs.wasNull()); - assertEquals(false, rs.getBoolean("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - rs2.setNullBoolean(true); - assertEquals(true, rs.getBoolean(1)); - assertEquals(true, rs.getBoolean("column")); - - } - - /** - * Tests the getByte implementation. - */ - public void testGetByte() throws SQLException { - - assertEquals((byte) 0, rs.getByte(1)); - assertTrue(rs.wasNull()); - assertEquals((byte) 0, rs.getByte("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final byte b = (byte) 10; - rs2.setNullByte(b); - assertEquals(b, rs.getByte(1)); - assertEquals(b, rs.getByte("column")); - - } - - /** - * Tests the getByte implementation. - */ - public void testGetBytes() throws SQLException { - - assertNull(rs.getBytes(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getBytes("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final byte[] b = new byte[5]; - for (int i = 0; i < 5; i++) { - b[0] = (byte) i; - } - rs2.setNullBytes(b); - assertNotNull(rs.getBytes(1)); - assertArrayEquals(b, rs.getBytes(1)); - assertNotNull(rs.getBytes("column")); - assertArrayEquals(b, rs.getBytes("column")); - - } - - private static void assertArrayEquals(final byte[] expected, final byte[] actual) { - if (expected == actual) { - return; - } - if (expected.length != actual.length) { - failNotEquals(null, Arrays.toString(expected), Arrays.toString(actual)); - } - for (int i = 0; i < expected.length; i++) { - final byte expectedItem = expected[i]; - final byte actualItem = actual[i]; - assertEquals("Array not equal at index " + i, expectedItem, actualItem); - } - } - - /** - * Tests the getCharacterStream implementation. - */ - public void testGetCharacterStream() throws SQLException { - - assertNull(rs.getCharacterStream(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getCharacterStream("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final Reader reader = new CharArrayReader("this is a string".toCharArray()); - rs2.setNullCharacterStream(reader); - assertNotNull(rs.getCharacterStream(1)); - assertEquals(reader, rs.getCharacterStream(1)); - assertNotNull(rs.getCharacterStream("column")); - assertEquals(reader, rs.getCharacterStream("column")); - - } - - /** - * Tests the getClob implementation. - */ - public void testGetClob() throws SQLException { - - assertNull(rs.getClob(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getClob("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final Clob clob = new SqlNullCheckedResultSetMockClob(); - rs2.setNullClob(clob); - assertNotNull(rs.getClob(1)); - assertEquals(clob, rs.getClob(1)); - assertNotNull(rs.getClob("column")); - assertEquals(clob, rs.getClob("column")); - - } - - /** - * Tests the getDate implementation. - */ - public void testGetDate() throws SQLException { - - assertNull(rs.getDate(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getDate("column")); - assertTrue(rs.wasNull()); - assertNull(rs.getDate(1, Calendar.getInstance())); - assertTrue(rs.wasNull()); - assertNull(rs.getDate("column", Calendar.getInstance())); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final java.sql.Date date = new java.sql.Date(new java.util.Date().getTime()); - rs2.setNullDate(date); - assertNotNull(rs.getDate(1)); - assertEquals(date, rs.getDate(1)); - assertNotNull(rs.getDate("column")); - assertEquals(date, rs.getDate("column")); - assertNotNull(rs.getDate(1, Calendar.getInstance())); - assertEquals(date, rs.getDate(1, Calendar.getInstance())); - assertNotNull(rs.getDate("column", Calendar.getInstance())); - assertEquals(date, rs.getDate("column", Calendar.getInstance())); - - } - - /** - * Tests the getDouble implementation. - */ - public void testGetDouble() throws SQLException { - - assertEquals(0.0, rs.getDouble(1), 0.0); - assertTrue(rs.wasNull()); - assertEquals(0.0, rs.getDouble("column"), 0.0); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final double d = 10.0; - rs2.setNullDouble(d); - assertEquals(d, rs.getDouble(1), 0.0); - assertEquals(d, rs.getDouble("column"), 0.0); - - } - - /** - * Tests the getFloat implementation. - */ - public void testGetFloat() throws SQLException { - assertEquals(0, rs.getFloat(1), 0.0); - assertTrue(rs.wasNull()); - assertEquals(0, rs.getFloat("column"), 0.0); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final float f = 10; - rs2.setNullFloat(f); - assertEquals(f, rs.getFloat(1), 0.0); - assertEquals(f, rs.getFloat("column"), 0.0); - } - - /** - * Tests the getInt implementation. - */ - public void testGetInt() throws SQLException { - assertEquals(0, rs.getInt(1)); - assertTrue(rs.wasNull()); - assertEquals(0, rs.getInt("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final int i = 10; - rs2.setNullInt(i); - assertEquals(i, rs.getInt(1)); - assertEquals(i, rs.getInt("column")); - } - - /** - * Tests the getLong implementation. - */ - public void testGetLong() throws SQLException { - assertEquals(0, rs.getLong(1)); - assertTrue(rs.wasNull()); - assertEquals(0, rs.getLong("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final long l = 10; - rs2.setNullLong(l); - assertEquals(l, rs.getLong(1)); - assertEquals(l, rs.getLong("column")); - } - - /** - * Tests the getObject implementation. - */ - public void testGetObject() throws SQLException { - - assertNull(rs.getObject(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getObject("column")); - assertTrue(rs.wasNull()); - assertNull(rs.getObject(1, (Map<String, Class<?>>) null)); - assertTrue(rs.wasNull()); - assertNull(rs.getObject("column", (Map<String, Class<?>>) null)); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final Object o = new Object(); - rs2.setNullObject(o); - assertNotNull(rs.getObject(1)); - assertEquals(o, rs.getObject(1)); - assertNotNull(rs.getObject("column")); - assertEquals(o, rs.getObject("column")); - assertNotNull(rs.getObject(1, (Map<String, Class<?>>) null)); - assertEquals(o, rs.getObject(1, (Map<String, Class<?>>) null)); - assertNotNull(rs.getObject("column", (Map<String, Class<?>>) null)); - assertEquals(o, rs.getObject("column", (Map<String, Class<?>>) null)); - - } - - /** - * Tests the getRef implementation. - */ - public void testGetRef() throws SQLException { - - assertNull(rs.getRef(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getRef("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final Ref ref = new SqlNullCheckedResultSetMockRef(); - rs2.setNullRef(ref); - assertNotNull(rs.getRef(1)); - assertEquals(ref, rs.getRef(1)); - assertNotNull(rs.getRef("column")); - assertEquals(ref, rs.getRef("column")); - - } - - /** - * Tests the getShort implementation. - */ - public void testGetShort() throws SQLException { - - assertEquals((short) 0, rs.getShort(1)); - assertTrue(rs.wasNull()); - assertEquals((short) 0, rs.getShort("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final short s = (short) 10; - rs2.setNullShort(s); - assertEquals(s, rs.getShort(1)); - assertEquals(s, rs.getShort("column")); - } - - /** - * Tests the getString implementation. - */ - public void testGetString() throws SQLException { - assertEquals(null, rs.getString(1)); - assertTrue(rs.wasNull()); - assertEquals(null, rs.getString("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final String s = "hello, world"; - rs2.setNullString(s); - assertEquals(s, rs.getString(1)); - assertEquals(s, rs.getString("column")); - } - - /** - * Tests the getTime implementation. - */ - public void testGetTime() throws SQLException { - - assertNull(rs.getTime(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getTime("column")); - assertTrue(rs.wasNull()); - assertNull(rs.getTime(1, Calendar.getInstance())); - assertTrue(rs.wasNull()); - assertNull(rs.getTime("column", Calendar.getInstance())); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final Time time = new Time(new java.util.Date().getTime()); - rs2.setNullTime(time); - assertNotNull(rs.getTime(1)); - assertEquals(time, rs.getTime(1)); - assertNotNull(rs.getTime("column")); - assertEquals(time, rs.getTime("column")); - assertNotNull(rs.getTime(1, Calendar.getInstance())); - assertEquals(time, rs.getTime(1, Calendar.getInstance())); - assertNotNull(rs.getTime("column", Calendar.getInstance())); - assertEquals(time, rs.getTime("column", Calendar.getInstance())); - - } - - /** - * Tests the getTimestamp implementation. - */ - public void testGetTimestamp() throws SQLException { - - assertNull(rs.getTimestamp(1)); - assertTrue(rs.wasNull()); - assertNull(rs.getTimestamp("column")); - assertTrue(rs.wasNull()); - assertNull(rs.getTimestamp(1, Calendar.getInstance())); - assertTrue(rs.wasNull()); - assertNull(rs.getTimestamp("column", Calendar.getInstance())); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final Timestamp ts = new Timestamp(new java.util.Date().getTime()); - rs2.setNullTimestamp(ts); - assertNotNull(rs.getTimestamp(1)); - assertEquals(ts, rs.getTimestamp(1)); - assertNotNull(rs.getTimestamp("column")); - assertEquals(ts, rs.getTimestamp("column")); - assertNotNull(rs.getTimestamp(1, Calendar.getInstance())); - assertEquals(ts, rs.getTimestamp(1, Calendar.getInstance())); - assertNotNull(rs.getTimestamp("column", Calendar.getInstance())); - assertEquals(ts, rs.getTimestamp("column", Calendar.getInstance())); - } - - /** - * Tests the getURL and setNullURL implementations. - * - * Uses reflection to allow for building under JDK 1.3. - */ - public void testURL() throws SQLException, MalformedURLException, - IllegalAccessException, IllegalArgumentException, - java.lang.reflect.InvocationTargetException - { - Method getUrlInt = null; - Method getUrlString = null; - try { - getUrlInt = ResultSet.class.getMethod("getURL", Integer.TYPE); - getUrlString = ResultSet.class.getMethod("getURL", String.class); - } catch(final NoSuchMethodException | SecurityException e) { - // ignore - } - if (getUrlInt != null && getUrlString != null) { - assertEquals(null, getUrlInt.invoke(rs, Integer.valueOf(1)) ); - assertTrue(rs.wasNull()); - assertEquals(null, getUrlString.invoke(rs, "column") ); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final URL u = new URL("http://www.apache.org"); - rs2.setNullURL(u); - assertEquals(u, getUrlInt.invoke(rs, Integer.valueOf(1)) ); - assertEquals(u, getUrlString.invoke(rs, "column") ); - } - } - - /** - * Tests the setNullAsciiStream implementation. - */ - public void testSetNullAsciiStream() throws SQLException { - - assertNull(rs2.getNullAsciiStream()); - // Set what gets returned to something other than the default - final InputStream stream = new ByteArrayInputStream(new byte[0]); - rs2.setNullAsciiStream(stream); - assertNotNull(rs.getAsciiStream(1)); - assertEquals(stream, rs.getAsciiStream(1)); - assertNotNull(rs.getAsciiStream("column")); - assertEquals(stream, rs.getAsciiStream("column")); - - } - - /** - * Tests the setNullBigDecimal implementation. - */ - public void testSetNullBigDecimal() throws SQLException { - - assertNull(rs2.getNullBigDecimal()); - // Set what gets returned to something other than the default - final BigDecimal bd = new BigDecimal(5.0); - rs2.setNullBigDecimal(bd); - assertNotNull(rs.getBigDecimal(1)); - assertEquals(bd, rs.getBigDecimal(1)); - assertNotNull(rs.getBigDecimal("column")); - assertEquals(bd, rs.getBigDecimal("column")); - - } - - /** - * Tests the setNullBinaryStream implementation. - */ - public void testSetNullBinaryStream() throws SQLException { - - assertNull(rs2.getNullBinaryStream()); - // Set what gets returned to something other than the default - final InputStream stream = new ByteArrayInputStream(new byte[0]); - rs2.setNullBinaryStream(stream); - assertNotNull(rs.getBinaryStream(1)); - assertEquals(stream, rs.getBinaryStream(1)); - assertNotNull(rs.getBinaryStream("column")); - assertEquals(stream, rs.getBinaryStream("column")); - - } - - /** - * Tests the setNullBlob implementation. - */ - public void testSetNullBlob() throws SQLException { - - assertNull(rs2.getNullBlob()); - // Set what gets returned to something other than the default - final Blob blob = new SqlNullCheckedResultSetMockBlob(); - rs2.setNullBlob(blob); - assertNotNull(rs.getBlob(1)); - assertEquals(blob, rs.getBlob(1)); - assertNotNull(rs.getBlob("column")); - assertEquals(blob, rs.getBlob("column")); - - } - - /** - * Tests the setNullBoolean implementation. - */ - public void testSetNullBoolean() throws SQLException { - - assertEquals(false, rs2.getNullBoolean()); - // Set what gets returned to something other than the default - rs2.setNullBoolean(true); - assertEquals(true, rs.getBoolean(1)); - assertEquals(true, rs.getBoolean("column")); - - } - - /** - * Tests the setNullByte implementation. - */ - public void testSetNullByte() throws SQLException { - - assertEquals((byte) 0, rs2.getNullByte()); - // Set what gets returned to something other than the default - final byte b = (byte) 10; - rs2.setNullByte(b); - assertEquals(b, rs.getByte(1)); - assertEquals(b, rs.getByte("column")); - - } - - /** - * Tests the setNullByte implementation. - */ - public void testSetNullBytes() throws SQLException { - // test the default, unset value - assertEquals(null, rs2.getNullBytes()); - - // test that setting null is safe - rs2.setNullBytes(null); - assertEquals(null, rs2.getNullBytes()); - - // Set what gets returned to something other than the default - final byte[] b = new byte[5]; - for (int i = 0; i < 5; i++) { - b[0] = (byte) i; - } - rs2.setNullBytes(b); - assertNotNull(rs.getBytes(1)); - assertArrayEquals(b, rs.getBytes(1)); - assertNotNull(rs.getBytes("column")); - assertArrayEquals(b, rs.getBytes("column")); - - } - - /** - * Tests the setNullCharacterStream implementation. - */ - public void testSetNullCharacterStream() throws SQLException { - - assertNull(rs2.getNullCharacterStream()); - // Set what gets returned to something other than the default - final Reader reader = new CharArrayReader("this is a string".toCharArray()); - rs2.setNullCharacterStream(reader); - assertNotNull(rs.getCharacterStream(1)); - assertEquals(reader, rs.getCharacterStream(1)); - assertNotNull(rs.getCharacterStream("column")); - assertEquals(reader, rs.getCharacterStream("column")); - - } - - /** - * Tests the setNullClob implementation. - */ - public void testSetNullClob() throws SQLException { - - assertNull(rs2.getNullClob()); - // Set what gets returned to something other than the default - final Clob clob = new SqlNullCheckedResultSetMockClob(); - rs2.setNullClob(clob); - assertNotNull(rs.getClob(1)); - assertEquals(clob, rs.getClob(1)); - assertNotNull(rs.getClob("column")); - assertEquals(clob, rs.getClob("column")); - - } - - /** - * Tests the setNullDate implementation. - */ - public void testSetNullDate() throws SQLException { - // test the default, unset value - assertEquals(null, rs2.getNullDate()); - - // test that setting null is safe - rs2.setNullDate(null); - assertEquals(null, rs2.getNullDate()); - - // Set what gets returned to something other than the default - final java.sql.Date date = new java.sql.Date(new java.util.Date().getTime()); - rs2.setNullDate(date); - assertNotNull(rs.getDate(1)); - assertEquals(date, rs.getDate(1)); - assertNotNull(rs.getDate("column")); - assertEquals(date, rs.getDate("column")); - assertNotNull(rs.getDate(1, Calendar.getInstance())); - assertEquals(date, rs.getDate(1, Calendar.getInstance())); - assertNotNull(rs.getDate("column", Calendar.getInstance())); - assertEquals(date, rs.getDate("column", Calendar.getInstance())); - - } - - /** - * Tests the setNullDouble implementation. - */ - public void testSetNullDouble() throws SQLException { - assertEquals(0.0, rs2.getNullDouble(), 0.0); - // Set what gets returned to something other than the default - final double d = 10.0; - rs2.setNullDouble(d); - assertEquals(d, rs.getDouble(1), 0.0); - assertEquals(d, rs.getDouble("column"), 0.0); - } - - /** - * Tests the setNullFloat implementation. - */ - public void testSetNullFloat() throws SQLException { - assertEquals((float) 0.0, rs2.getNullFloat(), 0.0); - // Set what gets returned to something other than the default - final float f = (float) 10.0; - rs2.setNullFloat(f); - assertEquals(f, rs.getFloat(1), 0.0); - assertEquals(f, rs.getFloat("column"), 0.0); - } - - /** - * Tests the setNullInt implementation. - */ - public void testSetNullInt() throws SQLException { - assertEquals(0, rs2.getNullInt()); - assertEquals(0, rs.getInt(1)); - assertTrue(rs.wasNull()); - assertEquals(0, rs.getInt("column")); - assertTrue(rs.wasNull()); - // Set what gets returned to something other than the default - final int i = 10; - rs2.setNullInt(i); - assertEquals(i, rs.getInt(1)); - assertEquals(i, rs.getInt("column")); - } - - /** - * Tests the setNullLong implementation. - */ - public void testSetNullLong() throws SQLException { - assertEquals(0, rs2.getNullLong()); - // Set what gets returned to something other than the default - final long l = 10; - rs2.setNullLong(l); - assertEquals(l, rs.getLong(1)); - assertEquals(l, rs.getLong("column")); - } - - /** - * Tests the setNullObject implementation. - */ - public void testSetNullObject() throws SQLException { - assertNull(rs2.getNullObject()); - // Set what gets returned to something other than the default - final Object o = new Object(); - rs2.setNullObject(o); - assertNotNull(rs.getObject(1)); - assertEquals(o, rs.getObject(1)); - assertNotNull(rs.getObject("column")); - assertEquals(o, rs.getObject("column")); - assertNotNull(rs.getObject(1, (Map<String, Class<?>>) null)); - assertEquals(o, rs.getObject(1, (Map<String, Class<?>>) null)); - assertNotNull(rs.getObject("column", (Map<String, Class<?>>) null)); - assertEquals(o, rs.getObject("column", (Map<String, Class<?>>) null)); - } - - /** - * Tests the setNullShort implementation. - */ - public void testSetNullShort() throws SQLException { - - assertEquals((short) 0, rs2.getNullShort()); - // Set what gets returned to something other than the default - final short s = (short) 10; - rs2.setNullShort(s); - assertEquals(s, rs.getShort(1)); - assertEquals(s, rs.getShort("column")); - - } - - /** - * Tests the setNullString implementation. - */ - public void testSetNullString() throws SQLException { - assertEquals(null, rs2.getNullString()); - // Set what gets returned to something other than the default - final String s = "hello, world"; - rs2.setNullString(s); - assertEquals(s, rs.getString(1)); - assertEquals(s, rs.getString("column")); - } - - /** - * Tests the setNullRef implementation. - */ - public void testSetNullRef() throws SQLException { - assertNull(rs2.getNullRef()); - // Set what gets returned to something other than the default - final Ref ref = new SqlNullCheckedResultSetMockRef(); - rs2.setNullRef(ref); - assertNotNull(rs.getRef(1)); - assertEquals(ref, rs.getRef(1)); - assertNotNull(rs.getRef("column")); - assertEquals(ref, rs.getRef("column")); - } - - /** - * Tests the setNullTime implementation. - */ - public void testSetNullTime() throws SQLException { - // test the default, unset value - assertEquals(null, rs2.getNullTime()); - - // test that setting null is safe - rs2.setNullTime(null); - assertEquals(null, rs2.getNullTime()); - - // Set what gets returned to something other than the default - final Time time = new Time(new java.util.Date().getTime()); - rs2.setNullTime(time); - assertNotNull(rs.getTime(1)); - assertEquals(time, rs.getTime(1)); - assertNotNull(rs.getTime("column")); - assertEquals(time, rs.getTime("column")); - assertNotNull(rs.getTime(1, Calendar.getInstance())); - assertEquals(time, rs.getTime(1, Calendar.getInstance())); - assertNotNull(rs.getTime("column", Calendar.getInstance())); - assertEquals(time, rs.getTime("column", Calendar.getInstance())); - } - - /** - * Tests the setNullTimestamp implementation. - */ - public void testSetNullTimestamp() throws SQLException { - // test the default, unset value - assertEquals(null, rs2.getNullTimestamp()); - - // test that setting null is safe - rs2.setNullTimestamp(null); - assertEquals(null, rs2.getNullTimestamp()); - - // Set what gets returned to something other than the default - final Timestamp ts = new Timestamp(new java.util.Date().getTime()); - rs2.setNullTimestamp(ts); - assertNotNull(rs.getTimestamp(1)); - assertEquals(ts, rs.getTimestamp(1)); - assertNotNull(rs.getTimestamp("column")); - assertEquals(ts, rs.getTimestamp("column")); - assertNotNull(rs.getTimestamp(1, Calendar.getInstance())); - assertEquals(ts, rs.getTimestamp(1, Calendar.getInstance())); - assertNotNull(rs.getTimestamp("column", Calendar.getInstance())); - assertEquals(ts, rs.getTimestamp("column", Calendar.getInstance())); - } - - public void testWrapResultSet() throws SQLException { - final ResultSet wrappedRs = mock(ResultSet.class); - final ResultSet rs = SqlNullCheckedResultSet.wrap(wrappedRs); - rs.beforeFirst(); - verify(wrappedRs).beforeFirst(); - rs.next(); - verify(wrappedRs).next(); - } -} - -class SqlNullUncheckedMockResultSet implements InvocationHandler { - - /** - * Always return false for booleans, 0 for numerics, and null for Objects. - * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) - */ - @Override - public Object invoke(final Object proxy, final Method method, final Object[] args) - throws Throwable { - - final Class<?> returnType = method.getReturnType(); - - if (method.getName().equals("wasNull")) { - return Boolean.TRUE; - - } - if (returnType.equals(Boolean.TYPE)) { - return Boolean.FALSE; - - } - if (returnType.equals(Integer.TYPE)) { - return Integer.valueOf(0); - - } - if (returnType.equals(Short.TYPE)) { - return Short.valueOf((short) 0); - - } - if (returnType.equals(Double.TYPE)) { - return new Double(0); - - } - if (returnType.equals(Long.TYPE)) { - return Long.valueOf(0); - - } - if (returnType.equals(Byte.TYPE)) { - return Byte.valueOf((byte) 0); - - } - if (returnType.equals(Float.TYPE)) { - return new Float(0); - - } - return null; - } -} - -class SqlNullCheckedResultSetMockBlob implements Blob { - - @Override - public InputStream getBinaryStream() throws SQLException { - return new ByteArrayInputStream(new byte[0]); - } - - @Override - public byte[] getBytes(final long param, final int param1) throws SQLException { - return new byte[0]; - } - - @Override - public long length() throws SQLException { - return 0; - } - - @Override - public long position(final byte[] values, final long param) throws SQLException { - return 0; - } - - @Override - public long position(final Blob blob, final long param) throws SQLException { - return 0; - } - - @Override - public void truncate(final long len) throws SQLException { - - } - - @Override - public int setBytes(final long pos, final byte[] bytes) throws SQLException { - return 0; - } - - @Override - public int setBytes(final long pos, final byte[] bytes, final int offset, final int len) - throws SQLException { - return 0; - } - - @Override - public OutputStream setBinaryStream(final long pos) throws SQLException { - return null; - } - - /** - * @throws SQLException - */ - @Override - public void free() throws SQLException { - - } - - /** - * @throws SQLException - */ - @Override - public InputStream getBinaryStream(final long pos, final long length) throws SQLException { - return null; - } - -} - -class SqlNullCheckedResultSetMockClob implements Clob { - - @Override - public InputStream getAsciiStream() throws SQLException { - return null; - } - - @Override - public Reader getCharacterStream() throws SQLException { - return null; - } - - @Override - public String getSubString(final long param, final int param1) throws SQLException { - return ""; - } - - @Override - public long length() throws SQLException { - return 0; - } - - @Override - public long position(final Clob clob, final long param) throws SQLException { - return 0; - } - - @Override - public long position(final String str, final long param) throws SQLException { - return 0; - } - - @Override - public void truncate(final long len) throws SQLException { - - } - - @Override - public OutputStream setAsciiStream(final long pos) throws SQLException { - return null; - } - - @Override - public Writer setCharacterStream(final long pos) throws SQLException { - return null; - } - - @Override - public int setString(final long pos, final String str) throws SQLException { - return 0; - } - - @Override - public int setString(final long pos, final String str, final int offset, final int len) - throws SQLException { - return 0; - } - - /** - * @throws SQLException - */ - @Override - public void free() throws SQLException { - - } - - /** - * @throws SQLException - */ - @Override - public Reader getCharacterStream(final long pos, final long length) throws SQLException { - return null; - } - -} - -class SqlNullCheckedResultSetMockRef implements Ref { - - @Override - public String getBaseTypeName() throws SQLException { - return ""; - } - - @Override - public Object getObject() throws SQLException { - return null; - } - - @Override - public void setObject(final Object value) throws SQLException { - - } - - @Override - public Object getObject(final Map<String,Class<?>> map) throws SQLException { - return null; - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.dbutils.wrappers; + +import java.io.ByteArrayInputStream; +import java.io.CharArrayReader; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.net.MalformedURLException; +import java.net.URL; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Map; + +import org.apache.commons.dbutils.BaseTestCase; +import org.apache.commons.dbutils.ProxyFactory; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +/** + * Test cases for {@code SqlNullCheckedResultSet} class. + */ +public class SqlNullCheckedResultSetTest extends BaseTestCase { + + private SqlNullCheckedResultSet rs2 = null; + + /** + * Sets up instance variables required by this test case. + */ + @Override + public void setUp() throws Exception { + super.setUp(); + + rs2 = + new SqlNullCheckedResultSet( + ProxyFactory.instance().createResultSet( + new SqlNullUncheckedMockResultSet())); + + rs = ProxyFactory.instance().createResultSet(rs2); // Override superclass field + } + + /** + * Tests the getAsciiStream implementation. + */ + public void testGetAsciiStream() throws SQLException { + + assertNull(rs.getAsciiStream(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getAsciiStream("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final InputStream stream = new ByteArrayInputStream(new byte[0]); + rs2.setNullAsciiStream(stream); + assertNotNull(rs.getAsciiStream(1)); + assertEquals(stream, rs.getAsciiStream(1)); + assertNotNull(rs.getAsciiStream("column")); + assertEquals(stream, rs.getAsciiStream("column")); + + } + + /** + * Tests the getBigDecimal implementation. + */ + public void testGetBigDecimal() throws SQLException { + + assertNull(rs.getBigDecimal(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getBigDecimal("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final BigDecimal bd = new BigDecimal(5.0); + rs2.setNullBigDecimal(bd); + assertNotNull(rs.getBigDecimal(1)); + assertEquals(bd, rs.getBigDecimal(1)); + assertNotNull(rs.getBigDecimal("column")); + assertEquals(bd, rs.getBigDecimal("column")); + + } + + /** + * Tests the getBinaryStream implementation. + */ + public void testGetBinaryStream() throws SQLException { + + assertNull(rs.getBinaryStream(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getBinaryStream("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final InputStream stream = new ByteArrayInputStream(new byte[0]); + rs2.setNullBinaryStream(stream); + assertNotNull(rs.getBinaryStream(1)); + assertEquals(stream, rs.getBinaryStream(1)); + assertNotNull(rs.getBinaryStream("column")); + assertEquals(stream, rs.getBinaryStream("column")); + + } + + /** + * Tests the getBlob implementation. + */ + public void testGetBlob() throws SQLException { + + assertNull(rs.getBlob(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getBlob("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final Blob blob = new SqlNullCheckedResultSetMockBlob(); + rs2.setNullBlob(blob); + assertNotNull(rs.getBlob(1)); + assertEquals(blob, rs.getBlob(1)); + assertNotNull(rs.getBlob("column")); + assertEquals(blob, rs.getBlob("column")); + + } + + /** + * Tests the getBoolean implementation. + */ + public void testGetBoolean() throws SQLException { + + assertEquals(false, rs.getBoolean(1)); + assertTrue(rs.wasNull()); + assertEquals(false, rs.getBoolean("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + rs2.setNullBoolean(true); + assertEquals(true, rs.getBoolean(1)); + assertEquals(true, rs.getBoolean("column")); + + } + + /** + * Tests the getByte implementation. + */ + public void testGetByte() throws SQLException { + + assertEquals((byte) 0, rs.getByte(1)); + assertTrue(rs.wasNull()); + assertEquals((byte) 0, rs.getByte("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final byte b = (byte) 10; + rs2.setNullByte(b); + assertEquals(b, rs.getByte(1)); + assertEquals(b, rs.getByte("column")); + + } + + /** + * Tests the getByte implementation. + */ + public void testGetBytes() throws SQLException { + + assertNull(rs.getBytes(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getBytes("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final byte[] b = new byte[5]; + for (int i = 0; i < 5; i++) { + b[0] = (byte) i; + } + rs2.setNullBytes(b); + assertNotNull(rs.getBytes(1)); + assertArrayEquals(b, rs.getBytes(1)); + assertNotNull(rs.getBytes("column")); + assertArrayEquals(b, rs.getBytes("column")); + + } + + private static void assertArrayEquals(final byte[] expected, final byte[] actual) { + if (expected == actual) { + return; + } + if (expected.length != actual.length) { + failNotEquals(null, Arrays.toString(expected), Arrays.toString(actual)); + } + for (int i = 0; i < expected.length; i++) { + final byte expectedItem = expected[i]; + final byte actualItem = actual[i]; + assertEquals("Array not equal at index " + i, expectedItem, actualItem); + } + } + + /** + * Tests the getCharacterStream implementation. + */ + public void testGetCharacterStream() throws SQLException { + + assertNull(rs.getCharacterStream(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getCharacterStream("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final Reader reader = new CharArrayReader("this is a string".toCharArray()); + rs2.setNullCharacterStream(reader); + assertNotNull(rs.getCharacterStream(1)); + assertEquals(reader, rs.getCharacterStream(1)); + assertNotNull(rs.getCharacterStream("column")); + assertEquals(reader, rs.getCharacterStream("column")); + + } + + /** + * Tests the getClob implementation. + */ + public void testGetClob() throws SQLException { + + assertNull(rs.getClob(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getClob("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final Clob clob = new SqlNullCheckedResultSetMockClob(); + rs2.setNullClob(clob); + assertNotNull(rs.getClob(1)); + assertEquals(clob, rs.getClob(1)); + assertNotNull(rs.getClob("column")); + assertEquals(clob, rs.getClob("column")); + + } + + /** + * Tests the getDate implementation. + */ + public void testGetDate() throws SQLException { + + assertNull(rs.getDate(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getDate("column")); + assertTrue(rs.wasNull()); + assertNull(rs.getDate(1, Calendar.getInstance())); + assertTrue(rs.wasNull()); + assertNull(rs.getDate("column", Calendar.getInstance())); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final java.sql.Date date = new java.sql.Date(new java.util.Date().getTime()); + rs2.setNullDate(date); + assertNotNull(rs.getDate(1)); + assertEquals(date, rs.getDate(1)); + assertNotNull(rs.getDate("column")); + assertEquals(date, rs.getDate("column")); + assertNotNull(rs.getDate(1, Calendar.getInstance())); + assertEquals(date, rs.getDate(1, Calendar.getInstance())); + assertNotNull(rs.getDate("column", Calendar.getInstance())); + assertEquals(date, rs.getDate("column", Calendar.getInstance())); + + } + + /** + * Tests the getDouble implementation. + */ + public void testGetDouble() throws SQLException { + + assertEquals(0.0, rs.getDouble(1), 0.0); + assertTrue(rs.wasNull()); + assertEquals(0.0, rs.getDouble("column"), 0.0); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final double d = 10.0; + rs2.setNullDouble(d); + assertEquals(d, rs.getDouble(1), 0.0); + assertEquals(d, rs.getDouble("column"), 0.0); + + } + + /** + * Tests the getFloat implementation. + */ + public void testGetFloat() throws SQLException { + assertEquals(0, rs.getFloat(1), 0.0); + assertTrue(rs.wasNull()); + assertEquals(0, rs.getFloat("column"), 0.0); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final float f = 10; + rs2.setNullFloat(f); + assertEquals(f, rs.getFloat(1), 0.0); + assertEquals(f, rs.getFloat("column"), 0.0); + } + + /** + * Tests the getInt implementation. + */ + public void testGetInt() throws SQLException { + assertEquals(0, rs.getInt(1)); + assertTrue(rs.wasNull()); + assertEquals(0, rs.getInt("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final int i = 10; + rs2.setNullInt(i); + assertEquals(i, rs.getInt(1)); + assertEquals(i, rs.getInt("column")); + } + + /** + * Tests the getLong implementation. + */ + public void testGetLong() throws SQLException { + assertEquals(0, rs.getLong(1)); + assertTrue(rs.wasNull()); + assertEquals(0, rs.getLong("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final long l = 10; + rs2.setNullLong(l); + assertEquals(l, rs.getLong(1)); + assertEquals(l, rs.getLong("column")); + } + + /** + * Tests the getObject implementation. + */ + public void testGetObject() throws SQLException { + + assertNull(rs.getObject(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getObject("column")); + assertTrue(rs.wasNull()); + assertNull(rs.getObject(1, (Map<String, Class<?>>) null)); + assertTrue(rs.wasNull()); + assertNull(rs.getObject("column", (Map<String, Class<?>>) null)); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final Object o = new Object(); + rs2.setNullObject(o); + assertNotNull(rs.getObject(1)); + assertEquals(o, rs.getObject(1)); + assertNotNull(rs.getObject("column")); + assertEquals(o, rs.getObject("column")); + assertNotNull(rs.getObject(1, (Map<String, Class<?>>) null)); + assertEquals(o, rs.getObject(1, (Map<String, Class<?>>) null)); + assertNotNull(rs.getObject("column", (Map<String, Class<?>>) null)); + assertEquals(o, rs.getObject("column", (Map<String, Class<?>>) null)); + + } + + /** + * Tests the getRef implementation. + */ + public void testGetRef() throws SQLException { + + assertNull(rs.getRef(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getRef("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final Ref ref = new SqlNullCheckedResultSetMockRef(); + rs2.setNullRef(ref); + assertNotNull(rs.getRef(1)); + assertEquals(ref, rs.getRef(1)); + assertNotNull(rs.getRef("column")); + assertEquals(ref, rs.getRef("column")); + + } + + /** + * Tests the getShort implementation. + */ + public void testGetShort() throws SQLException { + + assertEquals((short) 0, rs.getShort(1)); + assertTrue(rs.wasNull()); + assertEquals((short) 0, rs.getShort("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final short s = (short) 10; + rs2.setNullShort(s); + assertEquals(s, rs.getShort(1)); + assertEquals(s, rs.getShort("column")); + } + + /** + * Tests the getString implementation. + */ + public void testGetString() throws SQLException { + assertEquals(null, rs.getString(1)); + assertTrue(rs.wasNull()); + assertEquals(null, rs.getString("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final String s = "hello, world"; + rs2.setNullString(s); + assertEquals(s, rs.getString(1)); + assertEquals(s, rs.getString("column")); + } + + /** + * Tests the getTime implementation. + */ + public void testGetTime() throws SQLException { + + assertNull(rs.getTime(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getTime("column")); + assertTrue(rs.wasNull()); + assertNull(rs.getTime(1, Calendar.getInstance())); + assertTrue(rs.wasNull()); + assertNull(rs.getTime("column", Calendar.getInstance())); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final Time time = new Time(new java.util.Date().getTime()); + rs2.setNullTime(time); + assertNotNull(rs.getTime(1)); + assertEquals(time, rs.getTime(1)); + assertNotNull(rs.getTime("column")); + assertEquals(time, rs.getTime("column")); + assertNotNull(rs.getTime(1, Calendar.getInstance())); + assertEquals(time, rs.getTime(1, Calendar.getInstance())); + assertNotNull(rs.getTime("column", Calendar.getInstance())); + assertEquals(time, rs.getTime("column", Calendar.getInstance())); + + } + + /** + * Tests the getTimestamp implementation. + */ + public void testGetTimestamp() throws SQLException { + + assertNull(rs.getTimestamp(1)); + assertTrue(rs.wasNull()); + assertNull(rs.getTimestamp("column")); + assertTrue(rs.wasNull()); + assertNull(rs.getTimestamp(1, Calendar.getInstance())); + assertTrue(rs.wasNull()); + assertNull(rs.getTimestamp("column", Calendar.getInstance())); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final Timestamp ts = new Timestamp(new java.util.Date().getTime()); + rs2.setNullTimestamp(ts); + assertNotNull(rs.getTimestamp(1)); + assertEquals(ts, rs.getTimestamp(1)); + assertNotNull(rs.getTimestamp("column")); + assertEquals(ts, rs.getTimestamp("column")); + assertNotNull(rs.getTimestamp(1, Calendar.getInstance())); + assertEquals(ts, rs.getTimestamp(1, Calendar.getInstance())); + assertNotNull(rs.getTimestamp("column", Calendar.getInstance())); + assertEquals(ts, rs.getTimestamp("column", Calendar.getInstance())); + } + + /** + * Tests the getURL and setNullURL implementations. + * + * Uses reflection to allow for building under JDK 1.3. + */ + public void testURL() throws SQLException, MalformedURLException, + IllegalAccessException, IllegalArgumentException, + java.lang.reflect.InvocationTargetException + { + Method getUrlInt = null; + Method getUrlString = null; + try { + getUrlInt = ResultSet.class.getMethod("getURL", Integer.TYPE); + getUrlString = ResultSet.class.getMethod("getURL", String.class); + } catch(final NoSuchMethodException | SecurityException e) { + // ignore + } + if (getUrlInt != null && getUrlString != null) { + assertEquals(null, getUrlInt.invoke(rs, Integer.valueOf(1)) ); + assertTrue(rs.wasNull()); + assertEquals(null, getUrlString.invoke(rs, "column") ); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final URL u = new URL("http://www.apache.org"); + rs2.setNullURL(u); + assertEquals(u, getUrlInt.invoke(rs, Integer.valueOf(1)) ); + assertEquals(u, getUrlString.invoke(rs, "column") ); + } + } + + /** + * Tests the setNullAsciiStream implementation. + */ + public void testSetNullAsciiStream() throws SQLException { + + assertNull(rs2.getNullAsciiStream()); + // Set what gets returned to something other than the default + final InputStream stream = new ByteArrayInputStream(new byte[0]); + rs2.setNullAsciiStream(stream); + assertNotNull(rs.getAsciiStream(1)); + assertEquals(stream, rs.getAsciiStream(1)); + assertNotNull(rs.getAsciiStream("column")); + assertEquals(stream, rs.getAsciiStream("column")); + + } + + /** + * Tests the setNullBigDecimal implementation. + */ + public void testSetNullBigDecimal() throws SQLException { + + assertNull(rs2.getNullBigDecimal()); + // Set what gets returned to something other than the default + final BigDecimal bd = new BigDecimal(5.0); + rs2.setNullBigDecimal(bd); + assertNotNull(rs.getBigDecimal(1)); + assertEquals(bd, rs.getBigDecimal(1)); + assertNotNull(rs.getBigDecimal("column")); + assertEquals(bd, rs.getBigDecimal("column")); + + } + + /** + * Tests the setNullBinaryStream implementation. + */ + public void testSetNullBinaryStream() throws SQLException { + + assertNull(rs2.getNullBinaryStream()); + // Set what gets returned to something other than the default + final InputStream stream = new ByteArrayInputStream(new byte[0]); + rs2.setNullBinaryStream(stream); + assertNotNull(rs.getBinaryStream(1)); + assertEquals(stream, rs.getBinaryStream(1)); + assertNotNull(rs.getBinaryStream("column")); + assertEquals(stream, rs.getBinaryStream("column")); + + } + + /** + * Tests the setNullBlob implementation. + */ + public void testSetNullBlob() throws SQLException { + + assertNull(rs2.getNullBlob()); + // Set what gets returned to something other than the default + final Blob blob = new SqlNullCheckedResultSetMockBlob(); + rs2.setNullBlob(blob); + assertNotNull(rs.getBlob(1)); + assertEquals(blob, rs.getBlob(1)); + assertNotNull(rs.getBlob("column")); + assertEquals(blob, rs.getBlob("column")); + + } + + /** + * Tests the setNullBoolean implementation. + */ + public void testSetNullBoolean() throws SQLException { + + assertEquals(false, rs2.getNullBoolean()); + // Set what gets returned to something other than the default + rs2.setNullBoolean(true); + assertEquals(true, rs.getBoolean(1)); + assertEquals(true, rs.getBoolean("column")); + + } + + /** + * Tests the setNullByte implementation. + */ + public void testSetNullByte() throws SQLException { + + assertEquals((byte) 0, rs2.getNullByte()); + // Set what gets returned to something other than the default + final byte b = (byte) 10; + rs2.setNullByte(b); + assertEquals(b, rs.getByte(1)); + assertEquals(b, rs.getByte("column")); + + } + + /** + * Tests the setNullByte implementation. + */ + public void testSetNullBytes() throws SQLException { + // test the default, unset value + assertEquals(null, rs2.getNullBytes()); + + // test that setting null is safe + rs2.setNullBytes(null); + assertEquals(null, rs2.getNullBytes()); + + // Set what gets returned to something other than the default + final byte[] b = new byte[5]; + for (int i = 0; i < 5; i++) { + b[0] = (byte) i; + } + rs2.setNullBytes(b); + assertNotNull(rs.getBytes(1)); + assertArrayEquals(b, rs.getBytes(1)); + assertNotNull(rs.getBytes("column")); + assertArrayEquals(b, rs.getBytes("column")); + + } + + /** + * Tests the setNullCharacterStream implementation. + */ + public void testSetNullCharacterStream() throws SQLException { + + assertNull(rs2.getNullCharacterStream()); + // Set what gets returned to something other than the default + final Reader reader = new CharArrayReader("this is a string".toCharArray()); + rs2.setNullCharacterStream(reader); + assertNotNull(rs.getCharacterStream(1)); + assertEquals(reader, rs.getCharacterStream(1)); + assertNotNull(rs.getCharacterStream("column")); + assertEquals(reader, rs.getCharacterStream("column")); + + } + + /** + * Tests the setNullClob implementation. + */ + public void testSetNullClob() throws SQLException { + + assertNull(rs2.getNullClob()); + // Set what gets returned to something other than the default + final Clob clob = new SqlNullCheckedResultSetMockClob(); + rs2.setNullClob(clob); + assertNotNull(rs.getClob(1)); + assertEquals(clob, rs.getClob(1)); + assertNotNull(rs.getClob("column")); + assertEquals(clob, rs.getClob("column")); + + } + + /** + * Tests the setNullDate implementation. + */ + public void testSetNullDate() throws SQLException { + // test the default, unset value + assertEquals(null, rs2.getNullDate()); + + // test that setting null is safe + rs2.setNullDate(null); + assertEquals(null, rs2.getNullDate()); + + // Set what gets returned to something other than the default + final java.sql.Date date = new java.sql.Date(new java.util.Date().getTime()); + rs2.setNullDate(date); + assertNotNull(rs.getDate(1)); + assertEquals(date, rs.getDate(1)); + assertNotNull(rs.getDate("column")); + assertEquals(date, rs.getDate("column")); + assertNotNull(rs.getDate(1, Calendar.getInstance())); + assertEquals(date, rs.getDate(1, Calendar.getInstance())); + assertNotNull(rs.getDate("column", Calendar.getInstance())); + assertEquals(date, rs.getDate("column", Calendar.getInstance())); + + } + + /** + * Tests the setNullDouble implementation. + */ + public void testSetNullDouble() throws SQLException { + assertEquals(0.0, rs2.getNullDouble(), 0.0); + // Set what gets returned to something other than the default + final double d = 10.0; + rs2.setNullDouble(d); + assertEquals(d, rs.getDouble(1), 0.0); + assertEquals(d, rs.getDouble("column"), 0.0); + } + + /** + * Tests the setNullFloat implementation. + */ + public void testSetNullFloat() throws SQLException { + assertEquals((float) 0.0, rs2.getNullFloat(), 0.0); + // Set what gets returned to something other than the default + final float f = (float) 10.0; + rs2.setNullFloat(f); + assertEquals(f, rs.getFloat(1), 0.0); + assertEquals(f, rs.getFloat("column"), 0.0); + } + + /** + * Tests the setNullInt implementation. + */ + public void testSetNullInt() throws SQLException { + assertEquals(0, rs2.getNullInt()); + assertEquals(0, rs.getInt(1)); + assertTrue(rs.wasNull()); + assertEquals(0, rs.getInt("column")); + assertTrue(rs.wasNull()); + // Set what gets returned to something other than the default + final int i = 10; + rs2.setNullInt(i); + assertEquals(i, rs.getInt(1)); + assertEquals(i, rs.getInt("column")); + } + + /** + * Tests the setNullLong implementation. + */ + public void testSetNullLong() throws SQLException { + assertEquals(0, rs2.getNullLong()); + // Set what gets returned to something other than the default + final long l = 10; + rs2.setNullLong(l); + assertEquals(l, rs.getLong(1)); + assertEquals(l, rs.getLong("column")); + } + + /** + * Tests the setNullObject implementation. + */ + public void testSetNullObject() throws SQLException { + assertNull(rs2.getNullObject()); + // Set what gets returned to something other than the default + final Object o = new Object(); + rs2.setNullObject(o); + assertNotNull(rs.getObject(1)); + assertEquals(o, rs.getObject(1)); + assertNotNull(rs.getObject("column")); + assertEquals(o, rs.getObject("column")); + assertNotNull(rs.getObject(1, (Map<String, Class<?>>) null)); + assertEquals(o, rs.getObject(1, (Map<String, Class<?>>) null)); + assertNotNull(rs.getObject("column", (Map<String, Class<?>>) null)); + assertEquals(o, rs.getObject("column", (Map<String, Class<?>>) null)); + } + + /** + * Tests the setNullShort implementation. + */ + public void testSetNullShort() throws SQLException { + + assertEquals((short) 0, rs2.getNullShort()); + // Set what gets returned to something other than the default + final short s = (short) 10; + rs2.setNullShort(s); + assertEquals(s, rs.getShort(1)); + assertEquals(s, rs.getShort("column")); + + } + + /** + * Tests the setNullString implementation. + */ + public void testSetNullString() throws SQLException { + assertEquals(null, rs2.getNullString()); + // Set what gets returned to something other than the default + final String s = "hello, world"; + rs2.setNullString(s); + assertEquals(s, rs.getString(1)); + assertEquals(s, rs.getString("column")); + } + + /** + * Tests the setNullRef implementation. + */ + public void testSetNullRef() throws SQLException { + assertNull(rs2.getNullRef()); + // Set what gets returned to something other than the default + final Ref ref = new SqlNullCheckedResultSetMockRef(); + rs2.setNullRef(ref); + assertNotNull(rs.getRef(1)); + assertEquals(ref, rs.getRef(1)); + assertNotNull(rs.getRef("column")); + assertEquals(ref, rs.getRef("column")); + } + + /** + * Tests the setNullTime implementation. + */ + public void testSetNullTime() throws SQLException { + // test the default, unset value + assertEquals(null, rs2.getNullTime()); + + // test that setting null is safe + rs2.setNullTime(null); + assertEquals(null, rs2.getNullTime()); + + // Set what gets returned to something other than the default + final Time time = new Time(new java.util.Date().getTime()); + rs2.setNullTime(time); + assertNotNull(rs.getTime(1)); + assertEquals(time, rs.getTime(1)); + assertNotNull(rs.getTime("column")); + assertEquals(time, rs.getTime("column")); + assertNotNull(rs.getTime(1, Calendar.getInstance())); + assertEquals(time, rs.getTime(1, Calendar.getInstance())); + assertNotNull(rs.getTime("column", Calendar.getInstance())); + assertEquals(time, rs.getTime("column", Calendar.getInstance())); + } + + /** + * Tests the setNullTimestamp implementation. + */ + public void testSetNullTimestamp() throws SQLException { + // test the default, unset value + assertEquals(null, rs2.getNullTimestamp()); + + // test that setting null is safe + rs2.setNullTimestamp(null); + assertEquals(null, rs2.getNullTimestamp()); + + // Set what gets returned to something other than the default + final Timestamp ts = new Timestamp(new java.util.Date().getTime()); + rs2.setNullTimestamp(ts); + assertNotNull(rs.getTimestamp(1)); + assertEquals(ts, rs.getTimestamp(1)); + assertNotNull(rs.getTimestamp("column")); + assertEquals(ts, rs.getTimestamp("column")); + assertNotNull(rs.getTimestamp(1, Calendar.getInstance())); + assertEquals(ts, rs.getTimestamp(1, Calendar.getInstance())); + assertNotNull(rs.getTimestamp("column", Calendar.getInstance())); + assertEquals(ts, rs.getTimestamp("column", Calendar.getInstance())); + } + + public void testWrapResultSet() throws SQLException { + final ResultSet wrappedRs = mock(ResultSet.class); + final ResultSet rs = SqlNullCheckedResultSet.wrap(wrappedRs); + rs.beforeFirst(); + verify(wrappedRs).beforeFirst(); + rs.next(); + verify(wrappedRs).next(); + } +} + +class SqlNullUncheckedMockResultSet implements InvocationHandler { + + /** + * Always return false for booleans, 0 for numerics, and null for Objects. + * @see java.lang.reflect.InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[]) + */ + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) + throws Throwable { + + final Class<?> returnType = method.getReturnType(); + + if (method.getName().equals("wasNull")) { + return Boolean.TRUE; + + } + if (returnType.equals(Boolean.TYPE)) { + return Boolean.FALSE; + + } + if (returnType.equals(Integer.TYPE)) { + return Integer.valueOf(0); + + } + if (returnType.equals(Short.TYPE)) { + return Short.valueOf((short) 0); + + } + if (returnType.equals(Double.TYPE)) { + return new Double(0); + + } + if (returnType.equals(Long.TYPE)) { + return Long.valueOf(0); + + } + if (returnType.equals(Byte.TYPE)) { + return Byte.valueOf((byte) 0); + + } + if (returnType.equals(Float.TYPE)) { + return new Float(0); + + } + return null; + } +} + +class SqlNullCheckedResultSetMockBlob implements Blob { + + @Override + public InputStream getBinaryStream() throws SQLException { + return new ByteArrayInputStream(new byte[0]); + } + + @Override + public byte[] getBytes(final long param, final int param1) throws SQLException { + return new byte[0]; + } + + @Override + public long length() throws SQLException { + return 0; + } + + @Override + public long position(final byte[] values, final long param) throws SQLException { + return 0; + } + + @Override + public long position(final Blob blob, final long param) throws SQLException { + return 0; + } + + @Override + public void truncate(final long len) throws SQLException { + + } + + @Override + public int setBytes(final long pos, final byte[] bytes) throws SQLException { + return 0; + } + + @Override + public int setBytes(final long pos, final byte[] bytes, final int offset, final int len) + throws SQLException { + return 0; + } + + @Override + public OutputStream setBinaryStream(final long pos) throws SQLException { + return null; + } + + /** + * @throws SQLException + */ + @Override + public void free() throws SQLException { + + } + + /** + * @throws SQLException + */ + @Override + public InputStream getBinaryStream(final long pos, final long length) throws SQLException { + return null; + } + +} + +class SqlNullCheckedResultSetMockClob implements Clob { + + @Override + public InputStream getAsciiStream() throws SQLException { + return null; + } + + @Override + public Reader getCharacterStream() throws SQLException { + return null; + } + + @Override + public String getSubString(final long param, final int param1) throws SQLException { + return ""; + } + + @Override + public long length() throws SQLException { + return 0; + } + + @Override + public long position(final Clob clob, final long param) throws SQLException { + return 0; + } + + @Override + public long position(final String str, final long param) throws SQLException { + return 0; + } + + @Override + public void truncate(final long len) throws SQLException { + + } + + @Override + public OutputStream setAsciiStream(final long pos) throws SQLException { + return null; + } + + @Override + public Writer setCharacterStream(final long pos) throws SQLException { + return null; + } + + @Override + public int setString(final long pos, final String str) throws SQLException { + return 0; + } + + @Override + public int setString(final long pos, final String str, final int offset, final int len) + throws SQLException { + return 0; + } + + /** + * @throws SQLException + */ + @Override + public void free() throws SQLException { + + } + + /** + * @throws SQLException + */ + @Override + public Reader getCharacterStream(final long pos, final long length) throws SQLException { + return null; + } + +} + +class SqlNullCheckedResultSetMockRef implements Ref { + + @Override + public String getBaseTypeName() throws SQLException { + return ""; + } + + @Override + public Object getObject() throws SQLException { + return null; + } + + @Override + public void setObject(final Object value) throws SQLException { + + } + + @Override + public Object getObject(final Map<String,Class<?>> map) throws SQLException { + return null; + } + +}