001 package com.mockrunner.jdbc;
002
003 import java.io.InputStream;
004 import java.io.Reader;
005
006 import com.mockrunner.mock.jdbc.MockResultSet;
007 import com.mockrunner.util.common.ArrayUtil;
008 import com.mockrunner.util.common.MethodUtil;
009 import com.mockrunner.util.common.StreamUtil;
010
011 /**
012 * Util class for <code>PreparedStatement</code> and <code>ResultSet</code>
013 * parameters.
014 */
015 public class ParameterUtil
016 {
017 /**
018 * Copies a parameter of a <code>PreparedStatement</code>,
019 * <code>CallableStatement</code> or a <code>ResultSet</code> value.
020 * <code>InputStream</code> objects, <code>Reader</code> objects
021 * and arrays are copied into new allocated streams or arrays.
022 * All other objects are cloned by calling the clone method.
023 * If the object is not cloneable, it is returned unchanged.
024 * @param source the parameter to copy
025 * @return a copy of the parameter
026 */
027 public static Object copyParameter(Object source)
028 {
029 if(null == source) return null;
030 if(source.getClass().isArray())
031 {
032 return ArrayUtil.copyArray(source);
033 }
034 if(source instanceof InputStream)
035 {
036 return StreamUtil.copyStream((InputStream)source);
037 }
038 if(source instanceof Reader)
039 {
040 return StreamUtil.copyReader((Reader)source);
041 }
042 if(source instanceof Cloneable)
043 {
044 try
045 {
046 return MethodUtil.invoke(source, "clone");
047 }
048 catch(Exception exc)
049 {
050 return source;
051 }
052 }
053 return source;
054 }
055
056 /**
057 * Compares two parameters of a <code>PreparedStatement</code> or
058 * <code>CallableStatement</code>. Can also be used to compare
059 * values of a <code>ResultSet</code>. It is used by
060 * {@link com.mockrunner.jdbc.PreparedStatementResultSetHandler}
061 * for comparing parameters specified in the <code>prepare</code>
062 * methods.
063 * Since the parameters can be of the type <code>byte[]</code>,
064 * <code>InputStream</code> and <code>Reader</code> this method handles
065 * these types of objects. All other objects are compared using the
066 * <code>equals</code> method. The mock versions of <code>Ref</code>,
067 * <code>Array</code>, <code>Blob</code>, <code>Clob</code>,
068 * <code>Struct</code> etc. all provide a suitable <code>equals</code>
069 * implementation.
070 * @param source the first parameter
071 * @param target the second parameter
072 * @return <code>true</code> if <i>source</i> is equal to <i>target</i>,
073 * <code>false</code> otherwise
074 */
075 public static boolean compareParameter(Object source, Object target)
076 {
077 if(null == source && null == target) return true;
078 if(null == source || null == target) return false;
079 if(source instanceof InputStream && target instanceof InputStream)
080 {
081 return StreamUtil.compareStreams((InputStream)source, (InputStream)target);
082 }
083 if(source instanceof Reader && target instanceof Reader)
084 {
085 return StreamUtil.compareReaders((Reader)source, (Reader)target);
086 }
087 if(source instanceof MockResultSet && target instanceof MockResultSet)
088 {
089 return ((MockResultSet)source).isEqual((MockResultSet)target);
090 }
091 if(source.getClass().isArray() && target.getClass().isArray())
092 {
093 return ArrayUtil.areArraysEqual(source, target);
094 }
095 return source.equals(target);
096 }
097 }
098