Commit 9871fcb2 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

more on remote console applications

parent 743b1642
Loading
Loading
Loading
Loading
+161 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Copyright (c) 2014 Elphel, Inc.
 * This file is a part of Eclipse/VDT plug-in.
 * Eclipse/VDT plug-in is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Eclipse/VDT plug-in is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package com.elphel.vdt.core.launching;


import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
//import org.eclipse.core.resources.IProject;
//import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.IStreamListener;
//import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IProcess;
//import org.eclipse.debug.ui.DebugUITools;
//import org.eclipse.ui.console.ConsolePlugin;
//import org.eclipse.ui.console.IConsoleManager;
//import org.eclipse.ui.console.IPatternMatchListener;
//import org.eclipse.ui.console.MessageConsole;

import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.console.IConsole;
//import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IOConsole;
import org.eclipse.ui.console.IOConsoleInputStream;
import org.eclipse.ui.console.IOConsoleOutputStream;

import com.elphel.vdt.Txt;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.ui.MessageUI;
//import com.elphel.vdt.VDTPlugin;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.parser.OutlineContainer;
import com.elphel.vdt.veditor.preference.PreferenceStrings;








//import com.elphel.vdt.core.Utils;
import org.eclipse.ui.console.IConsoleListener;

public class RunningBuilds {
//	int nextBuildStep=0;
	private final Map<String, VDTRunnerConfiguration> unfinishedBuilds;
	public RunningBuilds(){
		unfinishedBuilds = new ConcurrentHashMap<String, VDTRunnerConfiguration>();
		IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
// This is not used, just for testing		
		System.out.println("***Addded console listeners");
		manager.addConsoleListener(new IConsoleListener(){
			public void consolesAdded(IConsole[] consoles){
				for (int i=0;i<consoles.length;i++){
					System.out.println("+++ Added: "+consoles[i].getName());
					// Only shows added consoles
				}
			}
			public void consolesRemoved(IConsole[] consoles){
				for (int i=0;i<consoles.length;i++){
					System.out.println("--- Removed: "+consoles[i].getName());
//					unfinishedBuilds.remove(consoles[i]);
					removeConsole(consoles[i]);
				}
			}
		});
	}
	
	public String findConsoleParent(IConsole console){
		Iterator<String> iter=unfinishedBuilds.keySet().iterator();
		System.out.println("findConsoleParent("+console.getName()+")");
		while (iter.hasNext()) {
			String consoleName=iter.next();
			System.out.print("Got console name:"+consoleName);
			VDTRunnerConfiguration runConfig=unfinishedBuilds.get(consoleName);
			if (runConfig.hasConsole(console)){
				System.out.println(consoleName+" -> GOT IT");
				return consoleName;
			}
			System.out.println(consoleName+" -> no luck");
		}
		return null;		
	}
	public void removeConsole(IConsole console){
		String consoleName=findConsoleParent(console);
		if (consoleName!=null){
			VDTRunnerConfiguration runConfig=unfinishedBuilds.get(consoleName);
			runConfig.removeConsole(console);
			System.out.println("Removing console "+console.getName()+" from runConfig for "+consoleName);
			if (runConfig.noConsoles()){
				System.out.println("No consoles left in unfinished "+consoleName+" - removing it too");
				unfinishedBuilds.remove(consoleName);
			}
		} else {
			System.out.println("Console "+console.getName()+" did not belong here");
		}
	}
	public boolean isUnfinished(IConsole console){
		return unfinishedBuilds.containsKey(console);
	}
	
	public VDTRunnerConfiguration resumeConfiguration(String consoleName){
		VDTRunnerConfiguration conf=unfinishedBuilds.get(consoleName);
		unfinishedBuilds.remove(consoleName);
		return conf;
	}

	public VDTRunnerConfiguration getConfiguration(String consoleName){
		VDTRunnerConfiguration conf=unfinishedBuilds.get(consoleName);
		return conf;
	}

	public void removeConfiguration(String consoleName){
		unfinishedBuilds.remove(consoleName);
	}

