org.owasp.html.AutoCloseableHtmlStreamRenderer Maven / Gradle / Ivy
package org.owasp.html;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.annotation.WillCloseWhenClosed;
final class AutoCloseableHtmlStreamRenderer extends HtmlStreamRenderer
// This is available on JDK6 and makes this class extend AutoCloseable.
implements Closeable {
private final Object closeable;
private static final Class> CLASS_AUTO_CLOSEABLE;
static {
Class> classAutoCloseable = null;
for (Class> superInterface : Closeable.class.getInterfaces()) {
if ("java.lang.AutoCloseable".equals(superInterface.getName())) {
classAutoCloseable = superInterface;
break;
}
}
CLASS_AUTO_CLOSEABLE = classAutoCloseable;
}
private static final Method METHOD_CLOSE;
static {
Method methodClose = null;
if (CLASS_AUTO_CLOSEABLE != null) {
try {
methodClose = CLASS_AUTO_CLOSEABLE.getMethod("close");
} catch (NoSuchMethodException ex) {
throw (NoSuchMethodError) new NoSuchMethodError().initCause(ex);
}
}
METHOD_CLOSE = methodClose;
}
static boolean isAutoCloseable(Object o) {
return o instanceof Closeable
|| CLASS_AUTO_CLOSEABLE != null && CLASS_AUTO_CLOSEABLE.isInstance(o);
}
static AutoCloseableHtmlStreamRenderer createAutoCloseableHtmlStreamRenderer(
@WillCloseWhenClosed
Appendable output, Handler super IOException> errorHandler,
Handler super String> badHtmlHandler) {
return new AutoCloseableHtmlStreamRenderer(
output, errorHandler, badHtmlHandler);
}
private AutoCloseableHtmlStreamRenderer(
@WillCloseWhenClosed
Appendable output, Handler super IOException> errorHandler,
Handler super String> badHtmlHandler) {
super(output, errorHandler, badHtmlHandler);
this.closeable = output;
}
private static final Object[] ZERO_OBJECTS = new Object[0];
public void close() throws IOException {
if (isDocumentOpen()) { closeDocument(); }
closeIfAnyCloseable(closeable);
}
static void closeIfAnyCloseable(Object closeable) throws IOException {
if (closeable instanceof Closeable) {
((Closeable) closeable).close();
} else if (METHOD_CLOSE != null) {
try {
METHOD_CLOSE.invoke(closeable, ZERO_OBJECTS);
} catch (IllegalAccessException ex) {
AssertionError ae = new AssertionError("close not public");
ae.initCause(ex);
throw ae;
} catch (InvocationTargetException ex) {
Throwable tgt = ex.getTargetException();
if (tgt instanceof IOException) {
throw (IOException) tgt;
} else if (tgt instanceof RuntimeException) {
throw (RuntimeException) tgt;
} else {
throw new AssertionError(null, tgt);
}
}
}
}
}