001package com.streamconverter.command;
002
003import java.io.IOException;
004import java.io.InputStream;
005import java.io.OutputStream;
006import java.util.Objects;
007import org.apache.commons.io.input.TeeInputStream;
008
009/**
010 * Abstract class for commands that consume an input stream and produce an output stream.
011 *
012 * <p>This class provides a template method pattern for executing the command, ensuring that the
013 * input and output streams are not null. It also provides a method to consume the input stream,
014 * which must be implemented by subclasses.
015 */
016public abstract class ConsumerCommand extends AbstractStreamCommand {
017
018  /**
019   * Default constructor.
020   *
021   * <p>Initializes the command with default settings.
022   */
023  public ConsumerCommand() {
024    super();
025  }
026
027  /**
028   * Executes the command on the provided input stream and writes the result to the output stream.
029   *
030   * @param inputStream The input stream to read data from.
031   * @param outputStream The output stream to write data to.
032   * @throws IOException If an I/O error occurs during the execution of the command.
033   */
034  @Override
035  public void executeInternal(InputStream inputStream, OutputStream outputStream)
036      throws IOException {
037    Objects.requireNonNull(inputStream);
038    Objects.requireNonNull(outputStream);
039
040    try (InputStream teeInputStream = new TeeInputStream(inputStream, outputStream); ) {
041      this.consume(teeInputStream);
042    } catch (IOException e) {
043      throw new IOException("Error while consuming input stream", e);
044    }
045  }
046
047  /**
048   * Abstract method to be implemented by subclasses for consuming the input stream.
049   *
050   * @param inputStream The input stream to read data from.
051   * @throws IOException If an I/O error occurs during the execution of the command.
052   */
053  public abstract void consume(InputStream inputStream) throws IOException;
054}