	public void saveUnfinished(String consoleName, VDTRunnerConfiguration configuration ){
		unfinishedBuilds.put(consoleName, configuration);
	}
    
} // class RunningBuilds
+281 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Copyright (c) 2014 Elphel, Inc.
 * This file is a part of Eclipse/VDT plug-in.
 * Eclipse/VDT plug-in is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Eclipse/VDT plug-in is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package com.elphel.vdt.core.launching;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.IStreamListener;
//import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IProcess;
//import org.eclipse.debug.ui.DebugUITools;
//import org.eclipse.ui.console.ConsolePlugin;
//import org.eclipse.ui.console.IConsoleManager;
//import org.eclipse.ui.console.IPatternMatchListener;
//import org.eclipse.ui.console.MessageConsole;

import org.eclipse.debug.core.model.IStreamMonitor;
//import org.eclipse.debug.core.model.IStreamListener;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.console.IConsole;
//import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IOConsole;
import org.eclipse.ui.console.IOConsoleOutputStream;

import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.ui.MessageUI;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.preference.PreferenceStrings;

public class VDTConsoleRunner{
	private final VDTRunnerConfiguration runConfig;
	private IProcess processErr=null;
	private IProcess processOut=null;
	private IStreamsProxy stdoutStreamProxy=null;
	private IStreamsProxy stderrStreamProxy=null;
	private IStreamsProxy sendErrorsToStreamProxy=null;
	private Object errorListener=null; //+
	private Object outputListener=null; //+
	private IOConsole iCons=null;
	private IProcess process=null;
    private IStreamsProxy consoleInStreamProxy= null;

	
	public VDTConsoleRunner (VDTRunnerConfiguration runConfig){
		this.runConfig=runConfig;
	}
	private BuildParamsItem getParser( String parserName){
		if (parserName==null) return null;
		BuildParamsItem[] buildParamsItems = runConfig.getArgumentsItemsArray(); // uses already calculated
		if (buildParamsItems==null) return null;
		for (int i=0;i<buildParamsItems.length;i++){
			if (parserName.equals(buildParamsItems[i].getNameAsParser()))
				return buildParamsItems[i];
		}
		return null;
	}
	
	public IOConsole runConsole(String consolePrefix
			, ILaunch launch
			, IProgressMonitor monitor 
			) throws CoreException{
    	VDTRunner runner = VDTLaunchUtil.getRunner();
		int numItem=runConfig.getBuildStep();
		BuildParamsItem buildParamsItem = runConfig.getArgumentsItemsArray()[numItem]; // uses already calculated
		//TODO: Handle monitor
		// Find console with name starting with consolePrefix
		IConsoleManager man = ConsolePlugin.getDefault().getConsoleManager(); // debugging
		IConsole[] consoles=(IConsole[]) man.getConsoles();
//		IOConsole iCons=null;
		iCons=null;
		consoleInStreamProxy=null;
		for (int i=0;i<consoles.length;i++){
			if (consoles[i].getName().startsWith(consolePrefix)){
				iCons=(IOConsole) consoles[i];
				break;
			}
		}
		if (iCons==null) {
			MessageUI.error("Specified console: "+consolePrefix+" is not found");
			return null;
		}
		// try to send 
        String[] arguments = runConfig.getToolArguments();
        if (arguments == null) arguments=new String[0];
        if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
//        	System.out.println("patternErrors= \""+  runConfig.getPatternErrors()+"\"");
//        	System.out.println("patternWarnings= \""+runConfig.getPatternWarnings()+"\"");
//        	System.out.println("patternInfo= \""    +runConfig.getPatternInfo()+"\"");
        	if (arguments!=null){
        		for (int i=0;i<arguments.length;i++){
        			System.out.println("Console line "+i+" = \""+arguments[i]+"\"");
        		}
        	}
        }
        runner.log("Writing to console "+iCons.getName()+":", arguments, null, false, true); /* Appears in the console of the target Eclipse (immediately erased) */
        runner.log("Writing to console "+iCons.getName()+":", arguments, null, false, false); /* Appears in the console of the parent Eclipse */

//        IOConsoleInputStream inStream= iCons.getInputStream();
        IOConsoleOutputStream 	outStream= iCons.newOutputStream();
//        IProcess process=((ProcessConsole)iCons).getProcess();
        process=((ProcessConsole)iCons).getProcess();
//        IStreamsProxy consoleInStreamProxy= process.getStreamsProxy();
        consoleInStreamProxy= process.getStreamsProxy();
        
