x10dt.ui.launch.java.launching.X10LaunchConfigurationDelegate.java Source code

Java tutorial

Introduction

Here is the source code for x10dt.ui.launch.java.launching.X10LaunchConfigurationDelegate.java

Source

/*******************************************************************************
 * Copyright (c) 2010 IBM Corporation.                                         *
 * 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                                   *
 *******************************************************************************/
package x10dt.ui.launch.java.launching;

import static x10dt.ui.launch.core.utils.PTPConstants.LOCAL_CONN_SERVICE_ID;
import static x10dt.ui.launch.core.utils.PTPConstants.REMOTE_CONN_SERVICE_ID;
import static x10dt.ui.launch.cpp.launching.ConnectionTab.ATTR_REMOTE_OUTPUT_FOLDER;
import static x10dt.ui.launch.cpp.launching.ConnectionTab.ATTR_X10_DISTRIBUTION;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.DirectorySourceContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.osgi.util.NLS;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionManager;
import org.eclipse.remote.core.IRemoteFileManager;
import org.eclipse.remote.core.IRemoteServices;
import org.eclipse.remote.core.RemoteServices;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

import x10dt.core.utils.URIUtils;
import x10dt.ui.launch.core.Constants;
import x10dt.ui.launch.core.launching.ArgumentParser;
import x10dt.ui.launch.core.utils.CoreResourceUtils;
import x10dt.ui.launch.core.utils.IProcessOuputListener;
import x10dt.ui.launch.core.utils.LaunchUtils;
import x10dt.ui.launch.core.utils.ProjectUtils;
import x10dt.ui.launch.core.utils.UIUtils;
import x10dt.ui.launch.cpp.CppLaunchCore;
import x10dt.ui.launch.cpp.LaunchMessages;
import x10dt.ui.launch.cpp.builder.target_op.ITargetOpHelper;
import x10dt.ui.launch.cpp.builder.target_op.TargetOpHelperFactory;
import x10dt.ui.launch.cpp.launching.ConfUtils;
import x10dt.ui.launch.java.Activator;
import x10dt.ui.launch.java.Messages;

/**
 * Performs launching of Java application generated by X10 back-end.
 * 
 * @author egeay
 */
public final class X10LaunchConfigurationDelegate implements ILaunchConfigurationDelegate {
    private static String ATTR_ENV = "org.eclipse.debug.core.environmentVariables";
    private static String NPLACES = "X10_NPLACES";
    private static String HOSTFILE = "X10_HOSTFILE";
    private static String HOSTLIST = "X10_HOSTLIST";
    public static int HOST_FILE = 0;
    public static int HOST_LIST = 1;

    // --- Overridden methods

