in xstream/src/java/com/thoughtworks/xstream/io/xml/TraxSource.java [482:572]
public ObjectOutputStream createObjectOutputStream(final Templates stylesheet, final Writer writer,
final String rootNodeName)
throws IOException {
getXMLReader();
final CompletableFuture<CustomObjectOutputStream> future = new CompletableFuture<>();
final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();
final Supplier<CustomObjectOutputStream> supplier = () -> {
try {
@SuppressWarnings("resource")
final CustomObjectOutputStream customObjectOutputStream = (CustomObjectOutputStream)xstream
.createObjectOutputStream(saxWriter, rootNodeName);
future.complete(customObjectOutputStream);
return customObjectOutputStream;
} catch (final IOException e) {
throw new StreamException(e);
}
};
try {
xmlReader.setProperty(SaxWriter.OOS_SUPPLIER_PROPERTY, supplier);
xmlReader.setProperty(SaxWriter.SOURCE_OBJECT_QUEUE_PROPERTY, queue);
} catch (SAXNotRecognizedException | SAXNotSupportedException e) {
throw new IllegalArgumentException(e.getMessage());
}
final TransformerException transEx[] = new TransformerException[1];
final Thread t = new Thread(() -> {
Transformer transformer;
try {
transformer = stylesheet.newTransformer();
transformer.transform(this, new StreamResult(writer));
} catch (final TransformerException e) {
transEx[0] = e;
}
});
t.start();
t.setName("XStream OutputObjectStream Transformer");
try {
final CustomObjectOutputStream customObjectOutputStream = future.get();
final CustomObjectOutputStream.StreamCallback callback = customObjectOutputStream.popCallback();
customObjectOutputStream.pushCallback(new CustomObjectOutputStream.StreamCallback() {
@Override
public void writeToStream(final Object object) throws IOException {
if (Thread.currentThread() == t) {
callback.writeToStream(object == NULL ? null : object);
} else {
TraxSource.checkException(transEx[0]);
try {
queue.put(object == null ? NULL : object);
} catch (final InterruptedException e) {
throw new InterruptedIOException();
}
}
}
@Override
public void writeFieldsToStream(final Map<String, Object> fields) throws IOException {
callback.writeFieldsToStream(fields);
}
@Override
public void defaultWriteObject() throws IOException {
callback.defaultWriteObject();
}
@Override
public void flush() throws IOException {
callback.flush();
}
@Override
public void close() throws IOException {
if (Thread.currentThread() == t) {
callback.close();
} else {
TraxSource.checkException(transEx[0]);
writeToStream(SaxWriter.EOS);
try {
t.join();
} catch (final InterruptedException e) {
throw new InterruptedIOException();
}
}
}
});
checkException(transEx[0]);
return customObjectOutputStream;
} catch (InterruptedException | ExecutionException e) {
throw new StreamException("Failed to communicate with transformation thread", e);
}
}