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

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

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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Suppliers;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nullable;
import java.lang.reflect.Array;
import java.util.function.Function;
import java.util.function.Supplier;

class StreamContents {

    private static int lengthOf(@Nullable String s) {
        return s == null ? 0 : s.length();
    }

    private static String innerFieldsToString(Object stdout, Object stderr) {
        boolean soArray = stdout != null && stdout.getClass().isArray();
        boolean seArray = stderr != null && stderr.getClass().isArray();
        String so = abbrev(stdout);
        String se = abbrev(stderr);
        StringBuilder s = new StringBuilder(lengthOf(so) + lengthOf(se) + 20);
        s.append("stdout=");
        if (so != null) {
            s.append(soArray ? "" : '"').append(so).append(soArray ? "" : '"');
        }
        s.append(", stderr=");
        if (se != null) {
            s.append(seArray ? "" : '"').append(se).append(seArray ? "" : '"');
        }
        return s.toString();
    }

    public static class DirectOutput implements StreamContent {

        private final SO stdout;
        private final SE stderr;

        public DirectOutput(SO stdout, SE stderr) {
            this.stdout = stdout;
            this.stderr = stderr;
        }

        @Override
        public SO stdout() {
            return stdout;
        }

        @Override
        public SE stderr() {
            return stderr;
        }

        @Override
        public String toString() {
            return "DirectOutput{" + innerFieldsToString(stdout, stderr) + '}';
        }
    }

    @VisibleForTesting
    static String betterToString(@Nullable Object object) {
        if (object == null) {
            return null;
        }
        if (object.getClass().isArray()) {
            String componentTypeName = object.getClass().getComponentType().getName();
            StringBuilder s = new StringBuilder(32);
            while (object != null && object.getClass().isArray()) {
                componentTypeName = object.getClass().getComponentType().getName();
                int length = Array.getLength(object);
                s.append('[').append(length).append(']');
                if (length > 0) {
                    object = Array.get(object, 0);
                } else {
                    break;
                }
            }
            if (componentTypeName.matches("^java\\.lang\\.[A-Z].*$")) {
                componentTypeName = StringUtils.removeStart(componentTypeName, "java.lang.");
            }
            return componentTypeName + s.toString();
        }
        return object.toString();
    }

    private static String abbrev(Object object) {
        if (object == null) {
            return null;
        }
        String abbreved = StringUtils.abbreviateMiddle(betterToString(object), "...", ABBREV);
        return StringEscapeUtils.escapeJava(abbreved);
    }

    public static class DeferredOutput implements StreamContent {

        private final Supplier stdoutSupplier;
        private final Supplier stderrSupplier;

        public DeferredOutput(Supplier stdoutSupplier, Supplier stderrSupplier) {
            this.stdoutSupplier = Suppliers.memoize(stdoutSupplier::get);
            this.stderrSupplier = Suppliers.memoize(stderrSupplier::get);
        }

        @Override
        public SO stdout() {
            return stdoutSupplier.get();
        }

        @Override
        public SE stderr() {
            return stderrSupplier.get();
        }

        @Override
        public String toString() {
            return "DeferredOutput{" +
                    "stdoutSupplier=" + stdoutSupplier +
                    ", stderrSupplier=" + stderrSupplier +
                    '}';
        }

        public String toStringExpanded() {
            return "DeferredOutput:Expanded{" + innerFieldsToString(stdout(), stderr()) + '}';
        }

    }

    private static final int ABBREV = 64;

    public static class MappedOutput extends DeferredOutput {

        public  MappedOutput(StreamContent original, Function stdoutMap, Function stderrMap) {
            super(() -> stdoutMap.apply(original.stdout()), () -> stderrMap.apply(original.stderr()));
        }

        @Override
        public String toString() {
            return toStringExpanded();
        }
    }

    @SuppressWarnings("unchecked")
    public static  StreamContent bothNull() {
        return BOTH_NULL;
    }

    private static final StreamContent BOTH_NULL = new StreamContent() {
        @Override
        public Void stdout() {
            return null;
        }

        @Override
        public Void stderr() {
            return null;
        }

        @Override
        public String toString() {
            return "NoOutput{}";
        }
    };
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy