LoggingInputStreamFactory.java

package emissary.core.channels;

import emissary.util.io.LoggingInputStream;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicLong;

/**
 * This class creates a InputStreamFactory for logging accesses to every method on the InputStream. It is intended only
 * for development/debugging purposes.
 */
public final class LoggingInputStreamFactory {
    private LoggingInputStreamFactory() {}

    /**
     * Creates an InputStreamFactory for logging accesses to every method on the InputStream.
     * 
     * @param inputStreamFactory that creates the InputStream to wrap.
     * @param identifier that is added to the log message.
     * @param logger to use for logging.
     * @param logStackTrace specifies whether a stack trace should be added to the log message.
     * @return the logging InputStreamFactory
     */
    public static InputStreamFactory create(final InputStreamFactory inputStreamFactory, final String identifier,
            final Logger logger, final boolean logStackTrace) {
        return new LoggingInputStreamFactoryImpl(inputStreamFactory, identifier, logger, logStackTrace);
    }

    /**
     * The InputStreamFactory for creating logging InputStreams.
     */
    private static class LoggingInputStreamFactoryImpl implements InputStreamFactory {
        /**
         * The InputStream that is being wrapped.
         */
        private final InputStreamFactory inputStreamFactory;
        /**
         * An identifier add to the log message.
         */
        private final String identifier;
        /**
         * The logger to be used for logging.
         */
        private final Logger logger;
        /**
         * Determines whether a stack trace should also be logged.
         */
        private final boolean logStackTrace;
        /**
         * A one-up counter for identifying each instance.
         */
        private final AtomicLong currentInstance = new AtomicLong(0);

        private LoggingInputStreamFactoryImpl(final InputStreamFactory inputStreamFactory, final String identifier,
                final Logger logger, final boolean logStackTrace) {
            Validate.notNull(inputStreamFactory, "Required: inputStreamFactory not null!");
            Validate.notNull(identifier, "Required: identifier not null!");
            Validate.notNull(logger, "Required: logger not null!");

            this.inputStreamFactory = inputStreamFactory;
            this.identifier = identifier;
            this.logger = logger;
            this.logStackTrace = logStackTrace;
        }

        @Override
        public InputStream create() throws IOException {
            return new LoggingInputStream(inputStreamFactory.create(),
                    identifier + " : " + currentInstance.getAndIncrement(), logger, logStackTrace);
        }
    }
}