alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.vcscore.cmdline.exec;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.text.*;

import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.util.Utilities;

import org.netbeans.modules.vcscore.util.*;
import org.netbeans.modules.vcscore.commands.VcsCommandExecutor;
import org.netbeans.modules.vcscore.commands.TextOutputListener;
import org.netbeans.modules.vcscore.commands.RegexOutputListener;
import org.netbeans.modules.vcscore.commands.TextInput;
import org.openide.ErrorManager;

/** Single external command to be executed. See {@link TestCommand} for typical usage.
 * 
 * @author Michal Fadljevic
 */
//-------------------------------------------
public class ExternalCommand implements TextInput {

    //public static final int SUCCESS=0;
    //public static final int FAILED=1;
    //public static final int FAILED_ON_TIMEOUT=2;

    private String command = null;
    private StructuredExec scommand = null;
    //private long timeoutMilis = 0;
    private int exitStatus = VcsCommandExecutor.SUCCEEDED;
    private String inputData = null;
    private boolean inputRepeat = false;
    // The standard input stream of the process, in case that inputRepeat == false
    private OutputStream inputStream = null;
    private int osType = Utilities.getOperatingSystem();

    private Object stdOutDataLock = new Object();
    //private RegexListener[] stdoutListeners = new RegexListener[0];
    private ArrayList stdOutDataListeners = new ArrayList();
    private ArrayList stdOutRegexps = new ArrayList();

    private Object stdErrDataLock = new Object();
    //private RegexListener[] stderrListeners = new RegexListener[0];
    private ArrayList stdErrDataListeners = new ArrayList();
    private ArrayList stdErrRegexps = new ArrayList();
    //private Object stdOutErrLock = new Object(); // synchronizes stdout and stderr

    private Object stdOutLock = new Object();
    private Object stdErrLock = new Object();
    private ArrayList stdOutListeners = new ArrayList();
    private ArrayList stdErrListeners = new ArrayList();
    private ArrayList stdImmediateOutListeners = new ArrayList();
    private ArrayList stdImmediateErrListeners = new ArrayList();
    boolean isImmediateOut = false;
    boolean isImmediateErr = false;
    
    // The environment variables
    private String[] envp = null;

    /** Creates new ExternalCommand */
    public ExternalCommand() {
    }

    //-------------------------------------------
    public ExternalCommand(String command) {
        setCommand(command);
    }

    //-------------------------------------------
    public ExternalCommand(String command, String input) {
        setCommand(command);
        //setTimeout(timeoutMilis);
        setInput(input, false);
    }

    public ExternalCommand(StructuredExec sexec) {
        setCommand(sexec);
    }

    //-------------------------------------------
    public void setCommand(String command) {
        this.command = command;
    }

    public void setCommand(StructuredExec scommand) {
        this.scommand = scommand;
    }


    /*
     * WE DO NOT SUPPORT TIMEOUTS ANY MORE !!
     * You may explicitly kill the command if it blocks somewhere.
    public void setTimeout(long timeoutMilis){
        this.timeoutMilis=timeoutMilis;
    }
     */


    /**
     * Set the input, which will be send to the command standard input.
     * @param inputData The String data that will be sent to the command standard input
     * @param repeat Whether the input sequence should be repeated while the command reads it.
     */
    public void setInput(String inputData, boolean repeat) {
        this.inputData = inputData;
        this.inputRepeat = repeat;
    }
    
