Package de.innovationgate.webgate.api.jdbc

Source Code of de.innovationgate.webgate.api.jdbc.HibernateQueryInputStream

/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.webgate.api.jdbc;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.Iterator;

import javax.imageio.IIOException;

import org.hibernate.Query;

import de.innovationgate.utils.io.IOBackendException;

/**
* Input stream implementation for Hibernate-Blob-Queries
*
*/
public class HibernateQueryInputStream extends InputStream {
 
  private static final int DEFAULT_BUFFERSIZE = 32; // 32 * 64k --> 2M

  private Iterator _data;
 
  private InputStream _input;
 
  private int _resultPos = 0;

  private Query _query;
 
  private int _bufferSize = 0;

  private boolean _disableQueryPaging;
 

  /**
   * Creates an input stream from the given query
   * The query should return only one column of type <code>Blob</code>
   * @param query
   * @param bufferSize the buffer size to use for streaming - actual heap usage will be (bufferSize * 64k)
   *            if bufferSize is <= 0 the default 32 will be used
   * @param disableQueryPaging true/false should hibernate query paging be used
   *           on databases like MySQL and Oracle query paging is recommend, on MSSQL paging will result in poor performance
   *           and should be disabled
   */
  public HibernateQueryInputStream(Query query, int bufferSize, boolean disableQueryPaging) {
    _query = query;
    _disableQueryPaging = disableQueryPaging;
    _bufferSize = bufferSize;
    if (_bufferSize <= 0) {
      _bufferSize = DEFAULT_BUFFERSIZE;
    }
    _query.setFetchSize(_bufferSize);
    if (!_disableQueryPaging) {
      _query.setFirstResult(0);
      _query.setMaxResults(_bufferSize);
      _resultPos = _bufferSize;
    }
   
    _data = _query.iterate();
  }

  /*
   * (non-Javadoc)
   * @see java.io.InputStream#read()
   */
  public int read() throws IOException {
    try {         
      if (_input == null) {
        // try to fetch first blob of the file
        if (_data.hasNext()) {
            AttachmentFilePart part = (AttachmentFilePart) _data.next();
          _input = part.getData().getBinaryStream();
        } else {
          return -1;
        }
      }
     
      int data = _input.read();     
      if (data != -1) {
        return data;
      }
      else {
          AttachmentFilePart part = fetchNextPart();
          if (part != null) {
              _input = part.getData().getBinaryStream();
              return _input.read();
          }
          else {
              return -1;
          }
      }
    }
    catch (SQLException e) {
      throw new HibernateQueryException("Exception reading file data", e);
    }   
  }
 
  private AttachmentFilePart fetchNextPart() throws SQLException {
     
      if (_data.hasNext()) {
            // fetch next part of file
            return (AttachmentFilePart) _data.next();
        }
       
        else {
            if (_disableQueryPaging) {
                // end of file reached
                return null;
            } else {
                // try if we can read more results from the database
                _query.setFirstResult(_resultPos);
                _resultPos += _bufferSize;
                _data = _query.iterate();
                if (_data.hasNext()) {
                   return (AttachmentFilePart) _data.next();
 
                } else {
                    // no more parts available - end of stream reached
                    return null;
                }
            }
        }
     
  }

    @Override
    public long skip(long n) throws IOException {
       
        long skipped = 0;
       
        try {
            // Skip remainder bytes of the current input
            if (_input != null) {
                long skippedNow = _input.skip(n);
                if (skippedNow > 0) {
                    skipped += skippedNow;
                }
                if (skipped >= n) {
                    return skipped;
                }
            }
           
            // Skip 64 kb blocks
            while ((n - skipped) >= WGDocumentImpl.ATTACHMENT_FILEPART_SIZE) {
                AttachmentFilePart part = fetchNextPart();
                if (part == null) {
                    return skipped;
                }
                skipped += WGDocumentImpl.ATTACHMENT_FILEPART_SIZE; // Is inexact since the last part may be <64 kb. But since we then have reached the end it should not matter what to report.
            }
           
            // Skip remaining bytes
            if ((n - skipped) > 0) {
                AttachmentFilePart part = fetchNextPart();
                if (part != null) {
                    _input = part.getData().getBinaryStream();
                    long skippedNow = _input.skip(n - skipped);
                    if (skippedNow > 0) {
                        skipped += skippedNow;
                    }
                }
            }
            return skipped;
        }
        catch (SQLException e) {
            throw new IOBackendException("Error executing SQL", e);
        }
       
    }

}
TOP

Related Classes of de.innovationgate.webgate.api.jdbc.HibernateQueryInputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.