Package de.aristaflow.adept2.util.io
Class RereadableContent
- java.lang.Object
-
- de.aristaflow.adept2.util.io.RereadableContent
-
- All Implemented Interfaces:
Closeable,AutoCloseable
- Direct Known Subclasses:
FileContent,MemoryContent,WrappingContent
public abstract class RereadableContent extends Object implements Closeable
TheRereadableContentcan be used when the content of anInputStreamneeds to be processed multiple times. Depending on its eventual size the whole content of the input stream is buffered in-memory - up to a certain threshold - or in a temporary file.The
RereadableContentas well as the provided input streams must beclosedafter use! This can be ensured by adhering to the following template:try (RereadableContentBuilder rcb = new RereadableContentBuilder(); RereadableContent rc = rcb.data(inputStream).build()) { ... try (InputStream is = rc.getInputStream()) { ... } ... try (InputStream is = rc.getInputStream()) { ... } ... }If you want to fill the builder using anOutputStreammake sure to fill and close this before building:try (RereadableContentBuilder rcb = new RereadableContentBuilder()) { ... try (OutputStream os = rcb.getOutputStream()) { ... } ... try (RereadableContent rc = rcb.build()) { ... } }You can also let theRereadableContentor theInputStreams get out of the block structure. But make sure toCloseable.close()them all.
AllRereadableContent rc; try (RereadableContentBuilder rcb = new RereadableContentBuilder()) { ... try (OutputStream os = rcb.getOutputStream()) { ... } rc = rbc.build(); } ... InputStream is1 = rc.getInputStream()) ... InputStream is2 = input.getInputStream()) ... // Just make sure to close them all (in arbitrary order). is1.close(); ... rc.close(); ... is2.close(); ...InputStreaminstances created by this class will beAttributedInputStreamalso providing the size and the SHA-512 hash of the stream data. The created streams will be tracked. TheRereadableContentwill not be closed when at least one of its input streams is still in use (has not been closed). It is ensured that closing will be done by the last active input stream (or by theRereadableContent). Also all of these will close in acleanupto make sure that they will be really closed.This class is thread-safe.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected static classRereadableContent.RrcCleanupprotected static classRereadableContent.RrcInputStreamThis class is an input stream that also provides theRereadableContentit has been created for.
-
Field Summary
Fields Modifier and Type Field Description protected Cleanup<IOException>cleanupThe clean-up called as post-mortem action of thisRereadableContent.protected Collection<Object>existingStreamsAll streams that have been created by thisRereadableContentincluding itself are identified by an arbitraryObject.protected CloseablefinalCleanupThe final clean-up to be executed after all streams and thisRereadableContenthave been closed/cleaned up.protected static StringRRC_INPUT_STREAM_SIZEThe name of theLongattribute providing the size of the input stream in bytes.protected byte[]sha512hashThe SHA-512 hash of the content.protected longsizeThe size of the content.
-
Constructor Summary
Constructors Modifier Constructor Description protectedRereadableContent(long size, byte[] sha512hash, Closeable finalCleanup)Creates a newRereadableContentfor the designated data.protectedRereadableContent(RereadableContent wrapped)Creates a newRereadableContentwrapping the designatedRereadableContentand creating a new input stream to keep the wrappedRereadableContentalive.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description voidclose()Closes the underlying stream or deletes the underlying file if there is no unclosedgetInputStream().protected abstract InputStreamcreateInputStream()Creates a new input stream for the content.booleanequals(Object obj)AttributedInputStreamgetInputStream()Gets an input stream for the data.byte[]getSHA512Hash()Gets the SHA—512 hash of the content.longgetSize()Gets the size of the content.static LonggetSize(InputStream is)Gets the size of the designated input stream in case it is provided viaRRC_INPUT_STREAM_SIZE,nullotherwise.inthashCode()
-
-
-
Field Detail
-
RRC_INPUT_STREAM_SIZE
protected static final String RRC_INPUT_STREAM_SIZE
The name of theLongattribute providing the size of the input stream in bytes.- See Also:
Attributable, Constant Field Values
-
size
protected final long size
The size of the content.
-
sha512hash
protected final byte[] sha512hash
The SHA-512 hash of the content.
-
existingStreams
protected final Collection<Object> existingStreams
All streams that have been created by thisRereadableContentincluding itself are identified by an arbitraryObject. They have a clean-up task used forInputStream.close()as well as post-mortem action. The task removes theObjectand the last one in the collection performs cleaning up theRereadableContent, for instance deleting the temporary file.
-
finalCleanup
protected final Closeable finalCleanup
The final clean-up to be executed after all streams and thisRereadableContenthave been closed/cleaned up.
-
cleanup
protected final Cleanup<IOException> cleanup
The clean-up called as post-mortem action of thisRereadableContent. Since this is the same logic, it is also used byclose().
-
-
Constructor Detail
-
RereadableContent
protected RereadableContent(long size, byte[] sha512hash, Closeable finalCleanup)Creates a newRereadableContentfor the designated data.- Parameters:
size- The size of the content.sha512hash- The SHA-512 hash of the content.finalCleanup- The final clean-up to be executed after all streams and theRereadableContenthave been closed/cleaned up.
-
RereadableContent
protected RereadableContent(RereadableContent wrapped) throws IOException
Creates a newRereadableContentwrapping the designatedRereadableContentand creating a new input stream to keep the wrappedRereadableContentalive.- Parameters:
wrapped- The wrappedRereadableContent.- Throws:
IOException- If creating a new input stream from the designatedRereadableContentfails, anIOExceptionwill be thrown.
-
-
Method Detail
-
getSize
public long getSize()
Gets the size of the content.- Returns:
- The size of the content.
-
getSHA512Hash
public byte[] getSHA512Hash()
Gets the SHA—512 hash of the content.- Returns:
- The SHA-512 hash of the content.
-
getInputStream
public AttributedInputStream getInputStream() throws IOException
Gets an input stream for the data. This method may be called multiple times. The returned stream must be closed properly after use!
Closing will not affect theInputStream.- Returns:
- An input stream for the data. The caller is responsible for closing.
- Throws:
IOException- If there are problems creating a new input stream for the data or thisRereadableContenthas already been closed, anIOExceptionwill be thrown.
-
createInputStream
protected abstract InputStream createInputStream() throws IOException
Creates a new input stream for the content.- Returns:
- A new input stream for the content. The caller is responsible for closing.
- Throws:
IOException- If there are problems creating a new input stream for the content, anIOExceptionwill be thrown.
-
close
public final void close() throws IOExceptionCloses the underlying stream or deletes the underlying file if there is no unclosedgetInputStream(). If there are input streams of thisRereadableContentthat have not been closed yet, closing deferred until closing the last one of these input streams.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Throws:
IOException- If closing or deleting fails, anIOExceptionwill be thrown.
-
getSize
public static Long getSize(InputStream is)
Gets the size of the designated input stream in case it is provided viaRRC_INPUT_STREAM_SIZE,nullotherwise.- Parameters:
is- The input stream for which to get the size (from the corresponding attribute).- Returns:
- The value of the size attribute of the designated input stream or
nullif not available.
-
-