    /**
     * Send some input data to a running command.
     * This will do nothing if the input is repeated.
     */
    public void sendInput(String inputData) {
        if (inputStream != null) {
            try {
                inputStream.write(inputData.getBytes());
                inputStream.flush();
            } catch (IOException ioex) {
                ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioex);
            }
        } else if (!inputRepeat) {
            if (this.inputData != null) {
                this.inputData += inputData;
            } else {
                this.inputData = inputData;
            }
        }
    }
    
    public void setEnv(String[] envp) {
        this.envp = envp;
    }


    private void setExitStatus(int exitStatus) {
        this.exitStatus = exitStatus;
    }

    /**
     * Get the exit status of the command.
     */
    public int getExitStatus(){
        return exitStatus;
    }

    //-------------------------------------------
    private String[] parseParameters(String s) {
        int NULL = 0x0;  // STICK + whitespace or NULL + non_"
        int INPARAM = 0x1; // NULL + " or STICK + " or INPARAMPENDING + "\ // NOI18N
        int INPARAMPENDING = 0x2; // INPARAM + \
        int STICK = 0x4; // INPARAM + " or STICK + non_" // NOI18N
        int STICKPENDING = 0x8; // STICK + \
        Vector params = new Vector(5,5);
        char c;
        int state = NULL;
        StringBuffer buff = new StringBuffer(20);
        int slength = s.length();
        for (int i = 0; i < slength; i++) {
            c = s.charAt(i);
            if (Character.isWhitespace(c)) {
                if (state == NULL) {
                    params.addElement(buff.toString());
                    buff.setLength(0);
                } else if (state == STICK) {
                    params.addElement(buff.toString());
                    buff.setLength(0);
                    state = NULL;
                } else if (state == STICKPENDING) {
                    buff.append('\\');
                    params.addElement(buff.toString());
                    buff.setLength(0);
                    state = NULL;
                } else if (state == INPARAMPENDING) {
                    state = INPARAM;
                    buff.append('\\');
                    buff.append(c);
                } else {    // INPARAM
                    buff.append(c);
                }
                continue;
            }

            if (c == '\\') {
                if (state == NULL) {
                    ++i;
                    if (i < slength) {
                        char cc = s.charAt(i);
                        if (cc == '"' || cc == '\\') {
                            buff.append(cc);
                        } else if (Character.isWhitespace(cc)) {
                            buff.append(c);
                            --i;
                        } else {
                            buff.append(c);
                            buff.append(cc);
                        }
                    } else {
                        buff.append('\\');
                        break;
                    }
                    continue;
                } else if (state == INPARAM) {
                    state = INPARAMPENDING;
                } else if (state == INPARAMPENDING) {
                    buff.append('\\');
                    state = INPARAM;
                } else if (state == STICK) {
                    state = STICKPENDING;
                } else if (state == STICKPENDING) {
                    buff.append('\\');
                    state = STICK;
                }
                continue;
            }

            if (c == '"') {
                if (state == NULL) {
                    state = INPARAM;
                } else if (state == INPARAM) {
                    state = STICK;
                } else if (state == STICK) {
                    state = INPARAM;
                } else if (state == STICKPENDING) {
                    buff.append('"');
                    state = STICK;
                } else { // INPARAMPENDING
                    buff.append('"');
                    state = INPARAM;
                }
                continue;
            }

            if (state == INPARAMPENDING) {
                buff.append('\\');
                state = INPARAM;
            } else if (state == STICKPENDING) {
                buff.append('\\');
                state = STICK;
            }
            buff.append(c);
        }
        // collect
        if (state == INPARAM) {
            params.addElement(buff.toString());
        } else if ((state & (INPARAMPENDING | STICKPENDING)) != 0) {
            buff.append('\\');
            params.addElement(buff.toString());
        } else { // NULL or STICK
            if (buff.length() != 0) {
                params.addElement(buff.toString());
            }
        }
        String[] ret = new String[params.size()];
        params.copyInto(ret);
        return ret;
    }
    
    public static String[] parseParameters(StructuredExec sexec) {
        List cmdList = new ArrayList();
        cmdList.add(sexec.getExecutable());
        StructuredExec.Argument[] args = sexec.getArguments();
        for (int i = 0; i < args.length; i++) {
            String arg = args[i].getArgument().trim();
            if (arg.length() == 0) continue;
            if (args[i].isLine()) {
                int begin = 0;
                int end = arg.indexOf(' ');
                while (end > 0) {
                    cmdList.add(arg.substring(begin, end));
                    begin = end + 1;
                    while (begin < arg.length() && Character.isWhitespace(arg.charAt(begin))) begin++;
                    end = arg.indexOf(' ', begin);
                }
                end = arg.length();
                if (begin < end) cmdList.add(arg.substring(begin, end));
            } else {
                cmdList.add(arg);
            }
        }
        return (String[]) cmdList.toArray(new String[0]);
    }
    
    private static ArrayList outputGrabbers = new ArrayList();
    private static RequestProcessor outputRequestProcessor;

    /**
     * Executes the external command.
     */
    public int exec(){
        Process proc=null;
        OutputGrabber output = null;

        synchronized (outputGrabbers) {
            if (outputRequestProcessor == null) {
                outputRequestProcessor = new RequestProcessor("External Command Output Grabber Processor"); // NOI18N
                outputRequestProcessor.post(new OutputGrabbersProcessor());
            }
        }
        try{
            String[] commandArr = null;
            try {
                if (scommand != null) {
                    commandArr = parseParameters(scommand);
                    //System.out.println("exec("+VcsUtilities.array2string(commandArr)+", w = '"+scommand.getWorking()+"')");
                    proc = Runtime.getRuntime().exec(commandArr, envp, scommand.getWorking());
                } else {
                    commandArr = parseParameters(command);
                    if (envp == null) {
                        proc = Runtime.getRuntime().exec(commandArr);
                        //System.out.println("exec("+VcsUtilities.array2string(commandArr)+")");
                    } else {
                        proc = Runtime.getRuntime().exec(commandArr, envp);
                        //System.out.println("exec("+VcsUtilities.array2string(commandArr)+", envp = "+envp+")");
                    }
                }
            } catch (IOException e){
                org.openide.ErrorManager.getDefault().notify(
                    org.openide.ErrorManager.getDefault().annotate(e,
                        g("EXT_CMD_RuntimeExc", VcsUtilities.array2string(commandArr))));
                stderrNextLine(g("EXT_CMD_RuntimeFailed", command)); // NOI18N
                setExitStatus(VcsCommandExecutor.FAILED);
                return getExitStatus();
            }

            //watchDog = new WatchDog("VCS-WatchDog",timeoutMilis,Thread.currentThread(), proc); // NOI18N
            // timeout 0 means no dog is waitng to eat you
            //if (timeoutMilis > 0) {
            //    watchDog.start();
            //}

            SafeRunnable inputRepeater = null;
            OutputStream os = proc.getOutputStream();
            if (inputData != null) {
                try{
                    //System.out.println("stdin>>"+inputData);
                    if (inputRepeat) {
                        inputRepeater = new InputRepeater(os, inputData);
                        RequestProcessor.getDefault().post(inputRepeater);
                    } else {
                        os.write(inputData.getBytes());
                    }
                }
                catch(IOException e){
                    ErrorManager.getDefault().notify(e);
                }
            }
            if (!inputRepeat) {
                inputStream = os;
            }

            output = new OutputGrabber(proc.getInputStream(), proc.getErrorStream());
            synchronized (outputGrabbers) {
                outputGrabbers.add(output);
                //System.out.println("ExternalCommand.exec(): output grabber added.");
                outputGrabbers.notifyAll();
            }

            int exit = proc.waitFor();
            if (inputRepeater != null) {
                inputRepeater.doStop();
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ioex) {
                    // silently ignore, will be a broken pipe
                }
            }
            output.doStop();
            try {
                output.waitToFinish();
            } catch (InterruptedException iex) {}

            setExitStatus(exit == 0 ? VcsCommandExecutor.SUCCEEDED
                                    : VcsCommandExecutor.FAILED);
        }
        catch(InterruptedException e){
            proc.destroy();
            setExitStatus(VcsCommandExecutor.INTERRUPTED);
        } finally {
            //processCommandOutput();
            if (output != null) { // if exec() throws an exception, output == null !
                output.doStop();
                boolean finished = false;
                do {
                    try {
                        output.waitToFinish();
                        finished = true;
                    } catch (InterruptedException iexc) {
                        // It's dangerous to finish before output finishes
                        output.doReallyStop();
                    }
                } while (!finished);
            }
        }

        return getExitStatus();
    }

    /*
    private void processCommandOutput() {
      for(Enumeration elements = commandOutput.elements(); elements.hasMoreElements(); ) {
        String what = (String) elements.nextElement();
        if (elements.hasMoreElements()) {
          if (what.equals(STDOUT)) {
            stdoutNextLineCached((String) elements.nextElement());
          } else {
            stderrNextLineCached((String) elements.nextElement());
          }
        }
      }
}
    */

    //-------------------------------------------
    public String toString(){
        return command;
    }

    private class OutputGrabber extends Object implements SafeRunnable {
        
        private static final int LINE_LENGTH = 80;
        private static final int BUFF_LENGTH = 512;
        
        private InputStreamReader stdout;
        private InputStreamReader stderr;

        // Variables indicating EOF of command's output streams.
        // They are needed only for the OpenVMS & OS/2 patch.
        private boolean eof_stdout = false;
        private boolean eof_stderr = false;

        private boolean shouldStop = false;
        private boolean stopped = false;
        private boolean finished = false;
        private StringBuffer outBuffer = new StringBuffer(LINE_LENGTH);
        private StringBuffer errBuffer = new StringBuffer(LINE_LENGTH);
        private char[] buff = new char[BUFF_LENGTH];
        
        public OutputGrabber(InputStream stdout, InputStream stderr) {
            this.stdout = new InputStreamReader(stdout);
            this.stderr = new InputStreamReader(stderr);
        }
        
        /** Stop the grabber */
        public void doStop() {
            shouldStop = true;
        }
        
        public void doReallyStop() {
            // We really need to stop it!
            try {
                stdout.close();
                stderr.close();
            } catch (IOException ioexc) {}
        }
        
        /** Whether the grabber is stopped. If yes, should be flushed and garbage-collected. */
        public boolean isStopped() {
            try {
                //if (shouldStop && !stdout.ready() && !stderr.ready()) stopped = true;
                // If the OS is OpenVMS or OS/2, we want to stop only if EOF has been reached on both output streams
                if (osType != Utilities.OS_VMS && osType != Utilities.OS_OS2) {
                    if (shouldStop && !stdout.ready() && !stderr.ready()) stopped = true;
                } else {
                    if (shouldStop && eof_stdout && eof_stderr) {
                        stopped = true;
                    } else {
                        stopped = false;
                    }
                }
            } catch (IOException ioexc) {
                stopped = true;
            }
            return stopped;
        }
        
        public void waitToFinish() throws InterruptedException {
            synchronized (this) {
                while (!finished) {
                    wait();
                }
            }
        }
        
        /** Whether there is some output to grab */
        public boolean hasOutput() {
            boolean has;
            try {
                //has = stdout.ready() || stderr.ready();
                // If the OS is OpenVMS or OS/2, just assume there is output available
                if (osType != Utilities.OS_VMS && osType != Utilities.OS_OS2) {
                    has = stdout.ready() || stderr.ready();
                } else {
                    has = true;
                }
            } catch (IOException ioexc) {
                has = false;
            }
            return has;
        }
        
        /** Run the grabbing. It grabbs some of the output, needs to be invoked periodically
             intil it's not stopped. */
        public void run() {
            int n = 0;
            try {
                //if (stdout.ready() && (n = stdout.read(buff, 0, BUFF_LENGTH)) > -1) {
                // For OpenVMS and OS/2, we need to see EOF before we're sure we've grabbed all output
                if (((osType == Utilities.OS_VMS || osType == Utilities.OS_OS2) && !eof_stdout) || stdout.ready()) {
                    n = stdout.read(buff, 0, BUFF_LENGTH);
                }
                if (n > -1) {
                    for (int i = 0; i < n; i++) {
                        if (buff[i] == '\n') {
                            try {
                                stdoutNextLine(outBuffer.toString());
                            } finally {
                                outBuffer.delete(0, outBuffer.length());
                            }
                        } else {
                            if (buff[i] != 13) {
                                outBuffer.append(buff[i]);
                            }
                        }
                    }
                    //if (n > 0) System.out.println("IMMEDIATE OUT("+n+") = '"+new String(buff, 0, n)+"'");
                    if (n > 0 && isImmediateOut) {
                        synchronized (stdOutLock) {
                            Iterator it = stdImmediateOutListeners.iterator();
                            while(it.hasNext()) {
                                ((TextOutputListener) it.next()).outputLine(new String(buff, 0, n));
                            }
                        }
                    }
                } else {
                    stopped = true;
                    eof_stdout = true;
                }
                //if (stderr.ready() && (n = stderr.read(buff, 0, BUFF_LENGTH)) > -1) {
                n = 0;
                // For OpenVMS and OS/2, we need to see EOF before we're sure we've grabbed all output
                if (((osType == Utilities.OS_VMS || osType == Utilities.OS_OS2) && !eof_stderr) || stderr.ready()) {
                    n = stderr.read(buff, 0, BUFF_LENGTH);
                }
                if (n > -1) {
                    for (int i = 0; i < n; i++) {
                        if (buff[i] == '\n') {
                            try {
                                stderrNextLine(errBuffer.toString());
                            } finally {
                                errBuffer.delete(0, errBuffer.length());
                            }
                        } else {
                            if (buff[i] != 13) {
                                errBuffer.append(buff[i]);
                            }
                        }
                    }
                    //if (n > 0) System.out.println("IMMEDIATE ERR("+n+") = '"+new String(buff, 0, n)+"'");
                    if (n > 0 && isImmediateErr) {
                        synchronized (stdErrLock) {
                            Iterator it = stdImmediateErrListeners.iterator();
                            while(it.hasNext()) {
                                ((TextOutputListener) it.next()).outputLine(new String(buff, 0, n));
                            }
                        }
                    }
                } else {
                    stopped = true;
                    eof_stderr = true;
                }
            } catch (IOException ioexc) {
                stopped = true;
            }
        }
        
        /** Flush some remaining output. */
        public void flush() {
            try {
                if (outBuffer.length() > 0) stdoutNextLine(outBuffer.toString());
                if (errBuffer.length() > 0) stderrNextLine(errBuffer.toString());
            } finally {
                try {
                    stdout.close();
                } catch (IOException ioexc) {}
                try {
                    stderr.close();
                } catch (IOException ioexc1) {}
                finished = true;
                synchronized (this) {
                    notifyAll();
                }
            }
        }
        
    }
    
    private class OutputGrabbersProcessor extends Object implements Runnable {
        
        public void run() {
            //System.out.println("OutputGrabbersProcessor started.");
            do {
                try {
                    synchronized (outputGrabbers) {
                        //System.out.println("outputGrabbers.size = "+outputGrabbers.size());
                        while (outputGrabbers.size() == 0) {
                            //System.out.println(" waiting...");
                            outputGrabbers.wait();
                            //System.out.println(" notified.");
                        }
                    }
                    boolean processed = false;
                    int n = outputGrabbers.size();
                    //System.out.println("  numGrabbers = "+n);
                    for (int i = 0; i < n; i++) {
                        OutputGrabber output = (OutputGrabber) outputGrabbers.get(i);
                        //System.out.println("  output("+i+"): isStopped() = "+output.isStopped()+", hasOutput() = "+output.hasOutput());
                        if (!output.isStopped()) {
                            if (output.hasOutput()) {
                                output.run();
                                processed = true;
                            }
                        } else {
                            output.flush();
                            outputGrabbers.remove(i);
                            i--;
                            n--;
                        }
                    }
                    if (!processed) {
                        Thread.currentThread().sleep(200);
                    }
                } catch (InterruptedException iexc) {
                    break;
                } catch (ThreadDeath td) {
                    throw td;
                } catch (Throwable t) {
                    org.openide.ErrorManager.getDefault().notify(t);
                }
            } while(true);
        }
        
    }
    
    private class InputRepeater extends Object implements SafeRunnable {
        
        private OutputStream out;
        private byte[] input;
        boolean stop = false;
        
        public InputRepeater(OutputStream out, String input) {
            this.out = out;
            this.input = input.getBytes();
        }
        
        public void doStop() {
            stop = true;
            try {
                out.close();
            } catch (IOException ioex) {
                // Probably broken pipe, not worth to notify anyone
                //ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioex);
            }
        }
        
        public void run() {
            try {
                while (!stop) {
                    //System.out.println("WRITTING to stdin: '"+new String(input)+"'");
                    out.write(input);
                }
            } catch (IOException ioex) {
                // Something bad has happened => stop
                stop = true;
                // Might be a Brokem pipe here. Do not notify anyone, we can not
                // cleanly test whether the process is still running or not anyway.
                // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioex);
            }
        }
        
    }


    /**
     * Add a listener to the standard output with a specific regular expression.
     */
    public void addRegexOutputListener(RegexOutputListener l, String regex) throws BadRegexException {
        synchronized(stdOutDataLock) {
            if (stdOutDataListeners.contains(l)) return;
            Pattern pattern = null;
            try {
                pattern = Pattern.compile(regex);
            } catch(PatternSyntaxException e) {
                throw new BadRegexException("Bad regexp.", e); // NOI18N
            }

            stdOutDataListeners.add(l);
            stdOutRegexps.add(pattern);
        }

    }


    /**
     * Add a listener to the standard error output with a specific regular expression.
     */
    public void addRegexErrorListener(RegexOutputListener l, String regex) throws BadRegexException {
        synchronized(stdErrDataLock) {
            if (stdErrDataListeners.contains(l)) return;
            Pattern pattern = null;
            try {
                pattern = Pattern.compile(regex);
            } catch(PatternSyntaxException e) {
                throw new BadRegexException("Bad regexp.", e); // NOI18N
            }
            stdErrDataListeners.add(l);
            stdErrRegexps.add(pattern);
        }
    }


    /**
     * Add a listener to the standard output.
     */
    public void addTextOutputListener(TextOutputListener l) {
        synchronized(stdOutLock) {
            this.stdOutListeners.add(l);
        }
    }


    /**
     * Add a listener to the standard error output.
     */
    public void addTextErrorListener(TextOutputListener l) {
        synchronized(stdErrLock) {
            this.stdErrListeners.add(l);
        }
    }
    
    /**
     * Add a listener to the standard output, that will be noified
     * immediately as soon as the output text is available. It does not wait
     * for the new line and does not send output line-by-line.
     */
    public void addImmediateTextOutputListener(TextOutputListener l) {
        isImmediateOut = true;
        synchronized(stdOutLock) {
            this.stdImmediateOutListeners.add(l);
        }
    }

    /**
     * Add a listener to the standard error output, that will be noified
     * immediately as soon as the output text is available. It does not wait
     * for the new line and does not send output line-by-line.
     */
    public void addImmediateTextErrorListener(TextOutputListener l) {
        isImmediateErr = true;
        synchronized(stdErrLock) {
            this.stdImmediateErrListeners.add(l);
        }
    }

    /**
     * Remove a standard output data listener.
     */
    public void removeRegexOutputListener(RegexOutputListener l) {
        synchronized(stdOutDataLock) {
            int index = stdOutDataListeners.indexOf(l);
            if (index < 0) return;
            stdOutDataListeners.remove(index);
            stdOutRegexps.remove(index);
        }
    }


    /**
     * Remove an error output data listener.
     */
    public void removeRegexErrorListener(RegexOutputListener l) {
        synchronized(stdErrDataLock) {
            int index = stdErrDataListeners.indexOf(l);
            if (index < 0) return;
            stdErrDataListeners.remove(index);
            stdErrRegexps.remove(index);
        }
    }


    //-------------------------------------------
    public static String[] matchToStringArray(Pattern pattern, String line) {
        Matcher m = pattern.matcher(line);
        if (!m.matches()) {
            return new String[0];
        }
        int count = m.groupCount();
        List l = new ArrayList(count);
        for (int i=1; i <= count; i++) {
            String capturingGroup = m.group(i);
            if (capturingGroup != null) {
                l.add(capturingGroup);
            }
        }
        count = l.size();
        if (count <= 0) count = 1;
        String[] sa = new String[count];
        l.toArray(sa);
        return sa;
    }

    //-------------------------------------------
    private void stdoutNextLine(String line) {
        synchronized(stdOutDataLock) {
            int n = stdOutDataListeners.size();
            for (int i = 0; i < n; i++) {
                try {
                    Pattern pattern = (Pattern) stdOutRegexps.get(i);
                    String[] sa = matchToStringArray(pattern, line);
                    if (sa != null && sa.length > 0) ((RegexOutputListener) stdOutDataListeners.get(i)).outputMatchedGroups(sa);
                } catch (ThreadDeath td) {
                    throw td;
                } catch (Throwable th) {
                    ErrorManager.getDefault().notify(th);
                }
            }
        }
        synchronized(stdOutLock) {
            Iterator it = stdOutListeners.iterator();
            while(it.hasNext()) {
                try {
                    ((TextOutputListener) it.next()).outputLine(line);
                } catch (ThreadDeath td) {
                    throw td;
                } catch (Throwable th) {
                    ErrorManager.getDefault().notify(th);
                }
            }
        }
    }

    //-------------------------------------------
    private void stderrNextLine(String line) {
        synchronized(stdErrDataLock) {
            int n = stdErrDataListeners.size();
            for (int i = 0; i < n; i++) {
                try {
                    Pattern pattern = (Pattern) stdErrRegexps.get(i);
                    String[] sa = matchToStringArray(pattern, line);
                    if (sa != null && sa.length > 0) ((RegexOutputListener) stdErrDataListeners.get(i)).outputMatchedGroups(sa);
                } catch (ThreadDeath td) {
                    throw td;
                } catch (Throwable th) {
                    ErrorManager.getDefault().notify(th);
                }
            }
        }
        synchronized(stdErrLock) {
            Iterator it = stdErrListeners.iterator();
            while(it.hasNext()) {
                try {
                    ((TextOutputListener) it.next()).outputLine(line);
                } catch (ThreadDeath td) {
                    throw td;
                } catch (Throwable th) {
                    ErrorManager.getDefault().notify(th);
                }
            }
        }
    }

    //-------------------------------------------
    String g(String s) {
        return NbBundle.getBundle(ExternalCommand.class).getString (s);
    }
    String  g(String s, Object obj) {
        return MessageFormat.format (g(s), new Object[] { obj });
    }
    String g(String s, Object obj1, Object obj2) {
        return MessageFormat.format (g(s), new Object[] { obj1, obj2 });
    }
    String g(String s, Object obj1, Object obj2, Object obj3) {
        return MessageFormat.format (g(s), new Object[] { obj1, obj2, obj3 });
    }
    //-------------------------------------------
}

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.