blob: ba9bb401bccb78eb202589d1e80d6b37340a01c4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.stanbol.enhancer.servicesapi.impl;
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.stanbol.enhancer.servicesapi.Blob;
import org.apache.stanbol.enhancer.servicesapi.ContentSource;
/**
* Allows to use a {@link InputStream} as {@link ContentSource}. This is the
* most common case, that all the contents passed via the RESTful interface of
* the Stanbol Enhancer will be passed as {@link InputStream}.
* @author Rupert Westenthaler
*
*/
public class StreamSource implements ContentSource {
private static final Map<String,List<String>> NO_HEADERS = Collections.emptyMap();
private final InputStream in;
private final String mt;
private final String name;
private final Map<String,List<String>> headers;
private boolean consumed = false;
private byte[] data;
/**
* Constructs a StreamSource for the passed InputStream. The mime type will
* be set to "<code>application/octet-stream</code>"
* @param in the stream
*/
public StreamSource(InputStream in) {
this(in,null,null,null);
}
/**
* Constructs a stream source for the passed stream and mime type. When
* parsing text the charset should be set as mime type parameter (e.g.
* "<code>text/plain; charset=UTF-8</code>". UTF-8 is assumed as default if
* missing.
* @param in the stream
* @param mt the media type or <code>null</code> if unknown
*/
public StreamSource(InputStream in, String mt) {
this(in,mt,null,null);
}
/**
* Constructs a stream source for the passed stream and mime type. When
* parsing text the charset should be set as mime type parameter (e.g.
* "<code>text/plain; charset=UTF-8</code>". UTF-8 is assumed as default if
* missing. <p>
* This allows in addition to pass the file name of the original file.
* NOTE however this information is currently not used as the {@link Blob}
* interface does not support those information
* @param in the stream
* @param mt the media type or <code>null</code> if unknown
* @param fileName the file name or <code>null</code> if unknown
*/
public StreamSource(InputStream in, String mt,String fileName) {
this(in,mt,fileName,null);
}
/**
* Constructs a stream source for the passed stream and mime type. When
* parsing text the charset should be set as mime type parameter (e.g.
* "<code>text/plain; charset=UTF-8</code>". UTF-8 is assumed as default if
* missing. <p>
* This allows in addition to pass a map with additional header filds
* (e.g. HTTP headers). <br>
* NOTE however this information is currently not used
* as the {@link Blob} interface does not support those information
* @param in the stream
* @param mt the media type or <code>null</code> if unknown
* @param headers additional headers or <code>null</code>/empty map if none.
*/
public StreamSource(InputStream in, String mt,Map<String,List<String>> headers) {
this(in,mt,null,headers);
}
/**
* Constructs a stream source for the passed stream and mime type. When
* parsing text the charset should be set as mime type parameter (e.g.
* "<code>text/plain; charset=UTF-8</code>". UTF-8 is assumed as default if
* missing. <p>
* This allows in addition to pass the file name and a map with
* additional header fields (e.g. HTTP headers). <br>
* NOTE however this information is currently not used
* as the {@link Blob} interface does not support those information
* @param in the stream
* @param mt the media type or <code>null</code> if unknown
* @param fileName the file name or <code>null</code> if unknown
* @param headers additional headers or <code>null</code>/empty map if none.
*/
public StreamSource(InputStream in, String mt,String fileName,Map<String,List<String>> headers) {
if(in == null){
throw new IllegalArgumentException("The passed InputStream MUST NOT be NULL!");
}
this.in = in;
this.mt = mt == null ? "application/octet-stream" : mt;
this.name = fileName;
this.headers = headers == null ? NO_HEADERS : headers;
}
@Override
public synchronized InputStream getStream() {
if(data != null){
return new ByteArrayInputStream(data);
}
if(consumed){
throw new IllegalStateException("This InputStream of this ContentSource is already consumed!");
}
consumed = true;
return new NonCloseableInputStream(in);
}
@Override
public synchronized byte[] getData() throws IOException {
if(data == null){
data = IOUtils.toByteArray(in);
}
return data;
}
@Override
public String getMediaType() {
return mt;
}
@Override
public String getFileName() {
return name;
}
@Override
public Map<String,List<String>> getHeaders() {
return headers;
}
// The parsed Stream MUST NOT be closed (STANBOL-898)
// @Override
// protected void finalize() throws Throwable {
// IOUtils.closeQuietly(in);
// }
/**
* Internally used to ensure that InputStreams returned by
* {@link StreamSource#getStream()} can not be closed by callers (as
* requested by STANBOL-898)
*/
private static class NonCloseableInputStream extends FilterInputStream {
protected NonCloseableInputStream(InputStream in) {
super(in);
}
@Override
public void close() throws IOException {
//ignore call to close
}
}
}