        BuildParamsItem stderrParser=getParser(buildParamsItem.getStderr()); // re-parses all - why?
        BuildParamsItem stdoutParser=getParser(buildParamsItem.getStdout());
        
        System.out.println("Using parser for stderr: "+((stderrParser!=null)?stderrParser.getNameAsParser():"none")); // actually may be the same as stdout
        System.out.println("Using parser for stdout: "+((stdoutParser!=null)?stdoutParser.getNameAsParser():"none"));
        
        processErr=null;
        processOut=null;
        stdoutStreamProxy=null;
        stderrStreamProxy=null;
        if (stdoutParser!=null){
			List<String> toolArgumentsStdout = new ArrayList<String>();
			List<String> stdoutArguments=stdoutParser.getParamsAsList();
			if (stdoutArguments != null)
				toolArgumentsStdout.addAll(stdoutArguments);
			// overwriting runConfig, but this is done sequentially, so OK
			runConfig.setToolArguments((String[])toolArgumentsStdout.toArray(new String[toolArgumentsStdout.size()]));
        	processOut=runner.run(runConfig,
        			"OUT for "+iCons.getName(),
        			launch,
        			null); //monitor);
            stdoutStreamProxy= processOut.getStreamsProxy();
//TODO: Add error parsers            
        }
        
        if (stderrParser!=null){
			List<String> toolArgumentsStderr = new ArrayList<String>();
			List<String> stderrArguments=stderrParser.getParamsAsList();
			if (stderrArguments != null)
				toolArgumentsStderr.addAll(stderrArguments);
			// overwriting runConfig, but this is done sequentially, so OK
			runConfig.setToolArguments((String[])toolArgumentsStderr.toArray(new String[toolArgumentsStderr.size()]));
        	processErr=runner.run(runConfig,
        			"ERR for "+iCons.getName(),
        			launch,
        			null); //monitor);
            stderrStreamProxy= processErr.getStreamsProxy();
          //TODO: Add error parsers            
        }
        
