package aliview.externalcommands;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import aliview.AliView;
import aliview.aligner.Aligner;
import aliview.aligner.MuscleWrapper;
import aliview.subprocesses.SubProcessWindow;
public class ExternalCommandExecutor {
private static final Logger logger = Logger.getLogger(ExternalCommandExecutor.class);
private static final String LF = System.getProperty("line.separator");
public static boolean executeMultiple(CommandItem cmdItem, SubProcessWindow subProcessWin) throws IOException {
// TODO Auto-generated method stub
boolean wasProcessInterrupted = false;
for(String[] commandLine: cmdItem.getParsedCommands()){
if(StringUtils.startsWith(commandLine[0], "ALIVIEW_")){
executeInternalCommand(commandLine, subProcessWin);
}
else{
wasProcessInterrupted = executeCommand(commandLine, subProcessWin);
if(subProcessWin.wasSubProcessDestrouedByUser()){
wasProcessInterrupted = true;
break;
}
}
}
return wasProcessInterrupted;
}
private static void executeInternalCommand(final String[] commandLine, final SubProcessWindow subProcessWin) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run(){
if(commandLine[0].equals("ALIVIEW_OPEN")){
AliView.openAlignmentFile(new File(commandLine[1]));
}
else{
subProcessWin.appendOutput("Failed: - Non recognized command: " + commandLine[0]);
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static boolean executeCommand(String[] commandArray, final SubProcessWindow subProcessWin) throws IOException{
boolean wasProcessInterrupted = false;
// check for piped output in command
File pipedOut = null;
for(int i = 0; i < commandArray.length; i++){
if(commandArray[i].equals(">")){
logger.info("found pipe");
if(commandArray.length >= i+1){
pipedOut = new File(commandArray[i+1]);
commandArray = (String[]) ArrayUtils.subarray(commandArray, 0, i);
break;
}
}
}
String cmdAsString ="";
for(String part: commandArray){
cmdAsString += " " + part;
}
logger.info(cmdAsString);
ProcessBuilder probuilder = new ProcessBuilder( commandArray );
probuilder.redirectErrorStream(true);
Process subprocess = probuilder.start();
// so that process gets killed when window destroys
subProcessWin.setActiveProcess(subprocess);
subProcessWin.appendOutput("command:" + LF + cmdAsString + LF);
final Scanner sc = new Scanner(subprocess.getInputStream());
// final Scanner errorSc = new Scanner(subprocess.getErrorStream());
//
// final File finalPipedOut = pipedOut;
//
// // read output in separate thread so nothing gets blocked
// Thread pipedOutThread = new Thread(new Runnable(){
// public void run(){
//
// // if pipped out then read output into file
// if(finalPipedOut != null){
// try {
// logger.info("piped out");
// BufferedWriter buffOut = new BufferedWriter(new FileWriter(finalPipedOut));
// while (sc.hasNext()){
// logger.info("beforeNextLine");
// String nextLine = sc.nextLine();
// logger.info("afterNextLine");
// buffOut.append(nextLine + LF);
// //logger.info((nextLine));
// }
// sc.close();
// buffOut.close();
// logger.info(("done with piped out"));
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// // else just dump output to screen
// else{
// try {
// logger.info(("going into scanner loop"));
// while (sc.hasNext()){
// logger.info("wait for");
// String nextLine = sc.nextLine();
// subProcessWin.appendOutput(nextLine + LF);
// logger.info((nextLine));
// }
// sc.close();
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// logger.info("outthreaddone");
// }
// });
// pipedOutThread.start();
//
while (sc.hasNext()){
//logger.info(errorSc.nextLine());
String nextLine = sc.nextLine();
subProcessWin.appendOutput(nextLine + LF);
System.out.println(nextLine);
}
sc.close();
logger.info("errorReaderThread-finished");
logger.info("before wait for subprocess");
// kill output thread if this was interrupted
// Dont close streams - it might block on windows
// if(subProcessWin.wasSubProcessDestrouedByUser()){
// subprocess.getInputStream().close();
// subprocess.getOutputStream().close();
// }
// close streams
// clean up external process
/*
try {
subprocess.waitFor();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
*/
subprocess.destroy();
logger.info("done");
return wasProcessInterrupted;
}
/*
private static boolean executeCommand(String[] commandArray, final SubProcessWindow subProcessWin) throws IOException{
boolean wasProcessInterrupted = false;
// check for piped output in command
File pipedOut = null;
for(int i = 0; i < commandArray.length; i++){
if(commandArray[i].equals(">")){
logger.info("found pipe");
if(commandArray.length >= i+1){
pipedOut = new File(commandArray[i+1]);
commandArray = (String[]) ArrayUtils.subarray(commandArray, 0, i);
break;
}
}
}
String cmdAsString ="";
for(String part: commandArray){
cmdAsString += " " + part;
}
logger.info(cmdAsString);
ProcessBuilder probuilder = new ProcessBuilder( commandArray );
Process subprocess = probuilder.start();
// so that process gets killed when window destroys
subProcessWin.setActiveProcess(subprocess);
final Scanner sc = new Scanner(subprocess.getInputStream());
final Scanner errorSc = new Scanner(subprocess.getErrorStream());
final File finalPipedOut = pipedOut;
// read output in separate thread so nothing gets blocked
Thread pipedOutThread = new Thread(new Runnable(){
public void run(){
// if pipped out then read output into file
if(finalPipedOut != null){
try {
logger.info("piped out");
BufferedWriter buffOut = new BufferedWriter(new FileWriter(finalPipedOut));
while (sc.hasNext()){
logger.info("beforeNextLine");
String nextLine = sc.nextLine();
logger.info("afterNextLine");
buffOut.append(nextLine + LF);
//logger.info((nextLine));
}
sc.close();
buffOut.close();
logger.info(("done with piped out"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// else just dump output to screen
else{
try {
logger.info(("going into scanner loop"));
while (sc.hasNext()){
logger.info("wait for");
String nextLine = sc.nextLine();
subProcessWin.appendOutput(nextLine + LF);
logger.info((nextLine));
}
sc.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
logger.info("outthreaddone");
}
});
pipedOutThread.start();
while (errorSc.hasNext()){
//logger.info(errorSc.nextLine());
String nextLine = errorSc.nextLine();
subProcessWin.appendOutput(nextLine + LF);
System.out.println(nextLine);
}
errorSc.close();
logger.info("errorReaderThread-finished");
logger.info("before wait for subprocess");
// kill output thread if this was interrupted
if(subProcessWin.wasSubProcessDestrouedByUser()){
pipedOutThread.interrupt();
subprocess.getInputStream().close();
subprocess.getOutputStream().close();
}
// clean up external process
try {
subprocess.waitFor();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
subprocess.destroy();
logger.info("done");
return wasProcessInterrupted;
}
*/
}