com.github.mustachejava.util.LatchedWriter Maven / Gradle / Ivy
package com.github.mustachejava.util;
import com.github.mustachejava.MustacheException;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.CountDownLatch;
/**
* Buffer content while a future is being evaluated in another thread.
*/
public class LatchedWriter extends Writer {
// Write to the buffer while latched, when unlatched, write the
// buffer to the underlying writer and any future writes
private final CountDownLatch latch = new CountDownLatch(1);
// A buffer that holds writes until the latch is unlatched
private final StringBuilder buffer = new StringBuilder();
// The underlying writer
private final Writer writer;
// This is set when the latch holder fails
private volatile Throwable e;
public LatchedWriter(Writer writer) {
this.writer = writer;
}
// Call this when your processing is complete
public synchronized void done() throws IOException {
writer.append(buffer);
latch.countDown();
}
// If you fail to complete, put an exception here
public void failed(Throwable e) {
this.e = e;
latch.countDown();
}
@Override
public synchronized void write(char[] cbuf, int off, int len) throws IOException {
checkException();
if (latch.getCount() == 0) {
writer.write(cbuf, off, len);
} else {
buffer.append(cbuf, off, len);
}
}
private void checkException() throws IOException {
if (e != null) {
if (e instanceof IOException) {
throw ((IOException) e);
}
throw new IOException(e);
}
}
@Override
public void flush() throws IOException {
checkException();
if (latch.getCount() == 0) {
synchronized (this) {
writer.flush();
}
}
}
@Override
public void close() throws IOException {
checkException();
await();
flush();
writer.close();
}
public void await() {
try {
latch.await();
} catch (InterruptedException e1) {
throw new MustacheException("Interrupted while waiting for completion", e1);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy