001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.dao.jdbc;
016    
017    import com.liferay.portal.kernel.io.LimitedInputStream;
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.io.OutputStream;
022    
023    import java.sql.Blob;
024    import java.sql.SQLException;
025    
026    /**
027     * @author Shuyang Zhou
028     */
029    public class OutputBlob implements Blob {
030    
031            public OutputBlob(InputStream inputStream, long length) {
032                    if (inputStream == null) {
033                            throw new IllegalArgumentException("Input stream is null");
034                    }
035    
036                    if (length < 0) {
037                            throw new IllegalArgumentException("Length is less than 0");
038                    }
039    
040                    _inputStream = inputStream;
041                    _length = length;
042            }
043    
044            public void free() throws SQLException {
045                    try {
046                            _inputStream.close();
047                    }
048                    catch (IOException ioe) {
049                            throw new SQLException(ioe.getMessage());
050                    }
051    
052                    _inputStream = null;
053            }
054    
055            public InputStream getBinaryStream() {
056                    return _inputStream;
057            }
058    
059            public InputStream getBinaryStream(long pos, long length)
060                    throws SQLException {
061    
062                    if (pos < 1) {
063                            throw new SQLException("Position is less than 1");
064                    }
065    
066                    long offset = pos - 1;
067    
068                    if ((offset >= _length) || ((offset + length) >= _length)) {
069                            throw new SQLException("Invalid range");
070                    }
071    
072                    try {
073                            return new LimitedInputStream(_inputStream, offset, length);
074                    }
075                    catch (IOException ioe) {
076                            throw new SQLException(ioe.getMessage());
077                    }
078            }
079    
080            public byte[] getBytes(long pos, int length) throws SQLException {
081                    if (pos < 1) {
082                            throw new SQLException("Position is less than 1");
083                    }
084    
085                    if (length < 0) {
086                            throw new SQLException("Length is less than 0");
087                    }
088    
089                    byte[] bytes = new byte[length];
090    
091                    try {
092                            int newLength = 0;
093    
094                            int read = -1;
095    
096                            while ((newLength < length) &&
097                                       ((read = _inputStream.read(
098                                               bytes, newLength, length - newLength)) != -1)) {
099    
100                                    newLength += read;
101                            }
102    
103                            if (newLength < length) {
104                                    byte[] newBytes = new byte[newLength];
105    
106                                    System.arraycopy(bytes, 0, newBytes, 0, newLength);
107    
108                                    bytes = newBytes;
109                            }
110                    }
111                    catch (IOException ioe) {
112                            throw new SQLException(ioe.getMessage());
113                    }
114    
115                    return bytes;
116            }
117    
118            public long length() {
119                    return _length;
120            }
121    
122            public long position(Blob pattern, long start) {
123                    throw new UnsupportedOperationException();
124            }
125    
126            public long position(byte[] pattern, long start) {
127                    throw new UnsupportedOperationException();
128            }
129    
130            public OutputStream setBinaryStream(long pos) {
131                    throw new UnsupportedOperationException();
132            }
133    
134            public int setBytes(long pos, byte[] bytes) {
135                    throw new UnsupportedOperationException();
136            }
137    
138            public int setBytes(long pos, byte[] bytes, int offset, int length) {
139                    throw new UnsupportedOperationException();
140            }
141    
142            public void truncate(long length) {
143                    throw new UnsupportedOperationException();
144            }
145    
146            private InputStream _inputStream;
147            private long _length;
148    
149    }