org.apache.xmlgraphics.image.loader.impl.ImageRawStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xmlgraphics-commons Show documentation
Show all versions of xmlgraphics-commons Show documentation
Apache XML Graphics Commons is a library that consists of several reusable
components used by Apache Batik and Apache FOP. Many of these components
can easily be used separately outside the domains of SVG and XSL-FO.
/*
* 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.
*/
/* $Id: ImageRawStream.java 1681137 2015-05-22 14:54:05Z ssteiner $ */
package org.apache.xmlgraphics.image.loader.impl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.MimeEnabledImageFlavor;
/**
* This class is an implementation of the Image interface exposing an InputStream for loading the
* raw/undecoded image.
*/
public class ImageRawStream extends AbstractImage {
private ImageFlavor flavor;
private InputStreamFactory streamFactory;
/**
* Main constructor.
* @param info the image info object
* @param flavor the image flavor for the raw image
* @param streamFactory the InputStreamFactory that is used to create InputStream instances
*/
public ImageRawStream(ImageInfo info, ImageFlavor flavor, InputStreamFactory streamFactory) {
super(info);
this.flavor = flavor;
setInputStreamFactory(streamFactory);
}
/**
* Constructor for a simple InputStream as parameter.
* @param info the image info object
* @param flavor the image flavor for the raw image
* @param in the InputStream with the raw content
*/
public ImageRawStream(ImageInfo info, ImageFlavor flavor, InputStream in) {
this(info, flavor, new SingleStreamFactory(in));
}
/** {@inheritDoc} */
public ImageFlavor getFlavor() {
return this.flavor;
}
/**
* Returns the MIME type of the stream data.
* @return the MIME type
*/
public String getMimeType() {
if (getFlavor() instanceof MimeEnabledImageFlavor) {
return getFlavor().getMimeType();
} else {
//Undetermined
return "application/octet-stream";
}
}
/** {@inheritDoc} */
public boolean isCacheable() {
return !this.streamFactory.isUsedOnceOnly();
}
/**
* Sets the InputStreamFactory to be used by this image. This method allows to replace the
* original factory.
* @param factory the new InputStreamFactory
*/
public void setInputStreamFactory(InputStreamFactory factory) {
if (this.streamFactory != null) {
this.streamFactory.close();
}
this.streamFactory = factory;
}
/**
* Returns a new InputStream to access the raw image.
* @return the InputStream
*/
public InputStream createInputStream() {
return this.streamFactory.createInputStream();
}
/**
* Writes the content of the image to an OutputStream. The OutputStream in NOT closed at the
* end.
* @param out the OutputStream
* @throws IOException if an I/O error occurs
*/
public void writeTo(OutputStream out) throws IOException {
InputStream in = createInputStream();
try {
IOUtils.copy(in, out);
} finally {
IOUtils.closeQuietly(in);
}
}
/**
* Represents a factory for InputStream objects. Make sure the class is thread-safe!
*/
public interface InputStreamFactory {
/**
* Indicates whether this factory is only usable once or many times.
* @return true if the factory can only be used once
*/
boolean isUsedOnceOnly();
/**
* Creates and returns a new InputStream.
* @return the new InputStream
*/
InputStream createInputStream();
/**
* Closes the factory and releases any resources held open during the lifetime of this
* object.
*/
void close();
}
/**
* InputStream factory that can return a pre-constructed InputStream exactly once.
*/
private static class SingleStreamFactory implements InputStreamFactory {
private InputStream in;
public SingleStreamFactory(InputStream in) {
this.in = in;
}
public synchronized InputStream createInputStream() {
if (this.in != null) {
InputStream tempin = this.in;
this.in = null; //Don't close, just remove the reference
return tempin;
} else {
throw new IllegalStateException("Can only create an InputStream once!");
}
}
public synchronized void close() {
IOUtils.closeQuietly(this.in);
this.in = null;
}
public boolean isUsedOnceOnly() {
return true;
}
/** {@inheritDoc} */
protected void finalize() {
close();
}
}
/**
* InputStream factory that wraps a byte array.
*/
public static class ByteArrayStreamFactory implements InputStreamFactory {
private byte[] data;
/**
* Main constructor.
* @param data the byte array
*/
public ByteArrayStreamFactory(byte[] data) {
this.data = data;
}
/** {@inheritDoc} */
public InputStream createInputStream() {
return new ByteArrayInputStream(data);
}
/** {@inheritDoc} */
public void close() {
//nop
}
/** {@inheritDoc} */
public boolean isUsedOnceOnly() {
return false;
}
}
}