All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mike10004.nativehelper.subprocess.StreamContext Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
package com.github.mike10004.nativehelper.subprocess;

import java.io.IOException;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * Interface that defines methods for manipulating process output.
 * @param  type of captured standard output content
 * @param  type of captured standard error content
 */
public interface StreamContext {

    /**
     * Produces the byte sources and byte sinks to be attached to the process
     * standard output, error, and input streams.
     * @return an output context
     * @throws IOException if something goes awry
     */
    C produceControl() throws IOException;

    /**
     * Gets the transform that produces a result from a process exit code.
     * Instances of this class create the process stream sources and sinks
     * (in {@link #produceControl()} and must be able to produce a
     * {@link StreamContent} instance after the process has finished.
     * @param exitCode the process exit code
     * @param context the output context produced by {@link #produceControl()}
     * @return the transform
     */
    StreamContent transform(int exitCode, C context);

    /**
     * Maps the types of this output control to other types using a pair of functions.
     * @param stdoutMap the standard output map function
     * @param stderrMap the standard error map function
     * @param  the destination type for standard output content
     * @param  the destination type for standard error content
     * @return an output control satisfying the requirements of the destination types
     */
    default  StreamContext map(Function stdoutMap, Function stderrMap) {
        StreamContext self = this;
        return new StreamContext() {
            @Override
            public C produceControl() throws IOException {
                return self.produceControl();
            }

            @Override
            public StreamContent transform(int exitCode, C context) {
                return self.transform(exitCode, context).map(stdoutMap, stderrMap);
            }
        };
    }

    /**
     * Interface that represents a stream context whose captured standard output and error
     * content has the same type.
     * @param  type of the captured standard output and standard error contents
     * @param  type of the stream control
     */
    interface UniformStreamContext extends StreamContext {

        /**
         * Wraps a process output control whose standard error and output type
         * in an object that satisfies this interface.
         * @param homogenous the uniform stream context
         * @param  stream control type
         * @param  type of captured standard output and standard error content
         * @return a new uniform stream context
         */
        static  UniformStreamContext wrap(StreamContext homogenous) {
            return new UniformStreamContext() {
                @Override
                public C produceControl() throws IOException {
                    return homogenous.produceControl();
                }

                @Override
                public StreamContent transform(int exitCode, C context) {
                    return homogenous.transform(exitCode, context);
                }
            };
        }

        /**
         * Maps this stream context to one whose output is a different type.
         * @param stmap the map function
         * @param  the different type
         * @return the mapped context
         * @see StreamContext#map(Function, Function)
         */
        default  UniformStreamContext map(Function stmap) {
            StreamContext duplex = this;
            return new UniformStreamContext() {

                @Override
                public C produceControl() throws IOException {
                    return duplex.produceControl();
                }

                @Override
                public StreamContent transform(int exitCode, C context) {
                    return duplex.transform(exitCode, context).map(stmap, stmap);
                }
            };
        }
    }

    /**
     * Creates a new stream context that ignores process output.
     * @param streamControl  the stream control to use
     * @param  stream control type
     * @param  type of captured standard output content
     * @param  type of captured standard error content
     * @return the new context
     */
    static  StreamContext predefinedAndOutputIgnored(C streamControl) {
        return predefined(streamControl, StreamContexts::noOutput);
    }

    /**
     * Creates a new stream context whose output content is supplied by the given suppliers.
     * @param streamControl the stream control
     * @param stdoutProvider the standard output content supplier
     * @param stderrProvider the standard error content supplier
     * @param  stream control type
     * @param  type of captured standard output content
     * @param  type of captured standard error content
     * @return the new context
     */
    static  StreamContext predefined(C streamControl, Supplier stdoutProvider, Supplier stderrProvider) {
        return predefined(streamControl, () -> StreamContent.direct(stdoutProvider.get(), stderrProvider.get()));
    }

    /**
     * Creates a new stream context whose output is supplied by the given supplier.
     * @param streamControl the stream control
     * @param outputter the standard output and error content supplier
     * @param  stream control type
     * @param  type of captured standard output content
     * @param  type of captured standard error content
     * @return the new context
     */
    static  StreamContext predefined(C streamControl, Supplier> outputter) {
        return new StreamContext() {
            @Override
            public C produceControl() {
                return streamControl;
            }

            @Override
            public StreamContent transform(int exitCode, C context) {
                return outputter.get();
            }
        };
    }

}