blob: c0e8a5af7b2dac21894f8d7f540f16ffc0071085 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License") + you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.openmeetings.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import org.openmeetings.app.documents.GenerateSWF;
public class ProcessHelper {
private static class Worker extends Thread {
private final Process process;
private Integer exitCode;
private Worker(Process process) {
this.process = process;
}
@Override
public void run() {
try {
exitCode = process.waitFor();
} catch (InterruptedException ignore) {
return;
}
}
}
private static class StreamWatcher extends Thread {
public StringBuilder output;
private final InputStream is;
private final BufferedReader br;
private StreamWatcher(Process process, boolean isError) throws UnsupportedEncodingException {
output = new StringBuilder();
is = isError ? process.getErrorStream() : process.getInputStream();
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
}
@Override
public void run() {
try {
String line = br.readLine();
while (line != null) {
output.append(line).append('\n');
line = br.readLine();
}
} catch (IOException ioexception) {
return;
}
}
}
public static HashMap<String, String> executeScript(String process, String[] argv) {
Map<String, String> env = new HashMap<String, String>();
return executeScript(process, argv, env);
}
public static HashMap<String, String> executeScript(String process,
String[] argv, Map<? extends String, ? extends String> env) {
HashMap<String, String> returnMap = new HashMap<String, String>();
returnMap.put("process", process);
GenerateSWF.log.debug("process: " + process);
GenerateSWF.log.debug("args: " + Arrays.toString(argv));
try {
returnMap.put("command", Arrays.toString(argv));
returnMap.put("out","");
// By using the process Builder we have access to modify the
// environment variables
// that is handy to set variables to run it inside eclipse
ProcessBuilder pb = new ProcessBuilder(argv);
pb.environment().putAll(env);
Process proc = pb.start();
// 20-minute timeout for command execution
// FFMPEG conversion of Recordings may take a real long time until
// its finished
long timeout = 60000 * 20;
StreamWatcher errorWatcher = new StreamWatcher(proc, true);
Worker worker = new Worker(proc);
StreamWatcher inputWatcher = new StreamWatcher(proc, false);
errorWatcher.start();
inputWatcher.start();
worker.start();
try {
worker.join(timeout);
if (worker.exitCode != null) {
returnMap.put("exitValue", "" + worker.exitCode);
GenerateSWF.log.debug("exitVal: " + worker.exitCode);
returnMap.put("error", errorWatcher.output.toString());
} else {
returnMap.put("exception", "timeOut");
returnMap.put("error", errorWatcher.output.toString());
returnMap.put("exitValue", "-1");
throw new TimeoutException();
}
} catch (InterruptedException ex) {
worker.interrupt();
errorWatcher.interrupt();
inputWatcher.interrupt();
Thread.currentThread().interrupt();
returnMap.put("error", ex.getMessage());
returnMap.put("exitValue", "-1");
throw ex;
} finally {
proc.destroy();
}
} catch (TimeoutException e) {
// Timeout exception is processed above
GenerateSWF.log.error("executeScript",e);
e.printStackTrace();
returnMap.put("error", e.getMessage());
returnMap.put("exception", e.toString());
returnMap.put("exitValue", "-1");
} catch (Throwable t) {
// Any other exception is shown in debug window
GenerateSWF.log.error("executeScript",t);
t.printStackTrace();
returnMap.put("error", t.getMessage());
returnMap.put("exception", t.toString());
returnMap.put("exitValue", "-1");
}
return returnMap;
}
}