blob: be1fde2a9648b6b93c3651f35b06db61f8735d52 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.tests.session;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.tests.session.ProcessController.TimeOutException;
/*
* Implementation note: vmArguments and eclipseArguments are HashMap (and not
* just Map) because we are interested in features that are specific to HashMap
* (is Cloneable, allows null values).
*/
public class Setup implements Cloneable {
public static final String APPLICATION = "application";
private static final String ARCH = "arch";
public static final String CONFIGURATION = "configuration";
public static final String DATA = "data";
public static final String DEBUG = "debug";
private static final int DEFAULT_TIMEOUT = 0;
public static final String DEV = "dev";
public static final String INSTALL = "install";
private static final String NL = "nl";
private static final String OS = "os";
public static final String VM = "vm";
private static final String WS = "ws";
private static final String PROP_BOOT_DELEGATION = "org.osgi.framework.bootdelegation";
public static String getDefaultArchOption() {
return System.getProperty(InternalPlatform.PROP_ARCH);
}
public static String getDefaultConfiguration() {
return System.getProperty(InternalPlatform.PROP_CONFIG_AREA);
}
public static String getDefaultDebugOption() {
return System.getProperty(InternalPlatform.PROP_DEBUG);
}
public static String getDefaultDevOption() {
return System.getProperty(InternalPlatform.PROP_DEV);
}
public static String getDefaultInstallLocation() {
String currentInstall = System.getProperty(InternalPlatform.PROP_INSTALL_AREA);
if (currentInstall != null) {
try {
return new URI(currentInstall).getPath();
} catch (URISyntaxException e) {
// nothing to be done
}
}
return null;
}
public static String getDefaultInstanceLocation() {
return new File(System.getProperty("java.io.tmpdir"), "workspace").toString();
}
public static String getDefaultNLOption() {
return System.getProperty(InternalPlatform.PROP_NL);
}
public static String getDefaultOSOption() {
return System.getProperty(InternalPlatform.PROP_OS);
}
/**
* Creates a setup containing default settings. The default settings will
* vary depending on the running environment.
*
* @see #getDefaultConfiguration()
* @see #getDefaultDebugOption()
* @see #getDefaultDevOption()
* @see #getDefaultInstallLocation()
* @see #getDefaultInstanceLocation()
* @see #getDefaultVMLocation()
* @return a setup with all default settings
*/
static Setup getDefaultSetup(SetupManager manager) {
Setup defaultSetup = new Setup(manager);
// see bug 93343
defaultSetup.setSystemProperty(PROP_BOOT_DELEGATION, System.getProperty(PROP_BOOT_DELEGATION));
defaultSetup.setSystemProperty(InternalPlatform.PROP_CONSOLE_LOG, System.getProperty(InternalPlatform.PROP_CONSOLE_LOG, "true"));
if (Setup.getDefaultVMLocation() != null) {
defaultSetup.setEclipseArgument(VM, Setup.getDefaultVMLocation());
}
if (Setup.getDefaultConfiguration() != null) {
defaultSetup.setEclipseArgument(CONFIGURATION, Setup.getDefaultConfiguration());
}
if (Setup.getDefaultDebugOption() != null) {
defaultSetup.setSystemProperty(InternalPlatform.PROP_DEBUG, Setup.getDefaultDebugOption());
}
if (Setup.getDefaultDevOption() != null) {
defaultSetup.setEclipseArgument(DEV, Setup.getDefaultDevOption());
}
if (Setup.getDefaultInstallLocation() != null) {
defaultSetup.setEclipseArgument(INSTALL, Setup.getDefaultInstallLocation());
}
if (Setup.getDefaultInstanceLocation() != null) {
defaultSetup.setEclipseArgument(DATA, Setup.getDefaultInstanceLocation());
}
if (Setup.getDefaultArchOption() != null) {
defaultSetup.setEclipseArgument(ARCH, Setup.getDefaultArchOption());
}
String defaultOS = Setup.getDefaultOSOption();
if (defaultOS != null) {
defaultSetup.setEclipseArgument(OS, defaultOS);
if (Platform.OS_MACOSX.equals(defaultOS)) {
// see bug 98508
defaultSetup.setVMArgument("XstartOnFirstThread", "");
}
}
if (Setup.getDefaultWSOption() != null) {
defaultSetup.setEclipseArgument(WS, Setup.getDefaultWSOption());
}
if (Setup.getDefaultNLOption() != null) {
defaultSetup.setEclipseArgument(NL, Setup.getDefaultNLOption());
}
defaultSetup.setTimeout(DEFAULT_TIMEOUT);
return defaultSetup;
}
public static String getDefaultVMLocation() {
String javaVM = System.getProperty("eclipse.vm");
if (javaVM != null) {
return javaVM;
}
javaVM = System.getProperty("java.home");
if (javaVM == null) {
return null;
}
// XXX: this is a hack and will not work with some VMs...
return new File(new File(javaVM, "bin"), "java").toString();
}
public static String getDefaultWSOption() {
return System.getProperty(InternalPlatform.PROP_WS);
}
private String[] baseSetups;
private HashMap<String, String> eclipseArguments = new HashMap<>();
private String id;
private SetupManager manager;
private String name;
private String[] requiredSets;
private HashMap<String, String> systemProperties = new HashMap<>();
private int timeout;
private HashMap<String, String> vmArguments = new HashMap<>();
public Setup(SetupManager manager) {
this.manager = manager;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#clone()
*/
@Override
public Object clone() {
Setup clone = null;
try {
clone = (Setup) super.clone();
// ensure we don't end up sharing references to mutable objects
clone.eclipseArguments = new HashMap<>(eclipseArguments);
clone.vmArguments = new HashMap<>(vmArguments);
clone.systemProperties = new HashMap<>(systemProperties);
} catch (CloneNotSupportedException e) {
// just does not happen: we do implement Cloneable
}
return clone;
}
private void fillClassPath(List<String> params) {
if (vmArguments.containsKey("cp") || vmArguments.containsKey("classpath")) {
// classpath was specified as VM argument
return;
}
String inheritedClassPath = System.getProperty("java.class.path");
if (inheritedClassPath == null) {
String installLocation = getEclipseArgument(INSTALL);
if (installLocation == null) {
throw new IllegalStateException("Classpath could not be computed");
}
inheritedClassPath = new File(installLocation, "startup.jar").toString();
}
params.add("-classpath");
params.add(inheritedClassPath);
}
public void fillCommandLine(List<String> commandLine) {
String vmLocation = getEclipseArgument(VM);
if (vmLocation == null) {
throw new IllegalStateException("VM location not set");
}
commandLine.add(vmLocation);
fillClassPath(commandLine);
fillVMArgs(commandLine);
fillSystemProperties(commandLine);
commandLine.add("org.eclipse.core.launcher.Main");
fillEclipseArgs(commandLine);
}
private void fillEclipseArgs(List<String> params) {
for (Entry<String, String> entry : eclipseArguments.entrySet()) {
params.add('-' + entry.getKey());
if (entry.getValue() != null && entry.getValue().length() > 0) {
params.add(entry.getValue());
}
}
}
private void fillSystemProperties(List<String> command) {
for (Entry<String, String> entry : systemProperties.entrySet()) {
// null-valued properties are ignored
if (entry.getValue() == null) {
continue;
}
StringBuilder property = new StringBuilder("-D");
property.append(entry.getKey());
if (entry.getValue().length() > 0) {
property.append('=');
property.append(entry.getValue());
}
command.add(property.toString());
}
}
private void fillVMArgs(List<String> params) {
for (Entry<String, String> entry : vmArguments.entrySet()) {
params.add('-' + entry.getKey());
if (entry.getValue() != null && entry.getValue().length() > 0) {
params.add(entry.getValue());
}
}
}
String[] getBaseSetups() {
return baseSetups;
}
public String[] getCommandLine() {
List<String> commandLine = new ArrayList<>();
fillCommandLine(commandLine);
return commandLine.toArray(new String[commandLine.size()]);
}
public String getEclipseArgsLine() {
List<String> eclipseArgs = new ArrayList<>();
fillEclipseArgs(eclipseArgs);
StringBuilder result = new StringBuilder();
for (String string : eclipseArgs) {
result.append(string);
result.append(' ');
}
return result.length() > 0 ? result.substring(0, result.length() - 1) : null;
}
public String getEclipseArgument(String key) {
return eclipseArguments.get(key);
}
public Map<String, String> getEclipseArguments() {
return new HashMap<>(eclipseArguments);
}
public String getId() {
return id;
}
public String getName() {
return name;
}
String[] getRequiredSets() {
return requiredSets;
}
public Map<String, String> getSystemProperties() {
return new HashMap<>(systemProperties);
}
public String getSystemPropertiesLine() {
List<String> sysProperties = new ArrayList<>();
fillSystemProperties(sysProperties);
StringBuilder result = new StringBuilder();
for (String string : sysProperties) {
result.append(string);
result.append(' ');
}
return result.length() > 0 ? result.substring(0, result.length() - 1) : null;
}
public int getTimeout() {
return timeout;
}
public String getVMArgsLine() {
List<String> vmArgs = new ArrayList<>();
fillVMArgs(vmArgs);
StringBuilder result = new StringBuilder();
for (String string : vmArgs) {
result.append(string);
result.append(' ');
}
return result.length() > 0 ? result.substring(0, result.length() - 1) : null;
}
public String getVMArgument(String key) {
return vmArguments.get(key);
}
public Map<String, String> getVMArguments() {
return new HashMap<>(vmArguments);
}
public boolean isA(String baseOptionSet) {
if (baseOptionSet.equals(id)) {
return true;
}
if (baseSetups == null) {
return false;
}
for (String baseSetup : baseSetups) {
Setup base = manager.getSetup(baseSetup);
if (base != null && base.isA(baseOptionSet)) {
return true;
}
}
return false;
}
public boolean isSatisfied(String[] availableSets) {
for (String requiredSet : requiredSets) {
boolean satisfied = false;
for (int j = 0; !satisfied && j < availableSets.length; j++) {
Setup available = manager.getSetup(availableSets[j]);
if (available != null && available.isA(requiredSet)) {
satisfied = true;
}
}
if (!satisfied) {
return false;
}
}
return true;
}
public void merge(Setup variation) {
eclipseArguments.putAll(variation.eclipseArguments);
vmArguments.putAll(variation.vmArguments);
systemProperties.putAll(variation.systemProperties);
}
public int run() throws InterruptedException, IOException, TimeOutException {
if (SetupManager.inDebugMode()) {
System.out.print("Command line: ");
System.out.println(toCommandLineString());
}
ProcessController process = new ProcessController(getTimeout(), getCommandLine());
process.forwardErrorOutput(System.err);
process.forwardOutput(System.out);
//if necessary to interact with the spawned process, this would have
// to be done
//process.forwardInput(System.in);
return process.execute();
}
void setBaseSetups(String[] baseSetups) {
this.baseSetups = baseSetups;
}
public void setEclipseArgument(String key, String value) {
if (value == null) {
eclipseArguments.remove(key);
} else {
eclipseArguments.put(key, value);
}
}
public void setEclipseArguments(Map<String, String> newArguments) {
if (newArguments == null) {
eclipseArguments.clear();
} else {
eclipseArguments.putAll(newArguments);
}
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
void setRequiredSets(String[] requiredSets) {
this.requiredSets = requiredSets;
}
public void setSystemProperties(Map<String, String> newProperties) {
if (newProperties == null) {
systemProperties.clear();
} else {
systemProperties.putAll(newProperties);
}
}
public void setSystemProperty(String key, String value) {
if (value == null) {
systemProperties.remove(key);
} else {
systemProperties.put(key, value);
}
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public void setVMArgument(String key, String value) {
if (value == null) {
vmArguments.remove(key);
} else {
vmArguments.put(key, value);
}
}
public void setVMArguments(Map<String, String> newArguments) {
if (newArguments == null) {
vmArguments.clear();
} else {
vmArguments.putAll(newArguments);
}
}
public String toCommandLineString() {
String[] commandLine = getCommandLine();
StringBuilder result = new StringBuilder();
result.append("[\n");
for (String element : commandLine) {
result.append('\t');
result.append(element);
result.append('\n');
}
result.append(']');
return result.toString();
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
if (id != null || name != null) {
if (id != null) {
result.append(id);
result.append(' ');
}
if (name != null) {
if (name != null) {
result.append("(");
result.append(name);
result.append(") ");
}
}
result.append("= ");
}
result.append("[");
result.append("\n\teclipseArguments: ");
result.append(eclipseArguments);
result.append("\n\tvmArguments: ");
result.append(vmArguments);
result.append("\n\tsystemProperties: ");
result.append(systemProperties);
result.append("\n]");
return result.toString();
}
}