001    package com.mockrunner.mock.jdbc;
002    
003    import java.io.ByteArrayInputStream;
004    import java.io.IOException;
005    import java.io.InputStream;
006    import java.io.OutputStream;
007    import java.io.Reader;
008    import java.io.StringReader;
009    import java.io.Writer;
010    import java.sql.Clob;
011    import java.sql.SQLException;
012    
013    import org.apache.commons.logging.Log;
014    import org.apache.commons.logging.LogFactory;
015    
016    /**
017     * Mock implementation of <code>Clob</code>.
018     */
019    public class MockClob implements Clob, Cloneable
020    {
021        private final static Log log = LogFactory.getLog(MockClob.class);
022        private StringBuffer clobData;
023        
024        public MockClob(String data)
025        {
026            clobData = new StringBuffer(data);
027        }
028    
029        public long length() throws SQLException
030        {
031            return clobData.length();
032        }
033    
034        public void truncate(long len) throws SQLException
035        {
036            clobData.setLength((int)len);
037        }
038    
039        public InputStream getAsciiStream() throws SQLException
040        {
041            return new ByteArrayInputStream(clobData.toString().getBytes());
042        }
043    
044        public OutputStream setAsciiStream(long pos) throws SQLException
045        {
046            return new ClobOutputStream((int)(pos - 1));
047        }
048    
049        public Reader getCharacterStream() throws SQLException
050        {
051            return new StringReader(clobData.toString());
052        }
053    
054        public Writer setCharacterStream(long pos) throws SQLException
055        {
056            return new ClobWriter((int)(pos - 1));
057        }
058    
059        public String getSubString(long pos, int length) throws SQLException
060        {
061            return clobData.substring((int)(pos - 1), (int)(pos - 1) + length);
062        }
063    
064        public int setString(long pos, String str) throws SQLException
065        {
066            return setString(pos, str, 0, str.length());
067        }
068    
069        public int setString(long pos, String str, int offset, int len) throws SQLException
070        {
071            str = str.substring(offset, offset + len);
072            clobData.replace((int)(pos - 1), (int)(pos - 1)+ str.length(), str);
073            return len;
074        }
075    
076        public long position(String searchstr, long start) throws SQLException
077        {
078            int index = clobData.toString().indexOf(searchstr, (int)(start - 1));
079            if(-1 != index) index += 1;
080            return index;
081        }
082    
083        public long position(Clob searchClob, long start) throws SQLException
084        {
085            return position(searchClob.getSubString(1, (int)searchClob.length()), start);
086        }
087        
088        private class ClobWriter extends Writer
089        {  
090            private int index;
091            
092            public ClobWriter(int index)
093            {
094                this.index = index;
095            }
096            
097            public void close() throws IOException
098            {
099    
100            }
101    
102            public void flush() throws IOException
103            {
104    
105            }
106    
107            public void write(char[] cbuf, int off, int len) throws IOException
108            {
109                try
110                {
111                    setString(index + 1, new String(cbuf, off, len));
112                }
113                catch(SQLException exc)
114                {
115                    throw new IOException(exc.getMessage());
116                }
117                index++;
118            }
119        }
120        
121        private class ClobOutputStream extends OutputStream
122        {  
123            private int index;
124        
125            public ClobOutputStream(int index)
126            {
127                this.index = index;
128            }
129        
130            public void write(int byteValue) throws IOException
131            {
132                byte[] bytes = new byte[] {(byte)byteValue};
133                try
134                {
135                    setString(index + 1, new String(bytes));
136                }
137                catch(SQLException exc)
138                {
139                    throw new IOException(exc.getMessage());
140                }
141                index++;
142            }
143        }
144        
145        public boolean equals(Object obj)
146        {
147            if(null == obj) return false;
148            if(!obj.getClass().equals(this.getClass())) return false;
149            MockClob other = (MockClob)obj;
150            return clobData.toString().equals(other.clobData.toString());
151        }
152    
153        public int hashCode()
154        {
155            return clobData.toString().hashCode();
156        }
157    
158        public String toString()
159        {
160            return "Clob data: " + clobData.toString();
161        }
162        
163        public Object clone()
164        {
165            try
166            {
167                MockClob clone = (MockClob)super.clone();
168                clone.clobData = new StringBuffer(clobData.toString());
169                return clone;
170            }
171            catch(CloneNotSupportedException exc)
172            {
173                log.error(exc.getMessage(), exc);
174            }
175            return null;
176        }
177    }