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

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

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

import com.github.mike10004.nativehelper.subprocess.StreamContext.UniformStreamContext;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.io.ByteSource;
import com.google.common.io.CharSource;

import javax.annotation.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Path;

import static java.util.Objects.requireNonNull;

class StreamContexts {

    private static final StreamContent NO_OUTPUT = StreamContent.direct(null, null);

    @SuppressWarnings("unchecked")
    static  StreamContent noOutput() {
        return NO_OUTPUT;
    }

    public static StreamContext sinkhole() {
        return StreamContext.predefined(PredefinedStreamControl.nullWithNullInput(), StreamContexts::noOutput);
    }

    public static UniformStreamContext memoryByteSources(@Nullable ByteSource stdin) {
        return byteArrays(stdin).map(ByteSource::wrap);
    }

    @SuppressWarnings("unused")
    public static UniformStreamContext memoryCharSources(Charset charset, @Nullable ByteSource stdin) {
        requireNonNull(charset);
        return memoryByteSources(stdin).map(byteSource -> byteSource.asCharSource(charset));
    }

    public static UniformStreamContext outputTempFiles(Path directory, @Nullable ByteSource stdin) {
        return new FileStreamContext() {
            @Override
            public FileStreamControl produceControl() throws IOException {
                File stdoutFile = File.createTempFile("FileStreamContext_stdout", ".tmp", directory.toFile());
                File stderrFile = File.createTempFile("FileStreamContext_stderr", ".tmp", directory.toFile());
                return new FileStreamControl(stdoutFile, stderrFile, stdin);
            }
        };
    }

    public static UniformStreamContext outputFiles(File stdoutFile, File stderrFile, @Nullable ByteSource stdin) {
        return new FileStreamContext() {
            @Override
            public FileStreamControl produceControl() {
                return new FileStreamControl(stdoutFile, stderrFile, stdin);
            }
        };
    }

    @VisibleForTesting
    static class BucketContext extends PredefinedStreamControl {

        public final ByteBucket stdout;
        public final ByteBucket stderr;

        public BucketContext(@Nullable ByteSource stdin) {
            this(ByteBucket.withInitialCapacity(256), ByteBucket.withInitialCapacity(256), stdin);
        }

        public BucketContext(ByteBucket stdout, ByteBucket stderr, @Nullable ByteSource stdin) {
            super(stdout, stderr, stdin);
            this.stdout = requireNonNull(stdout);
            this.stderr = requireNonNull(stderr);
        }


    }

    public static UniformStreamContext byteArrays(@Nullable ByteSource stdin) {
        return new UniformStreamContext() {
            @Override
            public BucketContext produceControl() {
                return new BucketContext(stdin);
            }

            @Override
            public StreamContent transform(int exitCode, BucketContext ctx) {
                return StreamContent.direct(ctx.stdout.dump(), ctx.stderr.dump());
            }
        };
    }

    public static UniformStreamContext strings(Charset charset, @Nullable ByteSource stdin) {
        requireNonNull(charset);
        return byteArrays(stdin).map(bytes -> new String(bytes, charset));
    }

    public static StreamContext inheritOutputs() {
        return StreamContext.predefined(PredefinedStreamControl.builder().inheritStderr().inheritStdout().build(), StreamContexts::noOutput);    }

    public static StreamContext inheritAll() {
        return StreamContext.predefined(PredefinedStreamControl.builder().inheritStdin().inheritStderr().inheritStdout().build(), StreamContexts::noOutput);
    }

    public static class FileStreamControl implements StreamControl {
        private final File stdoutFile, stderrFile;
        @Nullable
        private final ByteSource stdin;

        public FileStreamControl(File stdoutFile, File stderrFile, @Nullable ByteSource stdin) {
            this.stdoutFile = requireNonNull(stdoutFile);
            this.stderrFile = requireNonNull(stderrFile);
            this.stdin = stdin;
        }

        @Override
        public OutputStream openStdoutSink() throws IOException {
            return new FileOutputStream(stdoutFile);
        }

        @Override
        public OutputStream openStderrSink() throws IOException {
            return new FileOutputStream(stderrFile);
        }

        @Nullable
        @Override
        public InputStream openStdinSource() throws IOException {
            return stdin == null ? null : stdin.openStream();
        }
    }

    public static abstract class FileStreamContext implements UniformStreamContext {

        @Override
        public StreamContent transform(int exitCode, FileStreamControl context) {
            return StreamContent.direct(context.stdoutFile, context.stderrFile);
        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy