11package com .enot .cmd .core ;
22
3- import org .apache .commons .io .FileUtils ;
3+ import com .enot .cmd .core .LambdaListenerAdapter .AfterFinish ;
4+ import com .enot .cmd .core .LambdaListenerAdapter .AfterStart ;
5+ import com .enot .cmd .core .LambdaListenerAdapter .AfterStop ;
6+ import com .enot .cmd .core .LambdaListenerAdapter .BeforeStart ;
47import org .cactoos .iterable .IterableOf ;
58import org .cactoos .iterable .Joined ;
69import org .cactoos .iterable .Mapped ;
710import org .zeroturnaround .exec .ProcessExecutor ;
811
9- import java .io .File ;
10- import java .io .IOException ;
11- import java .io .OutputStream ;
12- import java .io .UncheckedIOException ;
13- import java .nio .file .Files ;
14- import java .nio .file .Path ;
15- import java .nio .file .Paths ;
16- import java .nio .file .StandardOpenOption ;
12+ import java .util .Arrays ;
13+ import java .util .Collections ;
14+ import java .util .List ;
15+ import java .util .Map ;
16+ import java .util .stream .Collectors ;
1717
1818/**
1919 * Command line representation with the additional features around a process execution
2020 */
2121public final class Cmd implements ICmd {
22- private final boolean cleanUp ;
23- private final String outputFileName ;
2422 private final Listening listening ;
25- private final LambdaListenerAdapter . BeforeStart configuring ;
23+ private final BeforeStart [] beforeStart ;
2624 private final String interpreter ;
2725
2826 public Cmd () {
29- this (false ,
30- "" ,
31- new Listening (null , new IterableOf <>()),
32- e -> {
33- },
34- "" );
27+ this (new Listening (null , new IterableOf <>()), new BeforeStart [0 ], "" );
3528 }
3629
37- public Cmd (boolean cleanUp , String outputFileName , Listening listening , LambdaListenerAdapter .BeforeStart configuring , String interpreter ) {
38- this .cleanUp = cleanUp ;
39- this .outputFileName = outputFileName ;
30+ public Cmd (Listening listening , BeforeStart [] beforeStart , String interpreter ) {
4031 this .listening = listening ;
41- this .configuring = configuring ;
32+ this .beforeStart = beforeStart ;
4233 this .interpreter = interpreter ;
4334 }
4435
45- /**
46- * Delete work directory after process stopped, only if the directory will be created during the execution
47- *
48- * @param cleanUp
49- * @return
50- */
5136 @ Override
52- public Cmd cleanUp (boolean cleanUp ) {
53- return new Cmd (cleanUp , outputFileName , listening , configuring , interpreter );
54- }
55-
56- @ Override
57- public Cmd outputFileName (String outputFileName ) {
58- return new Cmd (cleanUp , outputFileName , listening , configuring , interpreter );
59- }
60-
61- @ Override
62- public Cmd configuring (LambdaListenerAdapter .BeforeStart configuring ) {
63- return new Cmd (cleanUp , outputFileName , listening , configuring , interpreter );
37+ public Cmd configuring (BeforeStart ... configuring ) {
38+ return new Cmd (listening , configuring , interpreter );
6439 }
6540
6641 @ Override
@@ -70,7 +45,7 @@ public CmdListening listening() {
7045
7146 @ Override
7247 public Cmd interpreter (String interpreter ) {
73- return new Cmd (cleanUp , outputFileName , listening , configuring , interpreter );
48+ return new Cmd (listening , beforeStart , interpreter );
7449 }
7550
7651 public Command command (String ... command ) {
@@ -79,77 +54,51 @@ public Command command(String... command) {
7954
8055 private ProcessExecutor processExecutor (String ... command ) {
8156 ProcessExecutor executor = new ProcessExecutor ();
82- configuring .run (executor );
83- for (LambdaListenerAdapter listener : listening .listeners ) {
84- executor .addListener (listener );
85- }
57+
58+ Map <Boolean , List <BeforeStart >> configuring = Arrays .stream (beforeStart ).collect (
59+ Collectors .groupingBy (c -> c instanceof AfterStop ));
60+ List <BeforeStart > configuringBefore = configuring .getOrDefault (false , Collections .emptyList ());
61+ List <BeforeStart > configuringAfter = configuring .getOrDefault (true , Collections .emptyList ());
62+
63+ configuringBefore .forEach (c -> c .run (executor ));
64+ listening .listeners .forEach (executor ::addListener );
65+ configuringAfter .forEach (c -> c .run (executor ));
8666
8767 Iterable <String > commands = new IterableOf <>(command );
8868 if (interpreter != null && !interpreter .trim ().isEmpty ()) {
8969 commands = new Joined <>(new IterableOf <>(interpreter ), commands );
9070 }
91-
92- LambdaListenerAdapter beforeStart = new LambdaListenerAdapter ((LambdaListenerAdapter .BeforeStart ) processExecutor -> {
93- File dir = processExecutor .getDirectory ();
94- if (dir != null && !dir .exists ()) {
95- final boolean workDirCreated = dir .mkdirs ();
96- if (!workDirCreated )
97- throw new UncheckedIOException (
98- new IOException (String .format ("Work directory %s can not be created" , dir .toPath ())));
99- if (cleanUp ) {
100- processExecutor .addListener (new LambdaListenerAdapter ((LambdaListenerAdapter .AfterStop ) p -> {
101- try {
102- FileUtils .deleteDirectory (dir );
103- } catch (IOException e ) {
104- throw new UncheckedIOException (
105- String .format ("Work directory %s can not be deleted" , dir .toPath ()),
106- e );
107- }
108- }));
109- }
110- }
111- if (outputFileName != null && outputFileName .length () > 0 ) {
112- OutputStream outputStream = createFileOS (dir );
113- processExecutor .redirectOutputAlsoTo (outputStream );
114- processExecutor .addListener (new LambdaListenerAdapter ((LambdaListenerAdapter .AfterStop ) process -> {
115- try {
116- outputStream .close ();
117- } catch (IOException e ) {
118- throw new UncheckedIOException (e );
119- }
120- }));
121- }
122- });
123- return executor .command (commands ).addListener (beforeStart );
71+ return executor .command (commands );
12472 }
12573
126- private OutputStream createFileOS (File workDir ) {
127- Path outputFile ;
128- if (workDir != null ) {
129- outputFile = Paths .get (workDir .getPath (), outputFileName );
130- } else {
131- outputFile = Paths .get (outputFileName );
132- }
133- try {
134- return Files .newOutputStream (outputFile , StandardOpenOption .CREATE );
135- } catch (IOException e ) {
136- throw new UncheckedIOException (
137- String .format ("Output file %s can not be created" , outputFile ),
138- e );
139- }
140- }
14174
14275 private static final class Listening implements CmdListening {
14376 private final Cmd owner ;
14477 private final Iterable <LambdaListenerAdapter > listeners ;
14578
79+ public Listening (Cmd owner , BeforeStart ... lambdas ) {
80+ this (owner , new Mapped <>(LambdaListenerAdapter ::new , new IterableOf <>(lambdas )));
81+ }
82+
83+ public Listening (Cmd owner , AfterStart ... lambdas ) {
84+ this (owner , new Mapped <>(LambdaListenerAdapter ::new , new IterableOf <>(lambdas )));
85+ }
86+
87+ public Listening (Cmd owner , AfterFinish ... lambdas ) {
88+ this (owner , new Mapped <>(LambdaListenerAdapter ::new , new IterableOf <>(lambdas )));
89+ }
90+
91+ public Listening (Cmd owner , AfterStop ... lambdas ) {
92+ this (owner , new Mapped <>(LambdaListenerAdapter ::new , new IterableOf <>(lambdas )));
93+ }
94+
14695 public Listening (Cmd owner , Iterable <LambdaListenerAdapter > listeners ) {
14796 this .owner = owner ;
14897 this .listeners = listeners ;
14998 }
15099
151100 @ Override
152- public CmdListening beforeStart (LambdaListenerAdapter . BeforeStart ... lambdas ) {
101+ public CmdListening beforeStart (BeforeStart ... lambdas ) {
153102 return new Listening (
154103 owner ,
155104 new Joined <>(
@@ -159,7 +108,7 @@ public CmdListening beforeStart(LambdaListenerAdapter.BeforeStart... lambdas) {
159108 }
160109
161110 @ Override
162- public CmdListening afterStart (LambdaListenerAdapter . AfterStart ... lambdas ) {
111+ public CmdListening afterStart (AfterStart ... lambdas ) {
163112 return new Listening (
164113 owner ,
165114 new Joined <>(
@@ -169,7 +118,7 @@ public CmdListening afterStart(LambdaListenerAdapter.AfterStart... lambdas) {
169118 }
170119
171120 @ Override
172- public CmdListening afterFinish (LambdaListenerAdapter . AfterFinish ... lambdas ) {
121+ public CmdListening afterFinish (AfterFinish ... lambdas ) {
173122 return new Listening (
174123 owner ,
175124 new Joined <>(
@@ -179,7 +128,7 @@ public CmdListening afterFinish(LambdaListenerAdapter.AfterFinish... lambdas) {
179128 }
180129
181130 @ Override
182- public CmdListening afterStop (LambdaListenerAdapter . AfterStop ... lambdas ) {
131+ public CmdListening afterStop (AfterStop ... lambdas ) {
183132 return new Listening (
184133 owner ,
185134 new Joined <>(
@@ -190,7 +139,7 @@ public CmdListening afterStop(LambdaListenerAdapter.AfterStop... lambdas) {
190139
191140 @ Override
192141 public Cmd back () {
193- return new Cmd (owner . cleanUp , owner . outputFileName , this , owner .configuring , owner .interpreter );
142+ return new Cmd (this , owner .beforeStart , owner .interpreter );
194143 }
195144 }
196145}
0 commit comments