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
TheRereadableContent
can be used when the content of anInputStream
needs 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
RereadableContent
as well as the provided input streams must beclosed
after use! This can be ensured by adhering to the following template:try (RereadableContentBuilder rcb = new RereableContentBuilder(); RereadableContent rc = rcb.data(inputStream).build()) { ... try (InputStream is = rc.getInputStream()) { ... } ... try (InputStream is = rc.getInputStream()) { ... } ... }
If you want to fill the builder using anOutputStream
make 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 theRereadableContent
or theInputStream
s get out of the block structure. But make sure toCloseable.close()
them all.RereadableContent 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(); ...
InputStream
instances created by this class will beAttributedInputStream
also providing the size and the SHA-512 hash of the stream data. The created streams will be tracked. TheRereadableContent
will 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 acleanup
to 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 class
RereadableContent.RrcCleanup
protected static class
RereadableContent.RrcInputStream
This class is an input stream that also provides theRereadableContent
it has been created for.
-
Field Summary
Fields Modifier and Type Field Description protected Cleanup<IOException>
cleanup
The clean-up called as post-mortem action of thisRereadableContent
.protected Collection<Object>
existingStreams
All streams that have been created by thisRereadableContent
including itself are identified by an arbitraryObject
.protected Closeable
finalCleanup
The final clean-up to be executed after all streams and thisRereadableContent
have been closed/cleaned up.protected static String
RRC_INPUT_STREAM_SIZE
The name of theLong
attribute providing the size of the input stream in bytes.protected byte[]
sha512hash
The SHA-512 hash of the content.protected long
size
The size of the content.
-
Constructor Summary
Constructors Modifier Constructor Description protected
RereadableContent(long size, byte[] sha512hash, Closeable finalCleanup)
Creates a newRereadableContent
for the designated data.protected
RereadableContent(RereadableContent wrapped)
Creates a newRereadableContent
wrapping the designatedRereadableContent
and creating a new input stream to keep the wrappedRereadableContent
alive.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description void
close()
Closes the underlying stream or deletes the underlying file if there is no unclosedgetInputStream()
.protected abstract InputStream
createInputStream()
Creates a new input stream for the content.boolean
equals(Object obj)
AttributedInputStream
getInputStream()
Gets an input stream for the data.byte[]
getSHA512Hash()
Gets the SHA—512 hash of the content.long
getSize()
Gets the size of the content.static Long
getSize(InputStream is)
Gets the size of the designated input stream in case it is provided viaRRC_INPUT_STREAM_SIZE
,null
otherwise.int
hashCode()
-
-
-
Field Detail
-
RRC_INPUT_STREAM_SIZE
protected static final String RRC_INPUT_STREAM_SIZE
The name of theLong
attribute 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 thisRereadableContent
including itself are identified by an arbitraryObject
. They have a clean-up task used forInputStream.close()
as well as post-mortem action. The task removes theObject
and 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 thisRereadableContent
have 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 newRereadableContent
for 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 theRereadableContent
have been closed/cleaned up.
-
RereadableContent
protected RereadableContent(RereadableContent wrapped) throws IOException
Creates a newRereadableContent
wrapping the designatedRereadableContent
and creating a new input stream to keep the wrappedRereadableContent
alive.- Parameters:
wrapped
- The wrappedRereadableContent
.- Throws:
IOException
- If creating a new input stream from the designatedRereadableContent
fails, anIOException
will 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 thisRereadableContent
has already been closed, anIOException
will 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, anIOException
will be thrown.
-
close
public final void close() throws IOException
Closes the underlying stream or deletes the underlying file if there is no unclosedgetInputStream()
. If there are input streams of thisRereadableContent
that have not been closed yet, closing deferred until closing the last one of these input streams.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
- Throws:
IOException
- If closing or deleting fails, anIOException
will 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
,null
otherwise.- 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
null
if not available.
-
-