/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.rubypeople.rdt.launching; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IProcess; import org.rubypeople.rdt.internal.launching.LaunchingMessages; import org.rubypeople.rdt.internal.launching.LaunchingPlugin; /** * Abstract implementation of a VM runner. * <p> * Clients implementing VM runners should subclass this class. * </p> * * @see IVMRunner * @since 0.9.0 */ public abstract class AbstractVMRunner implements IVMRunner { protected IVMInstall fVMInstance; /** * Throws a core exception with an error status object built from the given message, lower level exception, and * error code. * * @param message * the status message * @param exception * lower level exception associated with the error, or <code>null</code> if none * @param code * error code * @throws CoreException * The exception encapsulating the reason for the abort */ protected void abort(String message, Throwable exception, int code) throws CoreException { throw new CoreException(new Status(IStatus.ERROR, getPluginIdentifier(), code, message, exception)); } /** * Returns the identifier of the plug-in this VM runner originated from. * * @return plug-in identifier */ protected abstract String getPluginIdentifier(); public void setVMInstall(IVMInstall vm) { fVMInstance = vm; } /** * @see DebugPlugin#exec(String[], File) */ protected Process exec(String[] cmdLine, File workingDirectory) throws CoreException { if (cmdLine == null) { abort("Command line for process exec is null", null, -1); } List<String> newCmdLine = new ArrayList<String>(); for (String string : cmdLine) { if (string == null) { LaunchingPlugin.log(new Throwable("Null value in command line: " + cmdLine)); } else { newCmdLine.add(string); } } cmdLine = newCmdLine.toArray(new String[newCmdLine.size()]); LaunchingPlugin.info(getDebugLogStatement(cmdLine, workingDirectory)); return DebugPlugin.exec(cmdLine, workingDirectory); } private String getDebugLogStatement(String[] cmdLine, File workingDirectory) { StringBuilder builder = new StringBuilder("Starting: "); builder.append(getCmdLineAsString(cmdLine)); if (workingDirectory != null) builder.append(" in working dir: ").append(workingDirectory); return builder.toString(); } /** * @since 0.9.0 * @see DebugPlugin#exec(String[], File, String[]) */ protected Process exec(String[] cmdLine, File workingDirectory, String[] envp) throws CoreException { if (cmdLine == null) { abort("Command line for process exec is null", null, -1); } List<String> newCmdLine = new ArrayList<String>(); for (String string : cmdLine) { if (string == null) { LaunchingPlugin.log(new Throwable("Null value in command line: " + cmdLine)); } else { newCmdLine.add(string); } } cmdLine = newCmdLine.toArray(new String[newCmdLine.size()]); if (envp == null) return exec(cmdLine, workingDirectory); LaunchingPlugin.info(getDebugLogStatement(cmdLine, workingDirectory)); return DebugPlugin.exec(cmdLine, workingDirectory, envp); } /** * Returns the given array of strings as a single space-delimited string. * * @param cmdLine * array of strings * @return a single space-delimited string */ protected String getCmdLineAsString(String[] cmdLine) { if (cmdLine == null) { return ""; } StringBuffer buff = new StringBuffer(); for (int i = 0, numStrings = cmdLine.length; i < numStrings; i++) { String value = cmdLine[i]; if (value == null) continue; if (value.indexOf(' ') != -1 && !value.startsWith("-")) { if (!value.startsWith("\"")) { value = "\"" + value; } if (!value.endsWith("\"")) { value = value + "\""; } } buff.append(value); buff.append(' '); } return buff.toString().trim(); } /** * Returns the default process attribute map for Ruby processes. * * @return default process attribute map for Ruby processes */ protected Map<String, String> getDefaultProcessMap() { Map<String, String> map = new HashMap<String, String>(); map.put(IProcess.ATTR_PROCESS_TYPE, IRubyLaunchConfigurationConstants.ID_RUBY_PROCESS_TYPE); return map; } /** * Returns a new process aborting if the process could not be created. * * @param launch * the launch the process is contained in * @param p * the system process to wrap * @param label * the label assigned to the process * @param attributes * values for the attribute map * @return the new process * @throws CoreException * problems occurred creating the process * @since 0.9.0 */ protected IProcess newProcess(ILaunch launch, Process p, String label, Map<String, String> attributes) throws CoreException { IProcess process = DebugPlugin.newProcess(launch, p, label, attributes); if (process == null) { p.destroy(); abort(LaunchingMessages.AbstractVMRunner_0, null, IRubyLaunchConfigurationConstants.ERR_INTERNAL_ERROR); } return process; } /** * Combines and returns VM arguments specified by the runner configuration, with those specified by the VM install, * if any. * * @param configuration * runner configuration * @param vmInstall * vm install * @return combined VM arguments specified by the runner configuration and VM install * @since 0.9.0 */ protected String[] combineVmArgs(VMRunnerConfiguration configuration, IVMInstall vmInstall) { String[] launchVMArgs = configuration.getVMArguments(); String[] vmVMArgs = vmInstall.getVMArguments(); if (vmVMArgs == null || vmVMArgs.length == 0) { return launchVMArgs; } String[] allVMArgs = new String[launchVMArgs.length + vmVMArgs.length]; System.arraycopy(launchVMArgs, 0, allVMArgs, 0, launchVMArgs.length); System.arraycopy(vmVMArgs, 0, allVMArgs, launchVMArgs.length, vmVMArgs.length); return allVMArgs; } }