package org.icij.extract.spewer;
import java.io.Reader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Serializable;
import org.apache.commons.io.TaggedIOException;
import org.apache.tika.metadata.Metadata;
import org.icij.extract.document.Document;
import org.icij.extract.document.EmbeddedDocument;
import org.icij.extract.parser.ParsingReader;
/**
* Writes the text output from a {@link ParsingReader}, and metadata, to the given {@link PrintStream}.
*
* @since 1.0.0-beta
*/
public class PrintStreamSpewer extends Spewer implements Serializable {
private static final long serialVersionUID = -1952187923616552629L;
private final PrintStream stream;
public PrintStreamSpewer(final PrintStream stream, final FieldNames fields) {
super(fields);
this.stream = stream;
}
@Override
public void write(final Document document, final Reader reader) throws IOException {
if (outputMetadata) {
writeMetadata(document);
}
// A PrintStream should never throw an IOException: the exception would always come from the input stream.
// There's no need to use a TaggedOutputStream or catch IOExceptions.
copy(reader, stream);
// Add an extra newline to signify the end of the text.
stream.println();
if (stream.checkError()) {
throw new TaggedIOException(new IOException("Error writing to print stream."), this);
}
// Write out child documents, if any.
for (EmbeddedDocument embed: document.getEmbeds()) {
try (final Reader embedReader = embed.getReader()) {
write(embed, embedReader);
}
}
}
@Override
public void writeMetadata(final Document document) throws IOException {
final Metadata metadata = document.getMetadata();
// Set the path field.
if (null != fields.forPath()) {
stream.println(fields.forPath() + ": " + document.getPath().toString());
}
// Set the parent path field.
if (null != fields.forParentPath() && document.getPath().getNameCount() > 1) {
stream.println(fields.forParentPath() + ": " + document.getPath().getParent().toString());
}
new MetadataTransformer(metadata, fields).transform((name, value)-> stream.println(name + ": " + value),
(name, values)-> stream.println(name + ": " + String.join(", ", values)));
// Add an extra newline to signify the end of the metadata.
stream.println();
}
@Override
public void close() throws IOException {
if (!stream.equals(System.out) && !stream.equals(System.err)) {
stream.close();
}
}
}