001    /**
002     * Copyright (c) 2000-2013 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            @Override
045            public void free() throws SQLException {
046                    try {
047                            _inputStream.close();
048                    }
049                    catch (IOException ioe) {
050                            throw new SQLException(ioe.getMessage());
051                    }
052    
053                    _inputStream = null;
054            }
055    
056            @Override
057            public InputStream getBinaryStream() {
058                    return _inputStream;
059            }
060    
061            @Override
062            public InputStream getBinaryStream(long pos, long length)
063                    throws SQLException {
064    
065                    if (pos < 1) {
066                            throw new SQLException("Position is less than 1");
067                    }
068    
069                    long offset = pos - 1;
070    
071                    if ((offset >= _length) || ((offset + length) >= _length)) {
072                            throw new SQLException("Invalid range");
073                    }
074    
075                    try {
076                            return new LimitedInputStream(_inputStream, offset, length);
077                    }
078                    catch (IOException ioe) {
079                            throw new SQLException(ioe.getMessage());
080                    }
081            }
082    
083            @Override
084            public byte[] getBytes(long pos, int length) throws SQLException {
085                    if (pos < 1) {
086                            throw new SQLException("Position is less than 1");
087                    }
088    
089                    if (length < 0) {
090                            throw new SQLException("Length is less than 0");
091                    }
092    
093                    byte[] bytes = new byte[length];
094    
095                    try {
096                            int newLength = 0;
097    
098                            int read = -1;
099    
100                            while ((newLength < length) &&
101                                       ((read = _inputStream.read(
102                                               bytes, newLength, length - newLength)) != -1)) {
103    
104                                    newLength += read;
105                            }
106    
107                            if (newLength < length) {
108                                    byte[] newBytes = new byte[newLength];
109    
110                                    System.arraycopy(bytes, 0, newBytes, 0, newLength);
111    
112                                    bytes = newBytes;
113                            }
114                    }
115                    catch (IOException ioe) {
116                            throw new SQLException(ioe.getMessage());
117                    }
118    
119                    return bytes;
120            }
121    
122            @Override
123            public long length() {
124                    return _length;
125            }
126    
127            @Override
128            public long position(Blob pattern, long start) {
129                    throw new UnsupportedOperationException();
130            }
131    
132            @Override
133            public long position(byte[] pattern, long start) {
134                    throw new UnsupportedOperationException();
135            }
136    
137            @Override
138            public OutputStream setBinaryStream(long pos) {
139                    throw new UnsupportedOperationException();
140            }
141    
142            @Override
143            public int setBytes(long pos, byte[] bytes) {
144                    throw new UnsupportedOperationException();
145            }
146    
147            @Override
148            public int setBytes(long pos, byte[] bytes, int offset, int length) {
149                    throw new UnsupportedOperationException();
150            }
151    
152            @Override
153            public void truncate(long length) {
154                    throw new UnsupportedOperationException();
155            }
156    
157            private InputStream _inputStream;
158            private long _length;
159    
160    }