001    package com.mockrunner.mock.jdbc;
002    
003    import java.io.ByteArrayInputStream;
004    import java.io.InputStream;
005    import java.io.Reader;
006    import java.io.StringReader;
007    import java.math.BigDecimal;
008    import java.net.MalformedURLException;
009    import java.net.URL;
010    import java.sql.Array;
011    import java.sql.Blob;
012    import java.sql.CallableStatement;
013    import java.sql.Clob;
014    import java.sql.Connection;
015    import java.sql.Date;
016    import java.sql.Ref;
017    import java.sql.ResultSet;
018    import java.sql.SQLException;
019    import java.sql.Time;
020    import java.sql.Timestamp;
021    import java.util.ArrayList;
022    import java.util.Calendar;
023    import java.util.Collections;
024    import java.util.HashMap;
025    import java.util.HashSet;
026    import java.util.Iterator;
027    import java.util.List;
028    import java.util.Map;
029    import java.util.Set;
030    
031    import com.mockrunner.jdbc.AbstractOutParameterResultSetHandler;
032    import com.mockrunner.util.common.StreamUtil;
033    
034    /**
035     * Mock implementation of <code>CallableStatement</code>.
036     */
037    public class MockCallableStatement extends MockPreparedStatement implements CallableStatement
038    {
039        private AbstractOutParameterResultSetHandler resultSetHandler;
040        private Map paramObjects = new HashMap();
041        private Set registeredOutParameterSetIndexed = new HashSet();
042        private Set registeredOutParameterSetNamed = new HashSet();
043        private List batchParameters = new ArrayList();
044        private Map lastOutParameters = null;
045        private boolean wasNull = false;
046        
047        public MockCallableStatement(Connection connection, String sql)
048        {
049            super(connection, sql);
050        }
051    
052        public MockCallableStatement(Connection connection, String sql, int resultSetType, int resultSetConcurrency)
053        {
054            super(connection, sql, resultSetType, resultSetConcurrency);
055        }
056    
057        public MockCallableStatement(Connection connection, String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
058        {
059            super(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability);
060        }
061        
062        public void setCallableStatementResultSetHandler(AbstractOutParameterResultSetHandler resultSetHandler)
063        {
064            super.setPreparedStatementResultSetHandler(resultSetHandler);
065            this.resultSetHandler = resultSetHandler;
066        }
067        
068        public Map getNamedParameterMap()
069        {
070            return Collections.unmodifiableMap(paramObjects);
071        }
072        
073        public Map getParameterMap()
074        {
075            Map parameterMap = new HashMap(getIndexedParameterMap());
076            parameterMap.putAll(getNamedParameterMap());
077            return Collections.unmodifiableMap(parameterMap);
078        }
079        
080        public Object getParameter(String name)
081        {
082            return paramObjects.get(name);
083        }
084        
085        public void clearParameters() throws SQLException
086        {
087            super.clearParameters();
088            paramObjects.clear();
089        }
090        
091        public Set getNamedRegisteredOutParameterSet()
092        {
093            return Collections.unmodifiableSet(registeredOutParameterSetNamed);
094        }
095        
096        public boolean isOutParameterRegistered(int index)
097        {
098            return registeredOutParameterSetIndexed.contains(new Integer(index));
099        }
100        
101        public Set getIndexedRegisteredOutParameterSet()
102        {
103            return Collections.unmodifiableSet(registeredOutParameterSetIndexed);
104        }
105        
106        public boolean isOutParameterRegistered(String parameterName)
107        {
108            return registeredOutParameterSetNamed.contains(parameterName);
109        }
110        
111        public void clearRegisteredOutParameter()
112        {
113            registeredOutParameterSetIndexed.clear();
114            registeredOutParameterSetNamed.clear();
115        }
116        
117        public ResultSet executeQuery() throws SQLException
118        {
119            ResultSet resultSet = executeQuery(getParameterMap());
120            lastOutParameters = getOutParameterMap();
121            return resultSet;
122        }
123        
124        public int executeUpdate() throws SQLException
125        {
126            int updateCount = executeUpdate(getParameterMap());
127            lastOutParameters = getOutParameterMap();
128            return updateCount;
129        }
130        
131        public void addBatch() throws SQLException
132        {
133            batchParameters.add(new HashMap(getParameterMap()));
134        }
135    
136        public int[] executeBatch() throws SQLException
137        {
138            return executeBatch(batchParameters);
139        }
140        
141        public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException
142        {
143            registeredOutParameterSetIndexed.add(new Integer(parameterIndex));
144        }
145    
146        public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException
147        {
148            registerOutParameter(parameterIndex, sqlType);
149        }
150    
151        public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException
152        {
153            registerOutParameter(parameterIndex, sqlType);
154        }
155        
156        public void registerOutParameter(String parameterName, int sqlType) throws SQLException
157        {
158            registeredOutParameterSetNamed.add(parameterName);
159        }
160        
161        public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException
162        {
163            registerOutParameter(parameterName, sqlType);
164        }
165        
166        public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException
167        {
168            registerOutParameter(parameterName, sqlType);
169        }
170            
171        public boolean wasNull() throws SQLException
172        {
173            return wasNull;
174        }
175    
176        public byte getByte(int parameterIndex) throws SQLException
177        {
178            Object value = getObject(parameterIndex);
179            if(null != value)
180            {
181                if(value instanceof Number) return ((Number)value).byteValue();
182                return new Byte(value.toString()).byteValue();
183            }
184            return 0;
185        }
186    
187        public double getDouble(int parameterIndex) throws SQLException
188        {
189            Object value = getObject(parameterIndex);
190            if(null != value)
191            {
192                if(value instanceof Number) return ((Number)value).doubleValue();
193                return new Double(value.toString()).doubleValue();
194            }
195            return 0;
196        }
197    
198        public float getFloat(int parameterIndex) throws SQLException
199        {
200            Object value = getObject(parameterIndex);
201            if(null != value)
202            {
203                if(value instanceof Number) return ((Number)value).floatValue();
204                return new Float(value.toString()).floatValue();
205            }
206            return 0;
207        }
208    
209        public int getInt(int parameterIndex) throws SQLException
210        {
211            Object value = getObject(parameterIndex);
212            if(null != value)
213            {
214                if(value instanceof Number) return ((Number)value).intValue();
215                return new Integer(value.toString()).intValue();
216            }
217            return 0;
218        }
219    
220        public long getLong(int parameterIndex) throws SQLException
221        {
222            Object value = getObject(parameterIndex);
223            if(null != value)
224            {
225                if(value instanceof Number) return ((Number)value).longValue();
226                return new Long(value.toString()).longValue();
227            }
228            return 0;
229        }
230    
231        public short getShort(int parameterIndex) throws SQLException
232        {
233            Object value = getObject(parameterIndex);
234            if(null != value)
235            {
236                if(value instanceof Number) return ((Number)value).shortValue();
237                return new Short(value.toString()).shortValue();
238            }
239            return 0;
240        }
241    
242        public boolean getBoolean(int parameterIndex) throws SQLException
243        {
244            Object value = getObject(parameterIndex);
245            if(null != value)
246            {
247                if(value instanceof Boolean) return ((Boolean)value).booleanValue();
248                return new Boolean(value.toString()).booleanValue();
249            }
250            return false;
251        }
252    
253        public byte[] getBytes(int parameterIndex) throws SQLException
254        {
255            Object value = getObject(parameterIndex);
256            if(null != value)
257            {
258                if(value instanceof byte[]) return (byte[])value;
259                return value.toString().getBytes();
260            }
261            return null;
262        }
263    
264        public Object getObject(int parameterIndex) throws SQLException
265        {
266            wasNull = false;
267            Object returnValue = null;
268            if(null != lastOutParameters)
269            {
270                returnValue = lastOutParameters.get(new Integer(parameterIndex));
271            }
272            if(null == returnValue) wasNull = true;
273            return returnValue;
274        }
275    
276        public String getString(int parameterIndex) throws SQLException
277        {
278            Object value = getObject(parameterIndex);
279            if(null != value) return value.toString();
280            return null;
281        }
282        
283        public byte getByte(String parameterName) throws SQLException
284        {
285            Object value = getObject(parameterName);
286            if(null != value)
287            {
288                if(value instanceof Number) return ((Number)value).byteValue();
289                return new Byte(value.toString()).byteValue();
290            }
291            return 0;
292        }
293    
294        public double getDouble(String parameterName) throws SQLException
295        {
296            Object value = getObject(parameterName);
297            if(null != value)
298            {
299                if(value instanceof Number) return ((Number)value).doubleValue();
300                return new Double(value.toString()).doubleValue();
301            }
302            return 0;
303        }
304    
305        public float getFloat(String parameterName) throws SQLException
306        {
307            Object value = getObject(parameterName);
308            if(null != value)
309            {
310                if(value instanceof Number) return ((Number)value).floatValue();
311                return new Float(value.toString()).floatValue();
312            }
313            return 0;
314        }
315    
316        public int getInt(String parameterName) throws SQLException
317        {
318            Object value = getObject(parameterName);
319            if(null != value)
320            {
321                if(value instanceof Number) return ((Number)value).intValue();
322                return new Integer(value.toString()).intValue();
323            }
324            return 0;
325        }
326    
327        public long getLong(String parameterName) throws SQLException
328        {
329            Object value = getObject(parameterName);
330            if(null != value)
331            {
332                if(value instanceof Number) return ((Number)value).longValue();
333                return new Long(value.toString()).longValue();
334            }
335            return 0;
336        }
337    
338        public short getShort(String parameterName) throws SQLException
339        {
340            Object value = getObject(parameterName);
341            if(null != value)
342            {
343                if(value instanceof Number) return ((Number)value).shortValue();
344                return new Short(value.toString()).shortValue();
345            }
346            return 0;
347        }
348    
349        public boolean getBoolean(String parameterName) throws SQLException
350        {
351            Object value = getObject(parameterName);
352            if(null != value)
353            {
354                if(value instanceof Boolean) return ((Boolean)value).booleanValue();
355                return new Boolean(value.toString()).booleanValue();
356            }
357            return false;
358        }
359    
360        public byte[] getBytes(String parameterName) throws SQLException
361        {
362            Object value = getObject(parameterName);
363            if(null != value)
364            {
365                if(value instanceof byte[]) return (byte[])value;
366                return value.toString().getBytes();
367            }
368            return null;
369        }
370    
371        public void setByte(String parameterName, byte byteValue) throws SQLException
372        {
373            setObject(parameterName, new Byte(byteValue));
374        }
375    
376        public void setDouble(String parameterName, double doubleValue) throws SQLException
377        {
378            setObject(parameterName, new Double(doubleValue));
379        }
380    
381        public void setFloat(String parameterName, float floatValue) throws SQLException
382        {
383            setObject(parameterName, new Float(floatValue));
384        }
385    
386        public void setInt(String parameterName, int intValue) throws SQLException
387        {
388            setObject(parameterName, new Integer(intValue));
389        }
390    
391        public void setNull(String parameterName, int sqlType) throws SQLException
392        {
393            setObject(parameterName, null);
394        }
395    
396        public void setLong(String parameterName, long longValue) throws SQLException
397        {
398            setObject(parameterName, new Long(longValue));
399        }
400    
401        public void setShort(String parameterName, short shortValue) throws SQLException
402        {
403            setObject(parameterName, new Short(shortValue));
404        }
405    
406        public void setBoolean(String parameterName, boolean booleanValue) throws SQLException
407        {
408            setObject(parameterName, new Boolean(booleanValue));
409        }
410    
411        public void setBytes(String parameterName, byte[] byteArray) throws SQLException
412        {
413            setObject(parameterName, byteArray);
414        }
415    
416        public BigDecimal getBigDecimal(int parameterIndex) throws SQLException
417        {
418            Object value = getObject(parameterIndex);
419            if(null != value)
420            {
421                if(value instanceof Number) return new BigDecimal(((Number)value).doubleValue());
422                return new BigDecimal(value.toString());
423            }
424            return null;
425        }
426    
427        public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException
428        {
429            return getBigDecimal(parameterIndex);
430        }
431    
432        public URL getURL(int parameterIndex) throws SQLException
433        {
434            Object value = getObject(parameterIndex);
435            if(null != value)
436            {
437                if(value instanceof URL) return (URL)value;
438                try
439                {
440                    return new URL(value.toString());
441                }
442                catch(MalformedURLException exc)
443                {
444                
445                }
446            }
447            return null;
448        }
449    
450        public Array getArray(int parameterIndex) throws SQLException
451        {
452            Object value = getObject(parameterIndex);
453            if(null != value)
454            {
455                if(value instanceof Array) return (Array)value;
456                return new MockArray(value);
457            }
458            return null;
459        }
460    
461        public Blob getBlob(int parameterIndex) throws SQLException
462        {
463            Object value = getObject(parameterIndex);
464            if(null != value)
465            {
466                if(value instanceof Blob) return (Blob)value;
467                return new MockBlob(getBytes(parameterIndex));
468            }
469            return null;
470        }
471    
472        public Clob getClob(int parameterIndex) throws SQLException
473        {
474            Object value = getObject(parameterIndex);
475            if(null != value)
476            {
477                if(value instanceof Clob) return (Clob)value;
478                return new MockClob(getString(parameterIndex));
479            }
480            return null;
481        }
482    
483        public Date getDate(int parameterIndex) throws SQLException
484        {
485            Object value = getObject(parameterIndex);
486            if(null != value)
487            {
488                if(value instanceof Date) return (Date)value;
489                return Date.valueOf(value.toString());
490            }
491            return null;
492        }
493    
494        public Ref getRef(int parameterIndex) throws SQLException
495        {
496            Object value = getObject(parameterIndex);
497            if(null != value)
498            {
499                if(value instanceof Ref) return (Ref)value;
500                return new MockRef(value);
501            }
502            return null;
503        }
504    
505        public Time getTime(int parameterIndex) throws SQLException
506        {
507            Object value = getObject(parameterIndex);
508            if(null != value)
509            {
510                if(value instanceof Time) return (Time)value;
511                return Time.valueOf(value.toString());
512            }
513            return null;
514        }
515    
516        public Timestamp getTimestamp(int parameterIndex) throws SQLException
517        {
518            Object value = getObject(parameterIndex);
519            if(null != value)
520            {
521                if(value instanceof Timestamp) return (Timestamp)value;
522                return Timestamp.valueOf(value.toString());
523            }
524            return null;
525        }
526    
527        public void setAsciiStream(String parameterName, InputStream stream, int length) throws SQLException
528        {
529            setBinaryStream(parameterName, stream, length);
530        }
531    
532        public void setBinaryStream(String parameterName, InputStream stream, int length) throws SQLException
533        {
534            byte[] data = StreamUtil.getStreamAsByteArray(stream, length);
535            setObject(parameterName, new ByteArrayInputStream(data));
536        }
537    
538        public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException
539        {
540            String data = StreamUtil.getReaderAsString(reader, length);
541            setObject(parameterName, new StringReader(data));
542        }
543    
544        public Object getObject(String parameterName) throws SQLException
545        {
546            wasNull = false;
547            Object returnValue = null;
548            if(null != lastOutParameters)
549            {
550                returnValue = lastOutParameters.get(parameterName);
551            }
552            if(null == returnValue) wasNull = true;
553            return returnValue;
554        }
555    
556        public void setObject(String parameterName, Object object) throws SQLException
557        {
558            paramObjects.put(parameterName, object);
559        }
560    
561        public void setObject(String parameterName, Object object, int targetSqlType) throws SQLException
562        {
563            setObject(parameterName, object);
564        }
565    
566        public void setObject(String parameterName, Object object, int targetSqlType, int scale) throws SQLException
567        {
568            setObject(parameterName, object);
569        }
570    
571        public Object getObject(int parameterIndex, Map map) throws SQLException
572        {
573            return getObject(parameterIndex);
574        }
575    
576        public String getString(String parameterName) throws SQLException
577        {
578            Object value = getObject(parameterName);
579            if(null != value) return value.toString();
580            return null;
581        }
582    
583        public void setNull(String parameterName, int sqlType, String typeName) throws SQLException
584        {
585            setNull(parameterName, sqlType);
586        }
587    
588        public void setString(String parameterName, String string) throws SQLException
589        {
590            setObject(parameterName, string);
591        }
592    
593        public BigDecimal getBigDecimal(String parameterName) throws SQLException
594        {
595            Object value = getObject(parameterName);
596            if(null != value)
597            {
598                if(value instanceof Number) return new BigDecimal(((Number)value).doubleValue());
599                return new BigDecimal(value.toString());
600            }
601            return null;
602        }
603    
604        public void setBigDecimal(String parameterName, BigDecimal bigDecimal) throws SQLException
605        {
606            setObject(parameterName, bigDecimal);
607        }
608    
609        public URL getURL(String parameterName) throws SQLException
610        {
611            Object value = getObject(parameterName);
612            if(null != value)
613            {
614                if(value instanceof URL) return (URL)value;
615                try
616                {
617                    return new URL(value.toString());
618                }
619                catch(MalformedURLException exc)
620                {
621                
622                }
623            }
624            return null;
625        }
626    
627        public void setURL(String parameterName, URL url) throws SQLException
628        {
629            setObject(parameterName, url);
630        }
631    
632        public Array getArray(String parameterName) throws SQLException
633        {
634            Object value = getObject(parameterName);
635            if(null != value)
636            {
637                if(value instanceof Array) return (Array)value;
638                return new MockArray(value);
639            }
640            return null;
641        }
642    
643        public Blob getBlob(String parameterName) throws SQLException
644        {
645            Object value = getObject(parameterName);
646            if(null != value)
647            {
648                if(value instanceof Blob) return (Blob)value;
649                return new MockBlob(getBytes(parameterName));
650            }
651            return null;
652        }
653    
654        public Clob getClob(String parameterName) throws SQLException
655        {
656            Object value = getObject(parameterName);
657            if(null != value)
658            {
659                if(value instanceof Clob) return (Clob)value;
660                return new MockClob(getString(parameterName));
661            }
662            return null;
663        }
664    
665        public Date getDate(String parameterName) throws SQLException
666        {
667            Object value = getObject(parameterName);
668            if(null != value)
669            {
670                if(value instanceof Date) return (Date)value;
671                return Date.valueOf(value.toString());
672            }
673            return null;
674        }
675    
676        public void setDate(String parameterName, Date date) throws SQLException
677        {
678            setObject(parameterName, date);
679        }
680    
681        public Date getDate(int parameterIndex, Calendar calendar) throws SQLException
682        {
683            return getDate(parameterIndex);
684        }
685    
686        public Ref getRef(String parameterName) throws SQLException
687        {
688            Object value = getObject(parameterName);
689            if(null != value)
690            {
691                if(value instanceof Ref) return (Ref)value;
692                return new MockRef(value);
693            }
694            return null;
695        }
696    
697        public Time getTime(String parameterName) throws SQLException
698        {
699            Object value = getObject(parameterName);
700            if(null != value)
701            {
702                if(value instanceof Time) return (Time)value;
703                return Time.valueOf(value.toString());
704            }
705            return null;
706        }
707    
708        public void setTime(String parameterName, Time time) throws SQLException
709        {
710            setObject(parameterName, time);
711        }
712    
713        public Time getTime(int parameterIndex, Calendar calendar) throws SQLException
714        {
715            return getTime(parameterIndex);
716        }
717    
718        public Timestamp getTimestamp(String parameterName) throws SQLException
719        {
720            Object value = getObject(parameterName);
721            if(null != value)
722            {
723                if(value instanceof Timestamp) return (Timestamp)value;
724                return Timestamp.valueOf(value.toString());
725            }
726            return null;
727        }
728    
729        public void setTimestamp(String parameterName, Timestamp timestamp) throws SQLException
730        {
731            setObject(parameterName, timestamp);
732        }
733    
734        public Timestamp getTimestamp(int parameterIndex, Calendar calendar) throws SQLException
735        {
736            return getTimestamp(parameterIndex);
737        }
738    
739        public Object getObject(String parameterName, Map map) throws SQLException
740        {
741            return getObject(parameterName);
742        }
743    
744        public Date getDate(String parameterName, Calendar calendar) throws SQLException
745        {
746            return getDate(parameterName);
747        }
748    
749        public Time getTime(String parameterName, Calendar calendar) throws SQLException
750        {
751            return getTime(parameterName);
752        }
753    
754        public Timestamp getTimestamp(String parameterName, Calendar calendar) throws SQLException
755        {
756            return getTimestamp(parameterName);
757        }
758    
759        public void setDate(String parameterName, Date date, Calendar calendar) throws SQLException
760        {
761            setDate(parameterName, date);
762        }
763    
764        public void setTime(String parameterName, Time time, Calendar calendar) throws SQLException
765        {
766            setTime(parameterName, time);
767        }
768    
769        public void setTimestamp(String parameterName, Timestamp timestamp, Calendar calendar) throws SQLException
770        {
771            setTimestamp(parameterName, timestamp);
772        }
773        
774        private Map getOutParameterMap()
775        {
776            Map outParameter = resultSetHandler.getOutParameter(getSQL(), getParameterMap());
777            if(null == outParameter)
778            {
779                outParameter = resultSetHandler.getOutParameter(getSQL());
780            }
781            if(null == outParameter)
782            {
783                outParameter = resultSetHandler.getGlobalOutParameter();
784            }
785            if(resultSetHandler.getMustRegisterOutParameters())
786            {
787                return filterNotRegisteredParameters(outParameter);
788            }
789            return outParameter;
790        }
791        
792        private Map filterNotRegisteredParameters(Map outParameter)
793        {
794            Map filteredMap = new HashMap();
795            Iterator keys = outParameter.keySet().iterator();
796            while(keys.hasNext())
797            {
798                Object nextKey = keys.next();
799                if(registeredOutParameterSetIndexed.contains(nextKey) || registeredOutParameterSetNamed.contains(nextKey))
800                {
801                    filteredMap.put(nextKey, outParameter.get(nextKey));
802                }
803            }
804            return Collections.unmodifiableMap(filteredMap);
805        }
806    }