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

io.github.laskowski.shell.output.DefaultPublisher Maven / Gradle / Ivy

Go to download

Library to launch .bat and .sh scripts of your choice with different configurations. Allows you to read tasks and services output from terminal

There is a newer version: 2.0.6.1
Show newest version
package io.github.laskowski.shell.output;

import io.github.laskowski.shell.output.messages.MessageExclusionStrategy;

import javax.annotation.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class DefaultPublisher extends SubmissionPublisher implements Publisher {
    public static final String LAST_MESSAGE = "PROCESS FINISHED";
    protected final MessageExclusionStrategy messageExclusionStrategy;
    protected volatile boolean shouldPublish = true;

    public DefaultPublisher(@Nullable MessageExclusionStrategy messageExclusionStrategy) {
        this.messageExclusionStrategy = messageExclusionStrategy;
    }

    public void startPublishing(Process process) {
        startPublishing(process, false);
    }

    public void startPublishing(Process process, boolean includeErrorStream) {
        Consumer publishMessageIfPresent = line -> publishMessage(line, messageExclusionStrategy);

        Thread processDetectionThread = new Thread(new ProcessDetectionRunnable(process));

        LineReader inputStreamLineReader = new LineReader(process.getInputStream());
        LineReader errorStreamLineReader = new LineReader(process.getErrorStream());

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));

        processDetectionThread.start();

        while (shouldPublish) {
            try {
                inputStreamLineReader.readLine().ifPresent(publishMessageIfPresent);

                if (includeErrorStream) {
                    errorStreamLineReader.readLine().ifPresent(publishMessageIfPresent);
                }

                process.waitFor(1, TimeUnit.MILLISECONDS);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (InterruptedException ignore) {}
        }

        try {
            stdInput.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        publishMessage(LAST_MESSAGE, messageExclusionStrategy);
    }

    protected void stopPublishing() {
        shouldPublish = false;
    }

    @Override
    public void publishMessage(String message, @Nullable MessageExclusionStrategy messageExclusionStrategy) {
        if (messageExclusionStrategy == null) {
            submit(message);
        } else {
            if (!messageExclusionStrategy.test(message)) {
                submit(message);
            }
        }
    }

    @Override
    public void registerSubscriber(Flow.Subscriber subscriber) {
        if (subscriber != null) {
            this.subscribe(subscriber);
        } else throw new IllegalArgumentException("You need to provide subscriber to Publisher!");
    }

    protected static class Sleeper {

        static void sleep(Duration duration) {
            try {
                Thread.sleep(duration.toMillis());
            } catch (InterruptedException ignore) {
            }
        }
    }

    protected class ProcessDetectionRunnable implements Runnable {
        private volatile Process process;

        ProcessDetectionRunnable(Process process) {
            this.process = process;
        }

        @Override
        public void run() {
            while(process.isAlive()) {
                Sleeper.sleep(Duration.ofMillis(500));
            }

            Sleeper.sleep(Duration.ofMillis(500));
            stopPublishing();
        }
    }

    protected static class LineReader {
        private BufferedReader stdInput;

        LineReader(InputStream inputStream) {
            stdInput = new BufferedReader(new InputStreamReader(inputStream));
        }

        public Optional readLine() throws IOException {
            boolean isOutReady = stdInput.ready();
            if (isOutReady) {
                return Optional.ofNullable(stdInput.readLine());
            } else {
                return Optional.empty();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy