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(); } } }