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    }