/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.core.types;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.sql.SQLXML;
import javax.activation.DataSource;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialClob;
import javax.xml.transform.Source;
import org.teiid.core.util.ReaderInputStream;
public abstract class InputStreamFactory implements Source {
public enum StorageMode {
MEMORY, //TODO: sources may return Serial values that are much too large and we should convert them to persistent.
PERSISTENT,
FREE,
OTHER
}
public interface StreamFactoryReference {
void setStreamFactory(InputStreamFactory inputStreamFactory);
}
private String systemId;
protected long length = -1;
/**
* Get a new InputStream
* @return
*/
public abstract InputStream getInputStream() throws IOException;
@Override
public String getSystemId() {
return this.systemId;
}
@Override
public void setSystemId(String systemId) {
this.systemId = systemId;
}
/**
* @throws IOException
*/
public void free() throws IOException {
}
/**
* Length in bytes of the {@link InputStream}
* @return the length or -1 if the length is not known
*/
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
/**
* @throws IOException
*/
public Reader getCharacterStream() throws IOException {
return null;
}
public StorageMode getStorageMode() {
return StorageMode.OTHER;
}
public static class FileInputStreamFactory extends InputStreamFactory {
private File f;
public FileInputStreamFactory(File f) {
this.f = f;
this.setSystemId(f.toURI().toASCIIString());
}
@Override
public long getLength() {
return f.length();
}
@Override
public InputStream getInputStream() throws IOException {
return new BufferedInputStream(new FileInputStream(f));
}
@Override
public StorageMode getStorageMode() {
return StorageMode.PERSISTENT;
}
}
public static class ClobInputStreamFactory extends InputStreamFactory implements DataSource {
private Clob clob;
private Charset charset = Charset.forName(Streamable.ENCODING);
public ClobInputStreamFactory(Clob clob) {
this.clob = clob;
}
public Charset getCharset() {
return charset;
}
public void setCharset(Charset charset) {
this.charset = charset;
}
@Override
public InputStream getInputStream() throws IOException {
try {
return new ReaderInputStream(clob.getCharacterStream(), charset);
} catch (SQLException e) {
throw new IOException(e);
}
}
@Override
public Reader getCharacterStream() throws IOException {
try {
return clob.getCharacterStream();
} catch (SQLException e) {
throw new IOException(e);
}
}
@Override
public String getContentType() {
return "text/plain"; //$NON-NLS-1$
}
@Override
public String getName() {
return "clob"; //$NON-NLS-1$
}
@Override
public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public StorageMode getStorageMode() {
return getStorageMode(clob);
}
}
public static class BlobInputStreamFactory extends InputStreamFactory implements DataSource {
private Blob blob;
public BlobInputStreamFactory(Blob blob) {
this.blob = blob;
}
@Override
public InputStream getInputStream() throws IOException {
try {
return blob.getBinaryStream();
} catch (SQLException e) {
throw new IOException(e);
}
}
@Override
public long getLength() {
if (length == -1) {
try {
length = blob.length();
} catch (SQLException e) {
}
}
return length;
}
@Override
public String getContentType() {
return "application/octet-stream"; //$NON-NLS-1$
}
@Override
public String getName() {
return "blob"; //$NON-NLS-1$
}
@Override
public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public StorageMode getStorageMode() {
return getStorageMode(blob);
}
}
public static StorageMode getStorageMode(Object lob) {
if (lob instanceof Streamable<?>) {
return getStorageMode(((Streamable<?>)lob).getReference());
}
if (lob instanceof SerialClob) {
return StorageMode.MEMORY;
}
if (lob instanceof SerialBlob) {
return StorageMode.MEMORY;
}
if (lob instanceof BaseLob) {
BaseLob baseLob = (BaseLob)lob;
try {
return baseLob.getStreamFactory().getStorageMode();
} catch (SQLException e) {
return StorageMode.FREE;
}
}
return StorageMode.OTHER;
}
public static class SQLXMLInputStreamFactory extends InputStreamFactory implements DataSource {
protected SQLXML sqlxml;
public SQLXMLInputStreamFactory(SQLXML sqlxml) {
this.sqlxml = sqlxml;
}
@Override
public InputStream getInputStream() throws IOException {
try {
return sqlxml.getBinaryStream();
} catch (SQLException e) {
throw new IOException(e);
}
}
@Override
public Reader getCharacterStream() throws IOException {
try {
return sqlxml.getCharacterStream();
} catch (SQLException e) {
throw new IOException(e);
}
}
@Override
public String getContentType() {
return "application/xml"; //$NON-NLS-1$
}
@Override
public String getName() {
return "sqlxml"; //$NON-NLS-1$
}
@Override
public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public StorageMode getStorageMode() {
return getStorageMode(sqlxml);
}
}
}