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.sql.Blob;
008: import java.sql.SQLException;
009: import java.util.ArrayList;
010: import java.util.List;
011:
012: import com.mockrunner.base.NestedApplicationException;
013: import com.mockrunner.util.common.ArrayUtil;
014: import com.mockrunner.util.common.CollectionUtil;
015:
016: /**
017: * Mock implementation of <code>Blob</code>.
018: */
019: public class MockBlob implements Blob, Cloneable {
020: private List blobData;
021: private boolean wasFreeCalled;
022:
023: public MockBlob(byte[] data) {
024: blobData = ArrayUtil.getListFromByteArray(data);
025: wasFreeCalled = false;
026: }
027:
028: public long length() throws SQLException {
029: if (wasFreeCalled) {
030: throw new SQLException("free() was called");
031: }
032: return blobData.size();
033: }
034:
035: public byte[] getBytes(long pos, int length) throws SQLException {
036: if (wasFreeCalled) {
037: throw new SQLException("free() was called");
038: }
039: length = verifyAndFixLength(pos, length);
040: return ArrayUtil.getByteArrayFromList(blobData,
041: (int) (pos - 1), length);
042: }
043:
044: public InputStream getBinaryStream() throws SQLException {
045: if (wasFreeCalled) {
046: throw new SQLException("free() was called");
047: }
048: return new ByteArrayInputStream(ArrayUtil
049: .getByteArrayFromList(blobData));
050: }
051:
052: public InputStream getBinaryStream(long pos, long length)
053: throws SQLException {
054: if (wasFreeCalled) {
055: throw new SQLException("free() was called");
056: }
057: length = verifyAndFixLength(pos, (int) length);
058: return new ByteArrayInputStream(ArrayUtil.getByteArrayFromList(
059: blobData, (int) (pos - 1), (int) length));
060: }
061:
062: public long position(byte[] pattern, long start)
063: throws SQLException {
064: if (wasFreeCalled) {
065: throw new SQLException("free() was called");
066: }
067: byte[] data = ArrayUtil.getByteArrayFromList(blobData);
068: int index = ArrayUtil.indexOf(data, pattern, (int) (start - 1));
069: if (-1 != index)
070: index += 1;
071: return index;
072: }
073:
074: public long position(Blob pattern, long start) throws SQLException {
075: return position(pattern.getBytes(1, (int) pattern.length()),
076: start);
077: }
078:
079: public int setBytes(long pos, byte[] bytes) throws SQLException {
080: if (wasFreeCalled) {
081: throw new SQLException("free() was called");
082: }
083: ArrayUtil.addBytesToList(bytes, blobData, (int) (pos - 1));
084: return bytes.length;
085: }
086:
087: public int setBytes(long pos, byte[] bytes, int offset, int len)
088: throws SQLException {
089: if (wasFreeCalled) {
090: throw new SQLException("free() was called");
091: }
092: ArrayUtil.addBytesToList(bytes, offset, len, blobData,
093: (int) (pos - 1));
094: return len;
095: }
096:
097: public OutputStream setBinaryStream(long pos) throws SQLException {
098: if (wasFreeCalled) {
099: throw new SQLException("free() was called");
100: }
101: return new BlobOutputStream((int) (pos - 1));
102: }
103:
104: public void truncate(long len) throws SQLException {
105: if (wasFreeCalled) {
106: throw new SQLException("free() was called");
107: }
108: blobData = CollectionUtil.truncateList(blobData, (int) len);
109: }
110:
111: public void free() throws SQLException {
112: wasFreeCalled = true;
113: }
114:
115: /**
116: * Returns if {@link #free} has been called.
117: * @return <code>true</code> if {@link #free} has been called,
118: * <code>false</code> otherwise
119: */
120: public boolean wasFreeCalled() {
121: return wasFreeCalled;
122: }
123:
124: public boolean equals(Object obj) {
125: if (null == obj)
126: return false;
127: if (!obj.getClass().equals(this .getClass()))
128: return false;
129: MockBlob other = (MockBlob) obj;
130: if (wasFreeCalled != other.wasFreeCalled())
131: return false;
132: return blobData.equals(other.blobData);
133: }
134:
135: public int hashCode() {
136: int hashCode = blobData.hashCode();
137: hashCode = (31 * hashCode) + (wasFreeCalled ? 31 : 62);
138: return hashCode;
139: }
140:
141: public String toString() {
142: return "Blob data: " + blobData.toString();
143: }
144:
145: public Object clone() {
146: try {
147: MockBlob blob = (MockBlob) super .clone();
148: blob.blobData = new ArrayList(blobData);
149: return blob;
150: } catch (CloneNotSupportedException exc) {
151: throw new NestedApplicationException(exc);
152: }
153: }
154:
155: private int verifyAndFixLength(long pos, int length) {
156: if (length < 0) {
157: throw new IllegalArgumentException(
158: "length must be greater or equals 0");
159: }
160: if ((length + (pos - 1)) > blobData.size()) {
161: return blobData.size() - (int) (pos - 1);
162: }
163: return length;
164: }
165:
166: private class BlobOutputStream extends OutputStream {
167: private int index;
168:
169: public BlobOutputStream(int index) {
170: this .index = index;
171: }
172:
173: public void write(int byteValue) throws IOException {
174: byte[] bytes = new byte[] { (byte) byteValue };
175: ArrayUtil.addBytesToList(bytes, blobData, index);
176: index++;
177: }
178: }
179: }
|