        sendErrorsToStreamProxy=(stderrStreamProxy!=null)?stderrStreamProxy:stdoutStreamProxy;
        final IStreamsProxy fSendErrorsToStreamProxy=sendErrorsToStreamProxy;
        final IStreamsProxy fSendOutputToStreamProxy= stdoutStreamProxy;

// connect input streams of the parsers to the out from the console process         
        IStreamMonitor consoleOutStreamMonitor=null;
        IStreamMonitor consoleErrStreamMonitor=null;
        runConfig.resetConsoleText();
        String interrupt=buildParamsItem.getInterrupt(); // Not yet used
        runConfig.setConsoleFinish(buildParamsItem.getPrompt());
		System.out.println("Using console program termination string: \""+buildParamsItem.getPrompt()+"\"");
		errorListener=null;
        if (fSendErrorsToStreamProxy!=null){
        	consoleErrStreamMonitor=consoleInStreamProxy.getErrorStreamMonitor();
//        	IStreamListener errorListener=null;
        	errorListener=new IStreamListener(){
        		public void streamAppended(String text, IStreamMonitor monitor){
 //       			System.out.println("Err:'"+text+"'");
        			try {
        				fSendErrorsToStreamProxy.write(text);

        			} catch (IOException e) {
        				System.out.println("Can not write errors"); //happens for the last prompt got after finish marker 
        			}
        			if (runConfig.addConsoleText(text)){
        				System.out.println("Got finish sequence");
        				// TODO: launch continuation of the build process
        				finishConsolescript();
        			}
        		}
       		};
        	consoleErrStreamMonitor.addListener((IStreamListener) errorListener);       		
       	}
        outputListener=null;
        if (fSendOutputToStreamProxy!=null){
        	consoleOutStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
        	outputListener=new IStreamListener(){
        		public void streamAppended(String text, IStreamMonitor monitor){
//        			System.out.println("Out:'"+text+"'");
        			try {
        				fSendOutputToStreamProxy.write(text);
        			} catch (IOException e) {
        				System.out.println("Can not write output");
        			}
        			if (runConfig.addConsoleText(text)){
        				System.out.println("Got finish sequence");
        				// TODO: launch continuation of the build process
        				finishConsolescript();
        			}
        		}
       		};
        	consoleOutStreamMonitor.addListener((IStreamListener) outputListener );
        }
		outStream.setColor(new Color(null, 128, 128, 255));
        try {
        	for (int i=0;i<arguments.length;i++){
				if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.LOCAL_ECHO)) {
					outStream.write(arguments[i]+"\n"); // writes to console itself
				}
				consoleInStreamProxy.write(arguments[i]+"\n");
        	}
        } catch (IOException e) {
        	System.out.println("Can not write to outStream of console "+iCons.getName());
        }
		return iCons;
		
	}
	
	
	// TODO: remove unneeded global vars
	
    public void finishConsolescript() {
		System.out.println("finishConsolescript()");
    	if (consoleInStreamProxy==null) {
    		System.out.println("Bug: consoleInStreamProxy == null");
    		return; // or continue other commands?
    	}
    	if (errorListener !=null) { // disconnect error stream listener
    		IStreamMonitor consoleErrorStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
    		consoleErrorStreamMonitor.removeListener((IStreamListener) errorListener);
    	}
    	if (outputListener !=null) { // disconnect output stream listener
    		IStreamMonitor consoleOutStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
    		consoleOutStreamMonitor.removeListener((IStreamListener) outputListener);
    	}
    	// terminate parser(s). Do those console listeners (parsers) have to be removed too?
    	if (processErr!=null){
    		try {
				processErr.terminate();
			} catch (DebugException e) {
				System.out.println("Failed to reminate processErr parser process");
			}
    	}
    	if (processOut!=null){
    		try {
				processOut.terminate();
			} catch (DebugException e) {
				System.out.println("Failed to reminate processOut parser process");
			}
    	}
    	// Is that all?
//    	runConfig.setBuildStep(runConfig.getBuildStep()+1); // next task to run
    	int thisStep=runConfig.getBuildStep();
    	System.out.println("Finished console task, step was "+thisStep);
    	runConfig.setBuildStep(thisStep+1); // next task to run
    	VDTLaunchUtil.getRunner().getRunningBuilds().saveUnfinished(runConfig.getOriginalConsoleName(), runConfig );
    	try {
    		VDTLaunchUtil.getRunner().resumeLaunch(runConfig.getOriginalConsoleName()); // replace with console
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
 } // class VDTConsoleRunner
+5 −3
Original line number Diff line number Diff line
@@ -107,9 +107,11 @@ public class VDTLaunchConfigurationDelegate implements ILaunchConfigurationDeleg
    	runConfig.setBuildStep(0);
    	List<String> controlFiles = VDTLaunchUtil.getControlFiles(configuration);
    	runConfig.setControlFiles((String[])controlFiles.toArray(new String[controlFiles.size()]));
//        String consoleName=VDTRunner.renderProcessLabel(runConfig.getToolName());
    	
        String consoleName=VDTRunner.renderProcessLabel(runConfig.getToolName());
        runner.saveUnfinished(consoleName, runConfig );
        String consoleName=runConfig.getOriginalConsoleName();
        
        runner.getRunningBuilds().saveUnfinished(consoleName, runConfig );
        runner.resumeLaunch(consoleName);
        return;
    }
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public class VDTLaunchUtil {
        }
        return toolRunner;
    }
        
    //runningBuilds
    /**
     * Construct attribute name for command line representations of 
     * tool parameter.
+23 −210

File changed.

Preview size limit exceeded, changes collapsed.

Loading