001 /*
002 *
003 * $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.backend.hibernate.tables;
025
026 import java.io.ByteArrayInputStream;
027 import java.io.InputStream;
028 import java.io.OutputStream;
029 import java.sql.Blob;
030 import java.sql.SQLException;
031
032 import org.apache.log4j.Logger;
033
034 import org.mycore.common.MCRException;
035
036 public class MCRBlob implements java.sql.Blob {
037 byte[] data;
038
039 MCRBlob(byte[] data) {
040 this.data = data;
041 }
042
043 public InputStream getBinaryStream() {
044 return new java.io.ByteArrayInputStream(this.data);
045 }
046
047 public OutputStream setBinaryStream(long l) {
048 throw new IllegalArgumentException("not implemented");
049 }
050
051 public int setBytes(long l, byte[] a, int u, int v) {
052 throw new IllegalArgumentException("not implemented");
053 }
054
055 public int setBytes(long l, byte[] a) {
056 throw new IllegalArgumentException("not implemented");
057 }
058
059 public void truncate(long l) {
060 throw new IllegalArgumentException("not implemented");
061 }
062
063 public byte[] getBytes(long pos, int length) throws SQLException {
064 if (pos < 1)
065 throw new SQLException("The ordinal position is less than 1: " + pos);
066 if (pos > Integer.MAX_VALUE)
067 throw new ArrayIndexOutOfBoundsException("Ordinal position grater than " + Integer.MAX_VALUE + " is not supported:" + pos);
068 if (length < 0)
069 throw new SQLException("The number of consecutive bytes to be copied must be 0 or greater: " + length);
070 // first byte is position 1 according to java.sql API, but position 0 in
071 // array
072 int arrayPos = (int) (pos - 1);
073 if ((arrayPos + length) > data.length) {
074 length = (int) (data.length - arrayPos);
075 }
076
077 byte[] result = new byte[length];
078 System.arraycopy(data, arrayPos, result, 0, length);
079
080 return result;
081 }
082
083 public long length() {
084 return this.data.length;
085 }
086
087 // Determines the byte position at which the specified byte pattern begins
088 // within the BLOB value that this Blob object represents.
089 public long position(byte[] pattern, long start) throws SQLException {
090 if (start < 1)
091 throw new SQLException("The start position is less than 1: " + start);
092 if (start > Integer.MAX_VALUE)
093 throw new ArrayIndexOutOfBoundsException("Start position grater than " + Integer.MAX_VALUE + " is not supported:" + start);
094 int arrayPos;
095 // first byte is position 1 according to java.sql API, but position 0 in
096 // array
097 searchloop: for (arrayPos = (int) start - 1; arrayPos < data.length; arrayPos++) {
098 int s;
099 int len = data.length - arrayPos;
100
101 if (pattern.length > (data.length - arrayPos)) {
102 break searchloop;
103 }
104
105 for (s = 0; s < len; s++) {
106 if (pattern[s] != data[arrayPos]) {
107 continue searchloop;
108 }
109 }
110 // again first byte in java.sql API is at position 1
111 return arrayPos + 1;
112 }
113
114 return -1;
115 }
116
117 // Determines the byte position in the BLOB value designated by this Blob
118 // object at which pattern begins.
119 public long position(Blob pattern, long start) throws SQLException {
120 byte[] b = pattern.getBytes(0, (int) pattern.length());
121
122 return position(b, start);
123 }
124
125 public static byte[] getBytes(Blob blob) {
126 try {
127 if (blob.length() > Integer.MAX_VALUE) {
128 throw new MCRException("Blobs longer than " + Integer.MAX_VALUE + " are not supported: " + blob.length());
129 }
130 return blob.getBytes(1, (int) blob.length());
131 } catch (java.sql.SQLException e) {
132 // TODO: check if this should be thrown
133 Logger.getLogger(MCRBlob.class).error("Caught SQLException." + e);
134 return null;
135 }
136 }
137
138 public void free() throws SQLException {
139 data = null;
140 }
141
142 public InputStream getBinaryStream(long pos, long length) throws SQLException {
143 if (pos < 1)
144 throw new SQLException("The ordinal position is less than 1: " + pos);
145 if (pos > data.length)
146 throw new ArrayIndexOutOfBoundsException("Ordinal position is greater than the number of bytes (" + data.length + ") in the Blob: " + length);
147 if (length < 0)
148 throw new SQLException("The number of consecutive bytes to be copied must be 0 or greater: " + length);
149 if ((pos + length) > data.length)
150 throw new SQLException("The ordinal position(" + pos + ") + the length(" + length + ") in bytes are greater than the number of bytes ("
151 + data.length + ") in the Blob.");
152 // first byte is position 1 according to java.sql API, but position 0 in
153 // array
154 return new ByteArrayInputStream(data, (int) pos - 1, (int) length);
155 }
156 }