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.UnsupportedEncodingException;
010: import java.io.Writer;
011: import java.sql.Clob;
012: import java.sql.SQLException;
013:
014: import com.mockrunner.base.NestedApplicationException;
015:
016: /**
017: * Mock implementation of <code>Clob</code>.
018: */
019: public class MockClob implements Clob, Cloneable {
020: private StringBuffer clobData;
021: private boolean wasFreeCalled;
022:
023: public MockClob(String data) {
024: clobData = new StringBuffer(data);
025: wasFreeCalled = false;
026: }
027:
028: public long length() throws SQLException {
029: return clobData.length();
030: }
031:
032: public void truncate(long len) throws SQLException {
033: if (wasFreeCalled) {
034: throw new SQLException("free() was called");
035: }
036: clobData.setLength((int) len);
037: }
038:
039: public InputStream getAsciiStream() throws SQLException {
040: if (wasFreeCalled) {
041: throw new SQLException("free() was called");
042: }
043: try {
044: return new ByteArrayInputStream(clobData.toString()
045: .getBytes("ISO-8859-1"));
046: } catch (UnsupportedEncodingException exc) {
047: throw new NestedApplicationException(exc);
048: }
049: }
050:
051: public OutputStream setAsciiStream(long pos) throws SQLException {
052: if (wasFreeCalled) {
053: throw new SQLException("free() was called");
054: }
055: return new ClobOutputStream((int) (pos - 1));
056: }
057:
058: public Reader getCharacterStream() throws SQLException {
059: if (wasFreeCalled) {
060: throw new SQLException("free() was called");
061: }
062: return new StringReader(clobData.toString());
063: }
064:
065: public Reader getCharacterStream(long pos, long length)
066: throws SQLException {
067: if (wasFreeCalled) {
068: throw new SQLException("free() was called");
069: }
070: length = verifyAndFixLength(pos, (int) length);
071: return new StringReader(getSubString(pos, (int) length));
072: }
073:
074: public Writer setCharacterStream(long pos) throws SQLException {
075: if (wasFreeCalled) {
076: throw new SQLException("free() was called");
077: }
078: return new ClobWriter((int) (pos - 1));
079: }
080:
081: public String getSubString(long pos, int length)
082: throws SQLException {
083: if (wasFreeCalled) {
084: throw new SQLException("free() was called");
085: }
086: length = verifyAndFixLength(pos, length);
087: return clobData.substring((int) (pos - 1), (int) (pos - 1)
088: + length);
089: }
090:
091: public int setString(long pos, String str) throws SQLException {
092: return setString(pos, str, 0, str.length());
093: }
094:
095: public int setString(long pos, String str, int offset, int len)
096: throws SQLException {
097: if (wasFreeCalled) {
098: throw new SQLException("free() was called");
099: }
100: str = str.substring(offset, offset + len);
101: clobData.replace((int) (pos - 1), (int) (pos - 1)
102: + str.length(), str);
103: return len;
104: }
105:
106: public long position(String searchstr, long start)
107: throws SQLException {
108: if (wasFreeCalled) {
109: throw new SQLException("free() was called");
110: }
111: int index = clobData.toString().indexOf(searchstr,
112: (int) (start - 1));
113: if (-1 != index)
114: index += 1;
115: return index;
116: }
117:
118: public long position(Clob searchClob, long start)
119: throws SQLException {
120: return position(searchClob.getSubString(1, (int) searchClob
121: .length()), start);
122: }
123:
124: public void free() throws SQLException {
125: wasFreeCalled = true;
126: }
127:
128: /**
129: * Returns if {@link #free} has been called.
130: * @return <code>true</code> if {@link #free} has been called,
131: * <code>false</code> otherwise
132: */
133: public boolean wasFreeCalled() {
134: return wasFreeCalled;
135: }
136:
137: public boolean equals(Object obj) {
138: if (null == obj)
139: return false;
140: if (!obj.getClass().equals(this .getClass()))
141: return false;
142: MockClob other = (MockClob) obj;
143: if (wasFreeCalled != other.wasFreeCalled())
144: return false;
145: return clobData.toString().equals(other.clobData.toString());
146: }
147:
148: public int hashCode() {
149: int hashCode = clobData.toString().hashCode();
150: hashCode = (31 * hashCode) + (wasFreeCalled ? 31 : 62);
151: return hashCode;
152: }
153:
154: public String toString() {
155: return "Clob data: " + clobData.toString();
156: }
157:
158: public Object clone() {
159: try {
160: MockClob clone = (MockClob) super .clone();
161: clone.clobData = new StringBuffer(clobData.toString());
162: return clone;
163: } catch (CloneNotSupportedException exc) {
164: throw new NestedApplicationException(exc);
165: }
166: }
167:
168: private int verifyAndFixLength(long pos, int length) {
169: if (length < 0) {
170: throw new IllegalArgumentException(
171: "length must be greater or equals 0");
172: }
173: if ((length + (pos - 1)) > clobData.length()) {
174: return clobData.length() - (int) (pos - 1);
175: }
176: return length;
177: }
178:
179: private class ClobWriter extends Writer {
180: private int index;
181:
182: public ClobWriter(int index) {
183: this .index = index;
184: }
185:
186: public void close() throws IOException {
187:
188: }
189:
190: public void flush() throws IOException {
191:
192: }
193:
194: public void write(char[] cbuf, int off, int len)
195: throws IOException {
196: try {
197: setString(index + 1, new String(cbuf, off, len));
198: } catch (SQLException exc) {
199: throw new IOException(exc.getMessage());
200: }
201: index++;
202: }
203: }
204:
205: private class ClobOutputStream extends OutputStream {
206: private int index;
207:
208: public ClobOutputStream(int index) {
209: this .index = index;
210: }
211:
212: public void write(int byteValue) throws IOException {
213: byte[] bytes = new byte[] { (byte) byteValue };
214: try {
215: setString(index + 1, new String(bytes));
216: } catch (SQLException exc) {
217: throw new IOException(exc.getMessage());
218: }
219: index++;
220: }
221: }
222: }
|