//idega 2001 - Eirikur Hrafnsson , eiki@idega.is
/*
*Copyright 2001 idega.is All Rights Reserved.
*/
package com.idega.data;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.idega.util.database.ConnectionBroker;
/**
* This is a class to read from BLOB columns in GenericEntity classes to be used as a regular InputStream
*@author <a href="mailto:eiki@idega.is">Eirikur Hrafnsson</a> @modified by <a href="mailto:tryggvi@idega.is">Tryggvi Larusson</a>
*@version 1.0
*/
public class BlobInputStream extends InputStream {
private InputStream input;
private Connection connection;
private GenericEntity entity;
private ResultSet RS;
private Statement Stmt;
private String columnName;
private String dataSource;
private boolean readFromEntityBlob=false;
private boolean isClosed=true;
/**
* Takes the first BLOB column found in the entity
* @param entity
*/
public BlobInputStream(GenericEntity entity){
this(entity,entity._lobColumnName);
}
public BlobInputStream(GenericEntity entity, String tableColumnName){
this.setEntity(entity);
this.setTableColumnName(tableColumnName);
//initConnection();
//getInputStreamForBlobRead();
}
public BlobInputStream(InputStream in) {
setInternalInputStream(in);
this.isClosed=false;
}
public void setEntity(GenericEntity entity) {
this.entity = entity;
setDataSource(entity.getDatasource());
//For Safetys sake if this BlobInputStream has been previously used with another entity entity instanse or inputstream:
closeInternalInputStream();
closeSQLVariables();
this.readFromEntityBlob=true;
this.isClosed=false;
}
public void setDataSource(String dataSourceName) {
this.dataSource = dataSourceName;
}
public String getDataSource() {
return this.dataSource;
}
public void setTableColumnName(String columnName) {
this.columnName = columnName;
}
public int read() throws IOException {
InputStream in = getInternalInputStream();
if (in!= null) {
return in.read();
//else throw new IOException("BlobInputStream: read() inputstream is null!");
}
else {
return -1;
}
}
public int read(byte b[], int off, int len) throws IOException {
InputStream in =getInternalInputStream();
if (in != null) {
return in.read(b, off, len);
//else throw new IOException("BlobInputStream: read(byte b[], int off, int len) inputstream is null!");
}
else {
return -1;
}
}
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
*<STRONG>Mandatory</STRONG> to call this function using this class
**/
public void close() throws IOException {
try{
InputStream in = getInternalInputStream();
if (in != null) {
in.close();
in = null;
}
//debug for interbase...not closing the stream
// if( in!=null) in.close();
} finally {
closeInternalInputStream();
closeSQLVariables();
}
}
// basic inputstream functions
public int available() throws IOException {
InputStream in = getInternalInputStream();
if (in != null) {
return in.available();
}
else {
return 0;
}
}
public boolean markSupported() {
InputStream in = getInternalInputStream();
if (in != null) {
return in.markSupported();
}
else {
return false;
}
}
public synchronized void mark(int readlimit) {
InputStream in = getInternalInputStream();
if (in != null) {
in.mark(readlimit);
}
}
public long skip(long n) throws IOException {
InputStream in = getInternalInputStream();
if (in != null) {
return in.skip(n);
}
else {
return -1;
//else throw new IOException("BlobInputStream: skip() inputstream is null!");
}
}
public synchronized void reset() throws IOException {
InputStream in = getInternalInputStream();
if (in != null) {
in.reset();
}
else {
throw new IOException("BlobInputStream: reset() inputstream is null!");
/*else{
close();
this.getInputStreamForBlobRead();
}*/
}
}
protected InputStream getInputStreamForBlobRead() {
InputStream in=null;
try {
if (in == null) {
Connection conn = getConnection();
if (this.connection != null) {
DatastoreInterface dsi = DatastoreInterface.getInstance(conn);
this.Stmt = this.connection.createStatement();
StringBuffer statement = new StringBuffer();
statement.append("select ");
statement.append(getTableColumnName());
statement.append(" from ");
statement.append(this.entity.getTableName());
dsi.appendPrimaryKeyWhereClause(this.entity,statement);
String sql = statement.toString();
this.RS = this.Stmt.executeQuery(sql);
/*
RS = Stmt.executeQuery(
"select "
+ getTableColumnName()
+ " from "
+ entity.getTableName()
+ " where "
+ entity.getIDColumnName()
+ "='"
+ entity.getID()
+ "'");*/
if ((this.RS != null) && (this.RS.next())) {
in = this.RS.getBinaryStream(1);
//System.out.println("in is set for "+entity.getClass().getName()+", id="+entity.getID());
} else {
closeSQLVariables();
}
}
}
} catch (SQLException ex) {
System.err.println("SQLException in BlobInputStream.getInputStreamForBlobRead(): " + ex.getMessage());
ex.printStackTrace(System.err);
}
return in;
}
public GenericEntity getEntity() {
return this.entity;
}
public boolean isClosed() {
return this.isClosed;
}
private String getTableColumnName() {
return this.columnName;
}
private Connection getConnection(){
if(this.connection==null){
this.connection=ConnectionBroker.getConnection(getDataSource());
}
return this.connection;
}
private InputStream getInternalInputStream(){
if(this.readFromEntityBlob&& (!this.isClosed) && this.input==null){
this.input = getInputStreamForBlobRead();
}
return this.input;
}
private void setInternalInputStream(InputStream in){
this.input=in;
}
private void closeInternalInputStream(){
if (this.input != null) {
try
{
this.input.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
this.input = null;
}
this.isClosed=true;
}
private void closeSQLVariables(){
if (this.RS != null) {
try {
this.RS.close();
} catch (SQLException sqle) {
System.err.println("BlobInputStream : error closing SQL ResultSet");
sqle.printStackTrace(System.err);
}
this.RS = null;
}
if (this.Stmt != null) {
try {
this.Stmt.close();
} catch (SQLException sqle) {
System.err.println("BlobInputStream : error closing SQL Statement");
sqle.printStackTrace(System.err);
}
this.Stmt = null;
}
if (this.connection != null) {
ConnectionBroker.freeConnection(getDataSource(), this.connection);
this.connection = null;
}
}
/*
protected void finalize()throws Throwable{
close();
super.finalize();
}
*/
}