    public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor)
            throws CoreException {
        IJavaProject javaProject = fLocalConfDelegate.verifyJavaProject(configuration);
        IProject project = javaProject.getProject();
        boolean shouldLaunch = true;
        int errorCount = CoreResourceUtils.getNumberOfBuildErrorMarkers(project);

        if (errorCount > 0) {
            // Oops, there are errors on the project... ask the user whether to proceed with the launch
            String message = (errorCount == 0) ? null
                    : NLS.bind(x10dt.ui.launch.core.Messages.LCD_LaunchWithErrorsCheck, errorCount,
                            project.getName());
            shouldLaunch = LaunchUtils.queryUserToLaunchWithErrors(message);
        }

        if (shouldLaunch) {
            runCommand(configuration, mode, javaProject, monitor);
        }
    }

    private void runCommand(final ILaunchConfiguration configuration, final String mode,
            final IJavaProject javaProject, final IProgressMonitor monitor) throws CoreException {
        try {

            final MessageConsole messageConsole = UIUtils.findOrCreateX10Console();
            final MessageConsoleStream mcStream = messageConsole.newMessageStream();
            messageConsole.activate();
            messageConsole.clearConsole();

            final String mainTypeName = this.fLocalConfDelegate.getMainTypeName(configuration);

            final File workingDir = getWorkingDir(configuration, javaProject, mainTypeName);

            final boolean isLocal = ConfUtils.isLocalConnection(configuration);

            final IPath jarPath;
            if (!isLocal) {
                jarPath = transferJar(createJarFile(workingDir, javaProject.getElementName(), mainTypeName),
                        configuration.getName(), getOutputFolder(configuration));
            } else {
                jarPath = null;
            }

            //         if (isLocal){
            //            ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
            //            if (manager != null) {
            //               ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
            //                  if (type != null) {
            //                     ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, "X10-Java-backend-launch");
            //                     
            //                     
            //                     workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
            //
            //                     workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, getClassPath(configuration));
            //
            //                     workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,getVMArguments(configuration, false));
            //
            //                     workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "x10.x10rt.Launcher");
            //                     
            //                     workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, workingDir.getAbsolutePath());
            //                     
            //                     final String attrProgArgs = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, ""); //$NON-NLS-1$
            //                      final String progArgs = mainTypeName + " " + VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(attrProgArgs);
            //                      
            //                      workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, progArgs);
            //                      ILaunchConfiguration conf = workingCopy.doSave();
            //                     workingCopy.launch(mode, monitor);
            //                     //DebugUITools.launch(conf, ILaunchManager.DEBUG_MODE);
            //                     
            //                     
            //                     
            //                     if (mode.equals(ILaunchManager.DEBUG_MODE)){
            //                        ILaunchConfigurationWorkingCopy remoteDebugLaunchConfig = createRemoteDebugLaunchConfiguration(javaProject.getProject().getName(), "54729");
            //                        remoteDebugLaunchConfig.launch(ILaunchManager.DEBUG_MODE, monitor);
            //                        //DebugUITools.launch(remoteDebugLaunchConfig, ILaunchManager.DEBUG_MODE);
            //                     }
            //                     
            //                     
            //                  }
            //            }
            //         }

            final Map<String, String> env = new HashMap<String, String>();
            final int NPlaces = ConfUtils.getNPlaces(configuration);
            env.put(NPLACES, (new Integer(NPlaces)).toString());
            int sel = ConfUtils.hostSelectionMode(configuration);
            if (sel == HOST_FILE) {
                env.put(HOSTFILE, ConfUtils.getHostFile(configuration));
            } else if (sel == HOST_LIST) {
                env.put(HOSTLIST, ConfUtils.getHostList(configuration));
            }

            Map<String, String> launchEnv = configuration.getAttribute(ATTR_ENV, (Map<String, String>) null);
            if (launchEnv != null) {
                for (String key : launchEnv.keySet()) {
                    env.put(key, launchEnv.get(key));
                }
            }
            final List<String> command = new ArrayList<String>();

            final String x10DistFolder = getX10DistributionFolder(configuration, !isLocal);
            this.fExecPath = getExecutablePath(x10DistFolder, isLocal, configuration.getName());
            final String cmd = this.fExecPath.toString();

            if (!isLocal) {
                command.add(cmd);
            }

            final String[] argArr = getProgArguments(configuration, mainTypeName, jarPath, !isLocal, mode);
            for (String s : argArr) {
                command.add(s);
            }

            this.fTargetOpHelper = TargetOpHelperFactory.create(ConfUtils.isLocalConnection(configuration),
                    this.fIsCygwin, ConfUtils.getConnectionName(configuration));
            this.fWorkspaceDir = getWorkspaceDir(configuration, javaProject.getProject(), isLocal);

            this.fTargetOpHelper.run(command, this.fWorkspaceDir, env, new IProcessOuputListener() {

                public void read(final String line) {
                    mcStream.println(line);

                }

                public void readError(final String line) {
                    if (this.fCounter == 0) {
                        //mcStream.println(NLS.bind(LaunchMessages.CLCD_CmdUsedMsg, cmd));
                        this.fCounter = 1;
                    }
                    if (mode.equals(ILaunchManager.DEBUG_MODE) && donePorts != NPlaces) {
                        donePorts++;

                        try {
                            ILaunchConfigurationWorkingCopy remoteDebugLaunchConfig = createRemoteDebugLaunchConfiguration(
                                    configuration, javaProject.getProject().getName(), getPort(line),
                                    getPlace(line));
                            remoteDebugLaunchConfig.launch(ILaunchManager.DEBUG_MODE, new NullProgressMonitor());
                        } catch (CoreException e) {

                        }

                    } else {
                        mcStream.println(line);
                    }
                }

                // --- Fields

                int fCounter;
                int donePorts = 0;

            }, monitor);

            mcStream.flush();
            mcStream.close();
        } catch (InterruptedException e) {
            throw new CoreException(
                    new Status(IStatus.ERROR, CppLaunchCore.PLUGIN_ID, LaunchMessages.CLCD_Interrupted, e));
        } catch (IOException e) {
            throw new CoreException(
                    new Status(IStatus.ERROR, CppLaunchCore.PLUGIN_ID, LaunchMessages.CLCD_IOError, e));
        }

    }

    // --- Private code

    private String getPort(String line) {
        int i = line.indexOf("address:");
        return line.substring(i + 9);
    }

    private String getPlace(String line) {
        int i = line.indexOf("-");
        return line.substring(0, i - 1);
    }

    private ILaunchConfigurationWorkingCopy createRemoteDebugLaunchConfiguration(ILaunchConfiguration configuration,
            final String projectName, final String port, final String place) throws CoreException {
        ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
        ILaunchConfigurationType type = manager
                .getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_REMOTE_JAVA_APPLICATION);

        final ILaunchConfigurationWorkingCopy remoteDebugConfig = type.newInstance(null, place);

        // Set project
        remoteDebugConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, projectName);

        String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO,
                (String) null);
        String source_locator_id = configuration.getType().getSourceLocatorId();
        ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
        ISourceLocator locator = launchManager.newSourceLocator(source_locator_id);
        if (locator instanceof AbstractSourceLookupDirector) {
            AbstractSourceLookupDirector director = (AbstractSourceLookupDirector) locator;
            if (memento == null) {
                director.initializeDefaults(configuration);
            } else {
                director.initializeFromMemento(memento, configuration);
            }
            DirectorySourceContainer dir = new DirectorySourceContainer(
                    this.fLocalConfDelegate.getX10SourceLocation(configuration), true);
            ArrayList<ISourceContainer> sourceContainers = new ArrayList<ISourceContainer>(
                    Arrays.asList(director.getSourceContainers()));
            sourceContainers.add(0, dir);
            director.setSourceContainers(
                    (ISourceContainer[]) sourceContainers.toArray(new ISourceContainer[sourceContainers.size()]));
            remoteDebugConfig.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, director.getMemento());
            remoteDebugConfig.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, director.getId());
        }

        // Set JVM debugger connection parameters
        Map<String, String> connectionParameters = new HashMap<String, String>();
        connectionParameters.put("hostname", "localhost");
        connectionParameters.put("port", port);
        remoteDebugConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, connectionParameters);
        remoteDebugConfig.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR,
                "org.eclipse.jdt.launching.socketAttachConnector");
        remoteDebugConfig.doSave();
        return remoteDebugConfig;
    }

    public String getWorkspaceDir(final ILaunchConfiguration configuration, final IProject project, boolean isLocal)
            throws CoreException {
        if (isLocal) {
            return ProjectUtils.getProjectOutputDirPath(project);
        } else {
            return getOutputFolder(configuration);
        }
    }

    private void addWinWMArgs(final StringBuilder stringBuilder) {
        if (Platform.OS_WIN32.equals(Platform.getOS())) {
            stringBuilder.append(' ').append(X10RT_IMPL_VMARG);
        }
    }

    /* private List<String> getClassPath(final ILaunchConfiguration configuration) throws CoreException {
         final List<String> list = new ArrayList<String>();
         for (final String element : this.fLocalConfDelegate.getClasspath(configuration)) {
      IRuntimeClasspathEntry entry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(element));
      list.add(entry.getMemento());
         }
         return list;
       }
       */

    private String buildClassPath(final ILaunchConfiguration configuration) throws CoreException {
        final StringBuilder sb = new StringBuilder();
        for (final String element : this.fLocalConfDelegate.getClasspath(configuration)) {
            if (sb.length() > 0) {
                sb.append(File.pathSeparatorChar);
            }
            sb.append(element);
        }
        return sb.toString();
    }

    private boolean containsMainType(final File folder, final String mainTypeFileName) {
        for (final File file : folder.listFiles()) {
            if (file.isDirectory()) {
                if (containsMainType(file, mainTypeFileName)) {
                    return true;
                }
            } else {
                if (file.getPath().endsWith(mainTypeFileName)) {
                    return true;
                }
            }
        }
        return false;
    }

    private void createJarFile(int pathStartIndex, final File folder, final JarOutputStream outStream,
            final byte[] buffer) throws IOException {
        for (final File file : folder.listFiles()) {
            if (file.isDirectory()) {
                String name = file.getPath().substring(pathStartIndex).replace("\\", "/");
                if (!name.endsWith("/")) {
                    name = name + "/";
                }
                final JarEntry jarEntry = new JarEntry(name);
                jarEntry.setTime(file.lastModified());
                outStream.putNextEntry(jarEntry);
                outStream.closeEntry();
                createJarFile(pathStartIndex, file, outStream, buffer);
            } else {
                if (file.getName().endsWith(Constants.CLASS_EXT)) {
                    final JarEntry jarEntry = new JarEntry(
                            file.getPath().substring(pathStartIndex).replace("\\", "/"));
                    jarEntry.setTime(file.lastModified());
                    outStream.putNextEntry(jarEntry);

                    final FileInputStream inputStream = new FileInputStream(file);
                    while (true) {
                        final int nRead = inputStream.read(buffer, 0, buffer.length);
                        if (nRead <= 0) {
                            break;
                        } else {
                            outStream.write(buffer, 0, nRead);
                        }
                    }
                    inputStream.close();
                    outStream.closeEntry();
                }
            }
        }
    }

    private IPath createJarFile(final File folder, final String projectName, final String mainTypeName)
            throws CoreException {
        try {
            final File archiveFile = new File(folder, projectName + ".jar"); //$NON-NLS-1$

            final FileOutputStream stream = new FileOutputStream(archiveFile);
            final Manifest manifest = new Manifest();
            manifest.getMainAttributes().putValue("Manifest-Version", "1.0"); //$NON-NLS-1$ //$NON-NLS-2$
            manifest.getMainAttributes().putValue("Main-Class", mainTypeName); //$NON-NLS-1$
            final JarOutputStream outStream = new JarOutputStream(stream, manifest);

            String path = folder.getPath().replace("\\", "/");
            int pathStartIndex = path.endsWith("/") ? path.length() : path.length() + 1;
            createJarFile(pathStartIndex, folder, outStream, new byte[1024]);

            outStream.close();
            stream.close();

            return new Path(archiveFile.getAbsolutePath());
        } catch (IOException except) {
            throw new CoreException(
                    new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.XLCD_JarCreationError, except));
        }
    }

    private IPath getExecutablePath(final String x10DistFolder, boolean isLocal, final String confName)
            throws CoreException {
        if (isLocal) {
            final IRemoteServices remoteServices = RemoteServices.getRemoteServices(LOCAL_CONN_SERVICE_ID);
            final IRemoteConnectionManager rmConnManager = remoteServices.getConnectionManager();
            final String x10Launcher = this.fLocalConfDelegate.getX10DistHostLauncherDir("bin/X10Launcher") //$NON-NLS-1$
                    .getAbsolutePath();
            final IRemoteConnection connection = rmConnManager
                    .getConnection(IRemoteConnectionManager.LOCAL_CONNECTION_NAME);
            final IRemoteFileManager rmFileManager = connection.getFileManager();
            final IFileStore x10LauncherFStore = rmFileManager.getResource(x10Launcher);
            final IFileInfo x10LauncherFInfo = x10LauncherFStore.fetchInfo();
            if (!x10LauncherFInfo.getAttribute(EFS.ATTRIBUTE_EXECUTABLE)) {
                x10LauncherFInfo.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, true);
                x10LauncherFStore.putInfo(x10LauncherFInfo, EFS.SET_ATTRIBUTES, null /* monitor */);
            }
            return new Path(x10Launcher);
        } else {
            final IRemoteServices remoteServices = RemoteServices.getRemoteServices(REMOTE_CONN_SERVICE_ID);
            final IRemoteConnectionManager rmConnManager = remoteServices.getConnectionManager();
            final IRemoteConnection connection = rmConnManager.getConnection(confName);
            final IRemoteFileManager rmFileManager = connection.getFileManager();
            final IPath x10 = new Path(x10DistFolder).append("bin").append("x10"); //$NON-NLS-1$ //$NON-NLS-2$
            final IFileStore x10FileStore = rmFileManager.getResource(x10.toString());
            if (x10FileStore.fetchInfo().exists()) {
                return x10;
            } else {
                throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.XLCD_NoX10Script));
            }
        }
    }

    private File getLocalFile(final IPath path) throws CoreException {
        final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        final IResource resource = root.findMember(path);
        if (resource == null) {
            throw new CoreException(
                    new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(Messages.XLCD_ResourceNotFound, path)));
        }
        final IFileStore fileStore = EFS.getLocalFileSystem()
                .getStore(URIUtils.getExpectedURI(resource.getLocationURI()));
        if (fileStore.fetchInfo().exists()) {
            return fileStore.toLocalFile(EFS.NONE, new NullProgressMonitor());
        } else {
            return null;
        }
    }

    private String getOutputFolder(final ILaunchConfiguration configuration) throws CoreException {
        final String folder = configuration.getAttribute(ATTR_REMOTE_OUTPUT_FOLDER, Constants.EMPTY_STR);
        if (folder.length() == 0) {
            throw new CoreException(
                    new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.XLCD_OutputFolderNotDefined));
        }
        return folder;
    }

    private String[] parse(String args) {
        return args.split("\\s+");
    }

    private String[] getProgArguments(final ILaunchConfiguration configuration, final String mainTypeName,
            final IPath jarPath, final boolean isRemote, String mode) throws CoreException {
        final StringBuilder sb = new StringBuilder();

        if (isRemote) {
            sb.append(String.format("%s -cp \"%s\" %s", getVMArguments(configuration, true), jarPath.toString(), //$NON-NLS-1$
                    mainTypeName));
        } else if (mode.equals(ILaunchManager.DEBUG_MODE)) {
            sb.append(String.format("java -XX:+UseParallelGC %s -cp \"%s\" %s -debug %s", //$NON-NLS-1$
                    getVMArguments(configuration, false), buildClassPath(configuration), "x10.x10rt.Launcher", mainTypeName));
        } else {
            sb.append(String.format("java %s -cp \"%s\" %s %s", getVMArguments(configuration, false), //$NON-NLS-1$
                    buildClassPath(configuration), "x10.x10rt.Launcher", mainTypeName));
        }

        final String attrProgArgs = configuration
                .getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, ""); //$NON-NLS-1$
        final String progArgs = VariablesPlugin.getDefault().getStringVariableManager()
                .performStringSubstitution(attrProgArgs);

        if (progArgs.length() > 0) {
            sb.append(' ').append(progArgs);
        }
        return new ArgumentParser(sb.toString()).getTokenArray();
    }

    private String getVMArguments(final ILaunchConfiguration configuration, final boolean isRemote)
            throws CoreException {
        final String vmArgs = this.fLocalConfDelegate.getVMArguments(configuration);
        final String[] vmArgsArray = new ArgumentParser(vmArgs).getTokenArray();
        if (isRemote) {
            final StringBuilder sb = new StringBuilder();
            for (final String vmArg : vmArgsArray) {
                if (sb.length() > 0) {
                    sb.append(' ');
                }
                if (vmArg.startsWith(JAVA_LIB_PATH_OPT)) {
                    sb.append("-libpath=\"").append(vmArg.substring(JAVA_LIB_PATH_OPT.length())).append('"'); //$NON-NLS-1$
                } else {
                    if (sb.length() > 0) {
                        sb.append(' ');
                    }
                    sb.append("-J").append(vmArg); //$NON-NLS-1$
                }
            }
            return sb.toString();
        } else {
            final String x10LibDir = this.fLocalConfDelegate.getX10DistHostLibDir().getAbsolutePath();
            boolean found = false;
            for (int i = 0; i < vmArgsArray.length; ++i) {
                if (vmArgsArray[i].startsWith(JAVA_LIB_PATH_OPT)) {
                    found = true;
                    final StringBuilder sb = new StringBuilder();
                    final String end = vmArgsArray[i].substring(JAVA_LIB_PATH_OPT.length());
                    sb.append(JAVA_LIB_PATH_OPT);
                    if (end.charAt(0) == '"') {
                        sb.append('"').append(x10LibDir).append(File.pathSeparatorChar)
                                .append(end.substring(1, end.length() - 1)).append('"');
                    } else if (end.charAt(0) == '\'') {
                        sb.append('\'').append(x10LibDir).append(File.pathSeparatorChar)
                                .append(end.substring(1, end.length() - 1)).append('\'');
                    } else {
                        sb.append('"').append(x10LibDir).append(File.pathSeparatorChar).append(end).append('"');
                    }
                    vmArgsArray[i] = sb.toString();
                    break;
                }
            }
            if (found) {
                final StringBuilder sb = new StringBuilder();
                for (final String vmArg : vmArgsArray) {
                    if (sb.length() > 0) {
                        sb.append(' ');
                    }
                    sb.append(vmArg);
                }
                addWinWMArgs(sb);
                return sb.toString();
            } else {
                final StringBuilder sb = new StringBuilder(vmArgs);
                sb.append(' ').append(JAVA_LIB_PATH_OPT).append('"').append(x10LibDir).append('"');
                addWinWMArgs(sb);
                return sb.toString();
            }
        }
    }

    private File getWorkingDir(final ILaunchConfiguration configuration, final IJavaProject javaProject,
            final String mainTypeName) throws CoreException {
        final IPath workDirPath = this.fLocalConfDelegate.getWorkingDirectoryPath(configuration);
        final String mainTypeFileName = mainTypeName.replace('.', File.separatorChar).concat(Constants.CLASS_EXT);
        if (workDirPath == null) {
            for (final IClasspathEntry cpEntry : javaProject.getRawClasspath()) {
                if ((cpEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE)
                        && (cpEntry.getOutputLocation() != null)) {
                    final File dir = getWorkindDir(mainTypeFileName, cpEntry.getOutputLocation(), false);
                    if (dir != null) {
                        return dir;
                    }
                }
            }
            return getWorkindDir(mainTypeFileName, javaProject.getOutputLocation(), true);
        } else {
            return getWorkindDir(mainTypeFileName, workDirPath, true);
        }
    }

    private File getWorkindDir(final String mainTypeFileName, final IPath outputPath,
            final boolean checkOutputFolder) throws CoreException {
        final File outputFolder = getLocalFile(outputPath);
        if ((outputFolder == null) && checkOutputFolder) {
            throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
                    NLS.bind(Messages.XLCD_WorkDirDoNotExist, outputPath)));
        }
        if (containsMainType(outputFolder, mainTypeFileName)) {
            return outputFolder;
        }
        if (checkOutputFolder) {
            throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
                    NLS.bind(Messages.XLCD_NoMainTypeName, outputPath)));
        }
        return null;
    }

    private String getX10DistributionFolder(final ILaunchConfiguration configuration, final boolean isRemote)
            throws CoreException {
        if (isRemote) {
            final String folder = configuration.getAttribute(ATTR_X10_DISTRIBUTION, Constants.EMPTY_STR);
            if (folder.length() == 0) {
                throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.XLCD_NoX10Distrib));
            }
            return folder;
        } else {
            return this.fLocalConfDelegate.getX10DistHostLibDir().getParent();
        }
    }

    private IPath transferJar(final IPath jarPath, final String confName, final String outputFolder)
            throws CoreException {
        final IRemoteServices remoteServices = RemoteServices.getRemoteServices(REMOTE_CONN_SERVICE_ID);
        final IRemoteConnectionManager rmConnManager = remoteServices.getConnectionManager();
        final IRemoteConnection connection = rmConnManager.getConnection(confName);
        final IRemoteFileManager rmFileManager = connection.getFileManager();

        final IPath outputFolderPath = new Path(outputFolder).append(jarPath.lastSegment());
        final IFileStore localJarFS = EFS.getLocalFileSystem().getStore(jarPath);
        final IFileStore remoteJarFS = rmFileManager.getResource(outputFolderPath.toString());
        localJarFS.copy(remoteJarFS, EFS.OVERWRITE, null);

        return outputFolderPath;
    }

    // --- Fields

    private final X10LocalLaunchConfigDelegate fLocalConfDelegate = new X10LocalLaunchConfigDelegate();

    private IPath fExecPath;

    private boolean fIsCygwin;

    private String fWorkspaceDir;

    private ITargetOpHelper fTargetOpHelper;

    private static final String JAVA_LIB_PATH_OPT = "-Djava.library.path="; //$NON-NLS-1$

    private static final String X10RT_IMPL_VMARG = "-DX10RT_IMPL=disabled"; //$NON-NLS-1$

}