1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.simpligility.maven.plugins.android;
17
18 import com.android.annotations.NonNull;
19 import com.android.ide.common.process.JavaProcessExecutor;
20 import com.android.ide.common.process.JavaProcessInfo;
21 import com.android.ide.common.process.ProcessException;
22 import com.android.ide.common.process.ProcessOutput;
23 import com.android.ide.common.process.ProcessOutputHandler;
24 import com.android.ide.common.process.ProcessResult;
25 import com.android.utils.ILogger;
26 import com.google.common.base.Joiner;
27 import com.google.common.collect.Lists;
28 import com.google.common.io.ByteStreams;
29 import com.google.common.io.Closeables;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.util.List;
34 import java.util.Map;
35
36
37
38 public class DefaultJavaProcessExecutor implements JavaProcessExecutor
39 {
40 private final ILogger mLogger;
41 public DefaultJavaProcessExecutor( ILogger logger )
42 {
43 mLogger = logger;
44 }
45 @NonNull
46 @Override
47 public ProcessResult execute(
48 @NonNull JavaProcessInfo processInfo,
49 @NonNull ProcessOutputHandler processOutputHandler )
50 {
51 List<String> command = Lists.newArrayList();
52 command.add( processInfo.getExecutable() );
53 command.addAll( processInfo.getArgs() );
54 String commandString = Joiner.on( ' ' ).join( command );
55 mLogger.info( "command: " + commandString );
56 try
57 {
58
59 ProcessBuilder processBuilder = new ProcessBuilder( command );
60 Map<String, Object> envVariableMap = processInfo.getEnvironment();
61 if ( !envVariableMap.isEmpty() )
62 {
63 Map<String, String> env = processBuilder.environment();
64 for ( Map.Entry<String, Object> entry : envVariableMap.entrySet() )
65 {
66 env.put( entry.getKey(), entry.getValue().toString() );
67 }
68 }
69
70 Process process = processBuilder.start();
71
72 ProcessOutput output = processOutputHandler.createOutput();
73 int exitCode = grabProcessOutput( process, output );
74 processOutputHandler.handleOutput( output );
75 return new ProcessResultImplCopy( commandString, exitCode );
76 }
77 catch ( IOException e )
78 {
79 return new ProcessResultImplCopy( commandString, e );
80 }
81 catch ( InterruptedException e )
82 {
83
84 Thread.currentThread().interrupt();
85 return new ProcessResultImplCopy( commandString, e );
86 }
87 catch ( ProcessException e )
88 {
89 return new ProcessResultImplCopy( commandString, e );
90 }
91 }
92
93
94
95
96
97
98
99
100
101
102
103 private static int grabProcessOutput(
104 @NonNull final Process process,
105 @NonNull final ProcessOutput output ) throws InterruptedException
106 {
107 Thread threadErr = new Thread( "stderr" )
108 {
109 @Override
110 public void run()
111 {
112 InputStream stderr = process.getErrorStream();
113 OutputStream stream = output.getErrorOutput();
114 try
115 {
116 ByteStreams.copy( stderr, stream );
117 stream.flush();
118 }
119 catch ( IOException e )
120 {
121
122 }
123 finally
124 {
125 try
126 {
127 Closeables.close( stderr, true );
128 }
129 catch ( IOException e )
130 {
131
132 }
133 try
134 {
135 Closeables.close( stream, true );
136 }
137 catch ( IOException e )
138 {
139
140 }
141 }
142 }
143 };
144 Thread threadOut = new Thread( "stdout" )
145 {
146 @Override
147 public void run()
148 {
149 InputStream stdout = process.getInputStream();
150 OutputStream stream = output.getStandardOutput();
151 try
152 {
153 ByteStreams.copy( stdout, stream );
154 stream.flush();
155 }
156 catch ( IOException e )
157 {
158
159 }
160 finally
161 {
162 try
163 {
164 Closeables.close( stdout, true );
165 }
166 catch ( IOException e )
167 {
168
169 }
170 try
171 {
172 Closeables.close( stream, true );
173 }
174 catch ( IOException e )
175 {
176
177 }
178 }
179 }
180 };
181 threadErr.start();
182 threadOut.start();
183
184
185
186 threadErr.join();
187 threadOut.join();
188
189 return process.waitFor();
190 }
191 }