Class ThresholdEncodedOutput<T,E extends Exception>
- Type Parameters:
T
- the downstream output typeE
- the exception type that can be thrown while writing to the output type
- All Implemented Interfaces:
Output<E>
,Output.CloseableEncodedOutput<E>
,Output.EncodedOutput<E>
,LimitEncodedOutput<T,
,E> AutoCloseable
- Direct Known Subclasses:
ThresholdEncodedOutput.OutputStreamThresholdEncodedOutput
T
once limit is
exceeded. If the limit is not exceeded then the buffered data will be replayed and
pushed when closed. Consequently this output strategy is a
better fit for integration of blocking APIs such as Servlet based frameworks where the
data is pushed instead of pulled. If pulling is more desired (non blocking code
generally prefers a pull approach) than BufferedEncodedOutput
is a better fit
but requires the entire output be buffered.
The output T
is lazily created once and only once by calling
createConsumer(int)
and the total size buffered will be passed if under limit.
If the limit is exceeded than the size passed will be -1
.
For this implementation to work close()
must be called and thus a
try-with-resource is recommended regardless if the downstream consumer needs to be
closed or not!
The total buffered amount of data is not guaranteed to be exactly at the limit even if the total output is greater than the limit.
The advantages to letting this implementation do the buffering instead of the downstream framework is saving memory in that the pre-encoded parts of the template are just pointers and are not copied multiple times. Since this output instance will be doing the buffering it is important to minimize downstream buffering by letting the framework know that it does not need to buffer.
Example for Servlet output:
class ServletThresholdEncodedOutput extends ThresholdEncodedOutput.OutputStreamThresholdEncodedOutput {
private final HttpServletResponse response;
public ServletThresholdEncodedOutput(Charset charset, HttpServletResponse response) {
super(charset, calculateLimit(response));
this.response = response;
}
private static int calculateLimit(HttpServletResponse response) {
int limit = response.getBufferSize();
if (limit <= 0) {
return 1024 * 32;
}
return limit;
}
@Override
protected OutputStream createConsumer(int size) throws IOException {
if (size > -1) {
response.setContentLength(size);
// It is already all in memory so we do not need a buffer.
response.setBufferSize(0);
}
return response.getOutputStream();
}
}
- Author:
- agentgt
- See Also:
- API Note
- This class is not thread safe.
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
An OutputStream backed buffer limited encoded output.Nested classes/interfaces inherited from interface io.jstach.jstachio.Output
Output.CloseableEncodedOutput<E extends Exception>, Output.EncodedOutput<E extends Exception>, Output.StringOutput
-
Field Summary
Modifier and TypeFieldDescriptionprotected final int
The maximum number of bytes to buffer. -
Constructor Summary
ModifierConstructorDescriptionprotected
ThresholdEncodedOutput
(Charset charset, int limit) Create with charset and limit. -
Method Summary
Modifier and TypeMethodDescriptionvoid
Analogous toAppendable.append(CharSequence)
.void
Analogous toAppendable.append(CharSequence)
which by default treats the String as a CharSequence.charset()
The charset that the encoded output should be.void
close()
If the limit is not exceeded then the buffered data will be replayed and pushed when closed.protected abstract void
Called to close the consumer.@Nullable T
consumer()
The created consumer.protected abstract T
createConsumer
(int size) Creates the consumer.int
limit()
Buffer limitint
size()
This is the current written length.void
write
(byte[] bytes) Analogous toOutputStream.write(byte[])
.protected abstract void
Writes to a consumer.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface io.jstach.jstachio.Output
append, append, append, append, append, toAppendable
Methods inherited from interface io.jstach.jstachio.Output.EncodedOutput
append, append, write
-
Field Details
-
limit
The maximum number of bytes to buffer.
-
-
Constructor Details
-
ThresholdEncodedOutput
Create with charset and limit.- Parameters:
charset
- the encoding to use.limit
- the amount of total bytes to limit buffering however the total buffered amount of data is not guaranteed to be exactly at the limit even if the total output is greater than the limit.
-
-
Method Details
-
write
Writes to a consumer.- Parameters:
consumer
- the consumer created fromcreateConsumer(int)
.bytes
- data to be written- Throws:
E
- if an error happens while using the consumer.
-
createConsumer
Creates the consumer. If size is not-1
than the entire output has been buffered and can be safely used to setContent-Length
before creating the actual consumer (often an OutputStream).- Parameters:
size
--1
indicates that the output is larger than the limit.- Returns:
- the created consumer
- Throws:
E
- an error while creating the consumer
-
close
Called to close the consumer. Implementations can decide whether or not to really close the consumer.- Parameters:
consumer
- to be closed or not- Throws:
E
- if an error happens while closing.
-
write
Description copied from interface:Output.EncodedOutput
Analogous toOutputStream.write(byte[])
. Implementations should not alter the byte array.- Specified by:
write
in interfaceOutput.EncodedOutput<T>
- Parameters:
bytes
- already encoded bytes- Throws:
E
- if an error happens
-
consumer
Description copied from interface:LimitEncodedOutput
The created consumer. Maybenull
but on successful close should not be. This is not to create the consumer but to fetch it after processing has finished since the consumer is created on demand.- Specified by:
consumer
in interfaceLimitEncodedOutput<T,
E extends Exception> - Returns:
- created consumer
-
charset
Description copied from interface:Output.EncodedOutput
The charset that the encoded output should be.- Specified by:
charset
in interfaceOutput.EncodedOutput<T>
- Returns:
- expected charset
-
close
If the limit is not exceeded then the buffered data will be replayed and pushed when closed. Regardlessclose(Object)
will be called on the output like object.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceOutput.CloseableEncodedOutput<T>
- Throws:
E
- if an error happens while creating or closing the downstream output
-
size
This is the current written length.- Specified by:
size
in interfaceLimitEncodedOutput<T,
E extends Exception> - Returns:
- current written length
-
limit
Description copied from interface:LimitEncodedOutput
Buffer limit- Specified by:
limit
in interfaceLimitEncodedOutput<T,
E extends Exception> - Returns:
- limit buffer to this amount of bytes
-
append
Description copied from interface:Output
Analogous toAppendable.append(CharSequence)
. -
append
Description copied from interface:Output
Analogous toAppendable.append(CharSequence)
which by default treats the String as a CharSequence.
-