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