1 /*
2 * *************************************************************************************************************************************************************
3 *
4 * TheseFoolishThings: Miscellaneous utilities
5 * http://tidalwave.it/projects/thesefoolishthings
6 *
7 * Copyright (C) 2009 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
8 *
9 * *************************************************************************************************************************************************************
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18 *
19 * *************************************************************************************************************************************************************
20 *
21 * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
22 * git clone https://github.com/tidalwave-it/thesefoolishthings-src
23 *
24 * *************************************************************************************************************************************************************
25 */
26 package it.tidalwave.util;
27
28 import javax.annotation.CheckForNull;
29 import javax.annotation.Nonnull;
30 import javax.annotation.concurrent.ThreadSafe;
31 import java.util.List;
32 import java.util.Scanner;
33 import java.io.IOException;
34 import it.tidalwave.util.spi.DefaultProcessExecutor;
35
36 /***************************************************************************************************************************************************************
37 *
38 * A facility that provides means for launching an external process, scraping its stdout and stderr in real-time and
39 * sending commands by means of its stdin.
40 *
41 * @see DefaultProcessExecutor
42 *
43 * @author Fabrizio Giudici
44 * @since 1.39
45 *
46 **************************************************************************************************************************************************************/
47 @ThreadSafe
48 public interface ProcessExecutor
49 {
50 /***********************************************************************************************************************************************************
51 * This interface provides operations that can be performed on the stdout or stderr consoles attached to the
52 * external process.
53 **********************************************************************************************************************************************************/
54 public static interface ConsoleOutput
55 {
56 /***************************************************************************************************************
57 *
58 * A listener that is invoked whenever a line is read from the console.
59 *
60 **************************************************************************************************************/
61 public static interface Listener
62 {
63 public void onReceived (@Nonnull String string);
64 }
65
66 /***************************************************************************************************************
67 *
68 * Returns {@code true} if the latest received line matches the given regular expression.
69 *
70 * @param regexp the regular expression
71 * @return {@code true} in case of match
72 *
73 **************************************************************************************************************/
74 public boolean latestLineMatches (@Nonnull String regexp);
75
76 /***************************************************************************************************************
77 *
78 * Returns a list of lines that match the given regular expression.
79 *
80 * @param regexp the regular expression
81 * @return the list of matching lines
82 *
83 **************************************************************************************************************/
84 @Nonnull
85 public List<String> filteredBy (@Nonnull String regexp);
86
87 /***************************************************************************************************************
88 *
89 * Returns a {@link Scanner} over the latest line matching a given regular expression, with the specific
90 * delimiter regular expression.
91 *
92 * @param regexp the regular expression for the filter
93 * @param delimiterRegexp the regular expression for the {@code Scanner}
94 * @return the list of matching lines
95 *
96 **************************************************************************************************************/
97 @Nonnull
98 public Scanner filteredAndSplitBy (@Nonnull String regexp, @Nonnull String delimiterRegexp);
99
100 /***************************************************************************************************************
101 *
102 * Waits for a line matching the given regular expression to appear.
103 *
104 * @param regexp the regular expression
105 * @return itself for chaining methods
106 * @throws InterruptedException if the wait has been interrupted
107 * @throws IOException in case the process has terminated or another I/O error
108 *
109 **************************************************************************************************************/
110 @Nonnull
111 public ConsoleOutput waitFor (@Nonnull String regexp)
112 throws InterruptedException, IOException;
113
114 /***************************************************************************************************************
115 *
116 * Clears the buffer of lines. This means that no filtering or waiting operation can be performed on the
117 * output produced so far. It will be possible to perform further operations on the output produced from now
118 * on.
119 *
120 **************************************************************************************************************/
121 public void clear();
122
123 /***************************************************************************************************************
124 *
125 * Sets a listener.
126 *
127 * @see Listener
128 * @param listener the listener
129 *
130 **************************************************************************************************************/
131 public void setListener (@Nonnull Listener listener);
132
133 /***************************************************************************************************************
134 *
135 * Returns the set listener
136 *
137 * @see Listener
138 * @return the listener
139 *
140 **************************************************************************************************************/
141 @CheckForNull
142 public Listener getListener();
143 }
144
145 /***********************************************************************************************************************************************************
146 * Adds some arguments to pass to the external process.
147 *
148 * @param arguments the arguments
149 * @return itself for chaining methods
150 **********************************************************************************************************************************************************/
151 @Nonnull
152 public ProcessExecutor withArguments (@Nonnull String ... arguments);
153
154 /***********************************************************************************************************************************************************
155 * Adds a single argument to pass to the external process.
156 *
157 * @param argument the argument
158 * @return itself for chaining methods
159 **********************************************************************************************************************************************************/
160 @Nonnull
161 public ProcessExecutor withArgument (@Nonnull String argument);
162
163 /***********************************************************************************************************************************************************
164 * Starts the external process.
165 *
166 * @return itself for chaining methods
167 * @throws IOException in case of error
168 **********************************************************************************************************************************************************/
169 @Nonnull
170 public ProcessExecutor start()
171 throws IOException;
172
173 /***********************************************************************************************************************************************************
174 * Stops the external process.
175 **********************************************************************************************************************************************************/
176 public void stop();
177
178 /***********************************************************************************************************************************************************
179 * Waits for the termination of the external process.
180 *
181 * @return itself for chaining methods
182 * @throws InterruptedException if the wait has been interrupted
183 * @throws IOException in case of I/O error
184 *
185 ******************************************************************************************************************/
186 @SuppressWarnings("RedundantThrows")
187 @Nonnull
188 public ProcessExecutor waitForCompletion()
189 throws IOException, InterruptedException;
190
191 /***********************************************************************************************************************************************************
192 * Sends a string to the stdin of the running process. If a carriage return is needed, it must be explicitly placed
193 * in the string.
194 *
195 * @param string the string to send
196 * @return itself for chaining methods
197 * @throws IOException in case of I/O error
198 **********************************************************************************************************************************************************/
199 @Nonnull
200 public ProcessExecutor send (@Nonnull String string)
201 throws IOException;
202
203 /***********************************************************************************************************************************************************
204 * Returns the stdout console.
205 *
206 * @return the console
207 **********************************************************************************************************************************************************/
208 @Nonnull
209 public ConsoleOutput getStdout();
210
211 /***********************************************************************************************************************************************************
212 * Returns the stderr console.
213 *
214 * @return the console
215 **********************************************************************************************************************************************************/
216 @Nonnull
217 public ConsoleOutput getStderr();
218 }
219