blob: 1cb840354903d9489a0376a1f91df85830bbb7b9 [file] [log] [blame]
package org.eclipse.core.internal.boot;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.util.*;
import org.eclipse.core.boot.*;
/**
* Special boot loader class for the Eclipse Platform. This class cannot
* be instantiated; all functionality is provided by static methods.
* <p>
* The Eclipse Platform makes heavy use of Java class loaders for
* loading plug-ins. Even the Platform Core Runtime itself, including
* the <code>Platform</code> class, needs to be loaded by a special
* class loader. The upshot is that a client program (such as a Java main
* program, a servlet) cannot directly reference even the
* <code>Platform</code> class. Instead, a client must use this
* loader class for initializing the platform, invoking functionality
* defined in plug-ins, and shutting down the platform when done.
* </p>
*
* @see org.eclipse.core.runtime.Platform
*/
public final class InternalBootLoader {
private static boolean running = false;
private static boolean starting = false;
private static String[] commandLine;
private static ClassLoader loader = null;
private static String baseLocation = null;
private static String applicationR10 = null; // R1.0 compatibility
private static URL installURL = null;
private static boolean debugRequested = false;
private static boolean usage = false;
private static String devClassPath = null;
private static String debugOptionsFilename = null;
private static Properties options = null;
private static boolean inDevelopmentMode = false;
private static PlatformConfiguration currentPlatformConfiguration = null;
// state for tracking the Platform context (e.g., the OS, Window system, locale, architecture, ...)
private static String nl = null;
private static String ws = null;
private static String os = null;
private static String arch = null;
private static final String[] OS_LIST = { BootLoader.OS_WIN32, BootLoader.OS_LINUX, BootLoader.OS_AIX, BootLoader.OS_SOLARIS, BootLoader.OS_HPUX, BootLoader.OS_QNX };
private static final String PLATFORM_ENTRYPOINT = "org.eclipse.core.internal.runtime.InternalPlatform";
private static final String BOOTNAME = "org.eclipse.core.boot";
private static final String RUNTIMENAME = "org.eclipse.core.runtime";
private static final String PLUGINSDIR = "plugins/";
private static final String LIBRARY = "library";
private static final String EXPORT = "export";
private static final String EXPORT_PUBLIC = "public";
private static final String EXPORT_PROTECTED = "protected";
private static final String META_AREA = ".metadata";
private static final String WORKSPACE = "workspace";
private static final String PLUGIN_PATH = ".plugin-path";
private static final String BOOTDIR = PLUGINSDIR + BOOTNAME + "/";
private static final String RUNTIMEDIR = PLUGINSDIR + RUNTIMENAME + "/";
private static final String OPTIONS = ".options";
// While we recognize the SunOS operating system, we change
// this internally to be Solaris.
private static final String INTERNAL_OS_SUNOS = "SunOS";
// While we recognize the i386 architecture, we change
// this internally to be x86.
private static final String INTERNAL_ARCH_I386 = "i386";
/**
* Execution options for the Runtime plug-in. They are defined here because
* we need to load them into the PlatformClassLoader which is created by the
* boot system. Users should see these options as Runtime options since there
* boot does not figure into normal Platform operation.
*/
private static final String PI_RUNTIME = "org.eclipse.core.runtime";
private static final String OPTION_STARTTIME = PI_RUNTIME + "/starttime";
private static final String OPTION_LOADER_DEBUG = PI_RUNTIME + "/loader/debug";
private static final String OPTION_LOADER_SHOW_CREATE = PI_RUNTIME + "/loader/debug/create";
private static final String OPTION_LOADER_SHOW_ACTIVATE = PI_RUNTIME + "/loader/debug/activateplugin";
private static final String OPTION_LOADER_SHOW_ACTIONS = PI_RUNTIME + "/loader/debug/actions";
private static final String OPTION_LOADER_SHOW_SUCCESS = PI_RUNTIME + "/loader/debug/success";
private static final String OPTION_LOADER_SHOW_FAILURE = PI_RUNTIME + "/loader/debug/failure";
private static final String OPTION_LOADER_FILTER_CLASS = PI_RUNTIME + "/loader/debug/filter/class";
private static final String OPTION_LOADER_FILTER_LOADER = PI_RUNTIME + "/loader/debug/filter/loader";
private static final String OPTION_LOADER_FILTER_RESOURCE = PI_RUNTIME + "/loader/debug/filter/resource";
private static final String OPTION_LOADER_FILTER_NATIVE = PI_RUNTIME + "/loader/debug/filter/native";
private static final String OPTION_URL_DEBUG = PI_RUNTIME+ "/url/debug";
private static final String OPTION_URL_DEBUG_CONNECT = PI_RUNTIME+ "/url/debug/connect";
private static final String OPTION_URL_DEBUG_CACHE_LOOKUP = PI_RUNTIME+ "/url/debug/cachelookup";
private static final String OPTION_URL_DEBUG_CACHE_COPY = PI_RUNTIME+ "/url/debug/cachecopy";
private static final String OPTION_UPDATE_DEBUG = PI_RUNTIME+ "/update/debug";
private static final String OPTION_CONFIGURATION_DEBUG = PI_RUNTIME+ "/config/debug";
// command line arguments
private static final String DEBUG = "-debug";
private static final String PLATFORM = "-platform";
private static final String DATA = "-data";
private static final String DEV = "-dev";
private static final String WS = "-ws";
private static final String OS = "-os";
private static final String ARCH = "-arch";
private static final String NL = "-nl";
private static final String USAGE = "-?";
// Development mode constants
private static final String PLUGIN_JARS = "plugin.jars";
private static final String VA_PROPERTIES = ".va.properties";
private static final String KEY_LIBRARY = "library";
private static final String KEY_EXPORT = "export";
private static final String KEY_PROJECT = "projects";
private static boolean inVAJ;
static {
try {
Class.forName("com.ibm.uvm.lang.ProjectClassLoader");
inVAJ = true;
} catch (Exception e) {
inVAJ = false;
}
}
private static boolean inVAME;
static {
try {
Class.forName("com.ibm.eclipse.core.VAME");
inVAME = true;
} catch (Exception e) {
inVAME = false;
}
}
/**
* Private constructor to block instance creation.
*/
private InternalBootLoader() {
}
private static void assertNotRunning() {
if (running)
throw new RuntimeException("The Platform must not be running");
}
private static void assertRunning() {
if (!running)
throw new RuntimeException("The Platform is not running");
}
/**
* Configure the class loader for the runtime plug-in.
*/
private static PlatformClassLoader configurePlatformLoader() {
Object[] loadPath = getPlatformClassLoaderPath();
URL base = null;
try {
base = new URL(PlatformURLBaseConnection.PLATFORM_URL_STRING+RUNTIMEDIR);
} catch (MalformedURLException e) {
}
return new PlatformClassLoader((URL[]) loadPath[0], (URLContentFilter[]) loadPath[1], InternalBootLoader.class.getClassLoader(), base);
}
/**
* @see BootLoader
*/
public static boolean containsSavedPlatform(String location) {
return new File(location + "/" + META_AREA).exists();
}
/**
* convert a list of comma-separated tokens into an array
*/
private static String[] getArrayFromList(String prop) {
if (prop == null || prop.trim().equals(""))
return new String[0];
Vector list = new Vector();
StringTokenizer tokens = new StringTokenizer(prop, ",");
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim();
if (!token.equals(""))
list.addElement(token);
}
return list.isEmpty() ? new String[0] : (String[]) list.toArray(new String[0]);
}
private static boolean getBooleanOption(String option, boolean defaultValue) {
String optionValue = options.getProperty(option);
return (optionValue == null) ? defaultValue : optionValue.equalsIgnoreCase("true");
}
/**
* @see BootLoader#getCommandLineArgs
*/
public static String[] getCommandLineArgs() {
return commandLine;
}
/**
* @see BootLoader
*/
public static PlatformConfiguration getCurrentPlatformConfiguration() {
return PlatformConfiguration.getCurrent();
}
/**
* @see BootLoader
*/
public static URL getInstallURL() {
if (installURL != null)
return installURL;
// Get the location of this class and compute the install location.
// this involves striping off last element (jar or directory) and adjusting
// for VAJ/VAME peculiarities.
URL url = InternalBootLoader.class.getProtectionDomain().getCodeSource().getLocation();
String path = url.getFile();
if (path.endsWith("/"))
path = path.substring(0, path.length() - 1);
int ix = path.lastIndexOf('/');
if ((inVAJ || inVAME))
// in VAJ or VAME strip off one segment (the boot project). Be sure to leave a trailing /
path = path.substring(0, ix + 1);
else {
// in jdk ... strip off boot jar/bin, boot plugin and plugins dir. Be sure to leave a trailing /
path = path.substring(0, ix);
ix = path.lastIndexOf('/');
path = path.substring(0, ix);
ix = path.lastIndexOf('/');
path = path.substring(0, ix + 1);
}
try {
if (url.getProtocol().equals("jar"))
installURL = new URL(path);
else
installURL = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
if (debugRequested)
System.out.println("Install URL: "+installURL.toExternalForm());
} catch (MalformedURLException e) {
throw new RuntimeException("Fatal Error: Unable to determine platform installation URL "+e);
}
return installURL;
}
private static String[] getListOption(String option) {
String filter = options.getProperty(option);
if (filter == null)
return new String[0];
List result = new ArrayList(5);
StringTokenizer tokenizer = new StringTokenizer(filter, " ,\t\n\r\f");
while (tokenizer.hasMoreTokens())
result.add(tokenizer.nextToken());
return (String[]) result.toArray(new String[result.size()]);
}
/**
* @see BootLoader
*/
public static String getOSArch() {
return arch;
}
/**
* @see BootLoader
*/
public static String getNL() {
return nl;
}
/**
* @see BootLoader
*/
public static String getOS() {
return os;
}
/**
* @see BootLoader
*/
public static PlatformConfiguration getPlatformConfiguration(URL url) throws IOException {
return new PlatformConfiguration(url);
}
private static Object[] getPlatformClassLoaderPath() {
PlatformConfiguration config = getCurrentPlatformConfiguration();
String execBase = config.getPluginPath(RUNTIMENAME).toExternalForm();
if (execBase == null)
execBase = getInstallURL() + RUNTIMEDIR;
String devBase = null;
Properties jarDefinitions = null;
if (InternalBootLoader.inVAJ || InternalBootLoader.inVAME) {
devBase = getInstallURL().toExternalForm();
jarDefinitions = loadJarDefinitions();
} else
devBase = execBase;
// build a list alternating lib spec and export spec
ArrayList libSpecs = new ArrayList(5);
String[] exportAll = new String[] { "*" };
// add in any development mode class paths and the export all filter
if (DelegatingURLClassLoader.devClassPath != null) {
String[] specs = getArrayFromList(DelegatingURLClassLoader.devClassPath);
// convert dev class path into url strings
for (int j = 0; j < specs.length; j++) {
libSpecs.add(devBase + specs[j] + "/");
libSpecs.add(exportAll);
}
}
ArrayList list = new ArrayList(5);
list.add("runtime.jar");
list.add(exportAll);
// add in the class path entries spec'd in the config. If in development mode,
// add the entries from the plugin.jars first.
for (Iterator i = list.iterator(); i.hasNext();) {
String library = (String) i.next();
String[] filters = (String[]) i.next();
// check for jar definitions
if (jarDefinitions != null) {
String key = library.substring(library.lastIndexOf('/') + 1);
String[] specs = getArrayFromList(jarDefinitions.getProperty(key));
for (int j = 0; j < specs.length; j++) {
libSpecs.add(devBase + specs[j] + "/");
libSpecs.add(filters);
}
}
// convert plugin.xml library entries to url strings if running in JDK
if (!(InternalBootLoader.inVAJ || InternalBootLoader.inVAME)) {
String libSpec = execBase + library.replace(File.separatorChar, '/');
if (!libSpec.endsWith("/")) {
if (libSpec.startsWith(PlatformURLHandler.PROTOCOL + PlatformURLHandler.PROTOCOL_SEPARATOR))
libSpec += PlatformURLHandler.JAR_SEPARATOR;
else
libSpec = PlatformURLHandler.JAR + PlatformURLHandler.PROTOCOL_SEPARATOR + libSpec + PlatformURLHandler.JAR_SEPARATOR;
}
libSpecs.add(libSpec);
libSpecs.add(filters);
}
}
// create path entries for libraries
ArrayList urls = new ArrayList(5);
ArrayList cfs = new ArrayList(5);
for (Iterator it = libSpecs.iterator(); it.hasNext();) {
try {
urls.add(new URL((String) it.next()));
cfs.add(new URLContentFilter((String[]) it.next()));
} catch (MalformedURLException e) {
// skip bad URLs
}
}
Object[] result = new Object[2];
result[0] = urls.toArray(new URL[urls.size()]);
result[1] = cfs.toArray(new URLContentFilter[cfs.size()]);
return result;
}
/**
* @see BootLoader
*/
/*
* This method is retained for R1.0 compatibility because it is defined as API.
* It's function matches the API description (returns <code>null</code> when
* argument URL is <code>null</code> or cannot be read).
*/
public static URL[] getPluginPath(URL pluginPathLocation/*R1.0 compatibility*/) {
InputStream input = null;
// first try and see if the given plugin path location exists.
if (pluginPathLocation == null)
return null;
try {
input = pluginPathLocation.openStream();
} catch (IOException e) {
}
// if the given path was null or did not exist, look for a plugin path
// definition in the install location.
if (input == null)
try {
URL url = new URL(PlatformURLBaseConnection.PLATFORM_URL_STRING + PLUGIN_PATH);
input = url.openStream();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
// nothing was found at the supplied location or in the install location
if (input == null)
return null;
// if we found a plugin path definition somewhere so read it and close the location.
URL[] result = null;
try {
try {
result = readPluginPath(input);
} finally {
input.close();
}
} catch (IOException e) {
}
return result;
}
private static URL[] getPluginPathVa(URL[] pluginPath) {
Vector result = new Vector(Arrays.asList(pluginPath));
if (inVAME) {
// check for projects with plugins on Java classpath
String classpath = System.getProperty("java.class.path");
StringTokenizer paths = new StringTokenizer(classpath, File.pathSeparator);
while (paths.hasMoreTokens()) {
String curr = (String) paths.nextToken();
if (!curr.endsWith(File.separator))
curr += File.separator;
curr += "plugins" + File.separator;
File dir = new File(curr);
if (dir.isDirectory()) {
try {
result.add(dir.toURL());
} catch (MalformedURLException e) {
}
}
}
} else
if (inVAJ /*disabled*/
&& false) {
// check for projects with plugins in project_resources
File pr = new File(getInstallURL().getFile());
String[] projects = ((projects = pr.list()) == null) ? new String[0] : projects;
for (int i = 0; i < projects.length; i++) {
File dir = new File(pr, projects[i] + File.separator + "plugins");
if (dir.isDirectory()) {
try {
result.add(dir.toURL());
} catch (MalformedURLException e) {
}
}
}
}
// if there are no new entries, return original plugin path. Otherwise, return the new path
if (pluginPath.length == result.size())
return pluginPath;
else
return (URL[]) result.toArray(new URL[result.size()]);
}
/**
* @see BootLoader
*/
public static IPlatformRunnable getRunnable(String applicationName) throws Exception {
assertRunning();
Class platform = loader.loadClass(PLATFORM_ENTRYPOINT);
Method method = platform.getDeclaredMethod("loaderGetRunnable", new Class[] {String.class});
try {
return (IPlatformRunnable) method.invoke(platform, new Object[] {applicationName});
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof Error)
throw (Error) e.getTargetException();
else
throw e;
}
}
/**
* @see BootLoader
*/
public static IPlatformRunnable getRunnable(String pluginId, String className, Object args) throws Exception {
assertRunning();
Class platform = loader.loadClass(PLATFORM_ENTRYPOINT);
Method method = platform.getDeclaredMethod("loaderGetRunnable", new Class[] {String.class, String.class, Object.class});
try {
return (IPlatformRunnable) method.invoke(platform, new Object[] {pluginId, className, args});
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof Error)
throw (Error) e.getTargetException();
else
throw e;
}
}
/**
* @see BootLoader
*/
public static String getWS() {
return ws;
}
/**
* @see BootLoader
*/
public static boolean inDebugMode() {
return debugRequested;
}
/**
* @see BootLoader
*/
public static boolean inDevelopmentMode() {
return inDevelopmentMode || inVAJ || inVAME;
}
private static String[] initialize(URL pluginPathLocation/*R1.0 compatibility*/, String location, String[] args) throws Exception {
if (running)
throw new RuntimeException("The platform is already running");
baseLocation = location;
String[] appArgs = processCommandLine(args);
// Do setupSystemContext() ASAP after processCommandLine
setupSystemContext();
// setup the devClassPath if any
DelegatingURLClassLoader.devClassPath = devClassPath;
// if a platform location was not found in the arguments, compute one.
if (baseLocation == null) {
if (inVAJ || inVAME) {
// In VAJ, set user.dir to be <code>eclipse</code> in the parent of the install
// directory. This typically makes the platform working directory:
// .../ide/eclipse
String dir = new File(new File(getInstallURL().getFile()).getParent(), "eclipse").getAbsolutePath();
System.setProperty("user.dir", dir);
baseLocation = dir;
} else {
// otherwise, use user.dir. If user.dir overlaps with the install dir, then make the
// location be a workspace subdir of the install location.
baseLocation = System.getProperty("user.dir");
URL installURL = resolve(getInstallURL());
String installLocation = new File(installURL.getFile()).getAbsolutePath();
if (baseLocation.equals(installLocation))
baseLocation = new File(installLocation, WORKSPACE).getAbsolutePath();
}
}
// load any debug options
loadOptions();
// initialize eclipse URL handling
PlatformURLHandlerFactory.startup(baseLocation + File.separator + META_AREA);
PlatformURLBaseConnection.startup(getInstallURL()); // past this point we can use eclipse:/platform/ URLs
// load platform configuration and consume configuration-related arguments (must call after URL handler initialization)
appArgs = PlatformConfiguration.startup(appArgs, pluginPathLocation/*R1.0 compatibility*/, applicationR10/*R1.0 compatibility*/);
// create and configure platform class loader
loader = configurePlatformLoader();
return appArgs;
}
/**
* Returns the complete plugin path.
* If in development mode, the returned value may have additional VA
* values added.
*/
private static URL[] internalGetPluginPath() {
URL[] result = getCurrentPlatformConfiguration().getPluginPath();
// augment with additional VA entries if in development mode.
if (inDevelopmentMode())
result = getPluginPathVa(result);
return result;
}
/**
* @see BootLoader
*/
public static boolean isRunning() {
return running;
}
public static boolean isStarting() {
return starting;
}
private static Properties loadJarDefinitions() {
if (!inDevelopmentMode())
return null;
Properties result = null;
InputStream is;
try {
result = new Properties();
URL props = new URL(getInstallURL(), PLUGINSDIR + RUNTIMENAME + "/" + PLUGIN_JARS);
is = props.openStream();
try {
result.load(is);
return result;
} finally {
is.close();
}
} catch (IOException e) {
result = null;
}
return result;
}
private static void loadOptions() {
// if no debug option was specified, don't even bother to try.
// Must ensure that the options slot is null as this is the signal to the
// platform that debugging is not enabled.
if (!debugRequested) {
options = null;
return;
}
options = new Properties();
URL optionsFile;
if (debugOptionsFilename == null)
debugOptionsFilename = getInstallURL().toExternalForm() + OPTIONS;
try {
optionsFile = new URL(debugOptionsFilename);
} catch (MalformedURLException e) {
System.out.println("Unable to construct URL for options file: " + debugOptionsFilename);
e.printStackTrace(System.out);
return;
}
System.out.println("Debug-Options: " + debugOptionsFilename);
try {
InputStream input = optionsFile.openStream();
try {
options.load(input);
} finally {
input.close();
}
} catch (FileNotFoundException e) {
// Its not an error to not find the options file
} catch (IOException e) {
System.out.println("Could not parse the options file: " + optionsFile);
e.printStackTrace(System.out);
}
// trim off all the blanks since properties files don't do that.
for (Iterator i = options.keySet().iterator(); i.hasNext();) {
Object key = i.next();
options.put(key, ((String) options.get(key)).trim());
}
InternalBootLoader.setupOptions();
}
private static String[] processCommandLine(String[] args) throws Exception {
int[] configArgs = new int[100];
configArgs[0] = -1; // need to initialize the first element to something that could not be an index.
int configArgIndex = 0;
for (int i = 0; i < args.length; i++) {
boolean found = false;
// check for args without parameters (i.e., a flag arg)
// check if debug should be enabled for the entire platform
// If this is the last arg or there is a following arg (i.e., arg+1 has a leading -),
// simply enable debug. Otherwise, assume that that the following arg is
// actually the filename of an options file. This will be processed below.
if (args[i].equalsIgnoreCase(DEBUG) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) {
found = true;
debugRequested = true;
}
// check if development mode should be enabled for the entire platform
// If this is the last arg or there is a following arg (i.e., arg+1 has a leading -),
// simply enable development mode. Otherwise, assume that that the following arg is
// actually some additional development time class path entries. This will be processed below.
if (args[i].equalsIgnoreCase(DEV) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) {
inDevelopmentMode = true;
found = true;
continue;
}
// look for the usage flag
if (args[i].equalsIgnoreCase(USAGE)) {
usage = true;
found = true;
}
if (found) {
configArgs[configArgIndex++] = i;
continue;
}
// check for args with parameters. If we are at the last argument or if the next one
// has a '-' as the first character, then we can't have an arg with a parm so continue.
if (i == args.length - 1 || args[i + 1].startsWith("-")) {
continue;
}
String arg = args[++i];
// look for the debug options file location.
if (args[i - 1].equalsIgnoreCase(DEBUG)) {
found = true;
debugRequested = true;
debugOptionsFilename = arg;
}
// look for the development mode and class path entries.
if (args[i - 1].equalsIgnoreCase(DEV)) {
inDevelopmentMode = true;
devClassPath = arg;
found = true;
continue;
}
// look for the platform location. Only set it if not already set. This
// preserves the value set in the startup() parameter. Be sure however
// to consume the command-line argument.
if (args[i - 1].equalsIgnoreCase(PLATFORM) || args[i - 1].equalsIgnoreCase(DATA)) {
found = true;
if (baseLocation == null)
baseLocation = arg;
}
// look for the window system.
if (args[i - 1].equalsIgnoreCase(WS)) {
found = true;
ws = arg;
}
// look for the operating system
if (args[i - 1].equalsIgnoreCase(OS)) {
found = true;
os = arg;
}
// look for the system architecture
if (args[i - 1].equalsIgnoreCase(ARCH)) {
found = true;
arch = arg;
}
// look for the system architecture
if (args[i - 1].equalsIgnoreCase(NL)) {
found = true;
nl = arg;
}
// done checking for args. Remember where an arg was found
if (found) {
configArgs[configArgIndex++] = i - 1;
configArgs[configArgIndex++] = i;
}
}
// remove all the arguments consumed by this argument parsing
if (configArgIndex == 0)
return args;
String[] passThruArgs = new String[args.length - configArgIndex];
configArgIndex = 0;
int j = 0;
for (int i = 0; i < args.length; i++) {
if (i == configArgs[configArgIndex])
configArgIndex++;
else
passThruArgs[j++] = args[i];
}
return passThruArgs;
}
private static URL[] readPluginPath(InputStream input) {
Properties ini = new Properties();
try {
ini.load(input);
} catch (IOException e) {
return null;
}
Vector result = new Vector(5);
for (Enumeration groups = ini.propertyNames(); groups.hasMoreElements();) {
String group = (String) groups.nextElement();
for (StringTokenizer entries = new StringTokenizer(ini.getProperty(group), ";"); entries.hasMoreElements();) {
String entry = (String) entries.nextElement();
if (!entry.equals(""))
try {
result.addElement(new URL(entry));
} catch (MalformedURLException e) {
}
}
}
return (URL[]) result.toArray(new URL[result.size()]);
}
public static URL resolve(URL url) throws IOException {
if (!url.getProtocol().equals(PlatformURLHandler.PROTOCOL))
return url;
URLConnection connection = url.openConnection();
if (connection instanceof PlatformURLConnection)
return ((PlatformURLConnection) connection).getResolvedURL();
else
return url;
}
/**
* @see BootLoader
*/
public static Object run(String applicationName/*R1.0 compatibility*/, URL pluginPathLocation/*R1.0 compatibility*/, String location, String[] args) throws Exception {
Object result = null;
applicationR10 = applicationName; // for R1.0 compatibility
String[] applicationArgs = null;
try {
applicationArgs = startup(pluginPathLocation, location, args);
} catch (Exception e) {
throw e;
}
String application = getCurrentPlatformConfiguration().getApplicationIdentifier();
IPlatformRunnable runnable = getRunnable(application);
if (runnable == null)
throw new IllegalArgumentException("Application not found: " + application);
try {
result = runnable.run(applicationArgs);
} catch (Throwable e) {
e.printStackTrace();
throw e;
} finally {
shutdown();
return result;
}
}
/**
* Setup the debug flags for the given debug options. This method will likely
* be called twice. Once when loading the options file from the command
* line or install dir and then again when we have loaded options from the
* specific platform metaarea.
*/
public static void setupOptions() {
// if no debug option was specified, don't even bother to try.
// Must ensure that the options slot is null as this is the signal to the
// platform that debugging is not enabled.
if (!debugRequested)
return;
options.put(OPTION_STARTTIME, Long.toString(System.currentTimeMillis()));
DelegatingURLClassLoader.DEBUG = getBooleanOption(OPTION_LOADER_DEBUG, false);
DelegatingURLClassLoader.DEBUG_SHOW_CREATE = getBooleanOption(OPTION_LOADER_SHOW_CREATE, true);
DelegatingURLClassLoader.DEBUG_SHOW_ACTIVATE = getBooleanOption(OPTION_LOADER_SHOW_ACTIVATE, true);
DelegatingURLClassLoader.DEBUG_SHOW_ACTIONS = getBooleanOption(OPTION_LOADER_SHOW_ACTIONS, true);
DelegatingURLClassLoader.DEBUG_SHOW_SUCCESS = getBooleanOption(OPTION_LOADER_SHOW_SUCCESS, true);
DelegatingURLClassLoader.DEBUG_SHOW_FAILURE = getBooleanOption(OPTION_LOADER_SHOW_FAILURE, true);
DelegatingURLClassLoader.DEBUG_FILTER_CLASS = getListOption(OPTION_LOADER_FILTER_CLASS);
DelegatingURLClassLoader.DEBUG_FILTER_LOADER = getListOption(OPTION_LOADER_FILTER_LOADER);
DelegatingURLClassLoader.DEBUG_FILTER_RESOURCE = getListOption(OPTION_LOADER_FILTER_RESOURCE);
DelegatingURLClassLoader.DEBUG_FILTER_NATIVE = getListOption(OPTION_LOADER_FILTER_NATIVE);
PlatformURLConnection.DEBUG = getBooleanOption(OPTION_URL_DEBUG, false);
PlatformURLConnection.DEBUG_CONNECT = getBooleanOption(OPTION_URL_DEBUG_CONNECT, true);
PlatformURLConnection.DEBUG_CACHE_LOOKUP = getBooleanOption(OPTION_URL_DEBUG_CACHE_LOOKUP, true);
PlatformURLConnection.DEBUG_CACHE_COPY = getBooleanOption(OPTION_URL_DEBUG_CACHE_COPY, true);
PlatformConfiguration.DEBUG = getBooleanOption(OPTION_CONFIGURATION_DEBUG,false);
}
/**
* Initializes the execution context for this run of the platform. The context
* includes information about the locale, operating system and window system.
*/
private static void setupSystemContext() {
if (nl == null)
nl = Locale.getDefault().toString();
if (os == null) {
String name = System.getProperty("os.name");
for (int i = 0; i < OS_LIST.length; i++)
if (name.regionMatches(true, 0, OS_LIST[i], 0, 3))
os = OS_LIST[i];
// EXCEPTION: All mappings of SunOS convert to Solaris
if (os == null)
os = name.equalsIgnoreCase(INTERNAL_OS_SUNOS) ? BootLoader.OS_SOLARIS : BootLoader.OS_UNKNOWN;
}
if (ws == null)
// setup default values for known OSes if nothing was specified
if (os.equals(BootLoader.OS_WIN32))
ws = BootLoader.WS_WIN32;
else
if (os.equals(BootLoader.OS_LINUX))
ws = BootLoader.WS_MOTIF;
else
ws = BootLoader.WS_UNKNOWN;
if (arch == null) {
String name = System.getProperty("os.arch");
// Map i386 architecture to x86
arch = name.equalsIgnoreCase(INTERNAL_ARCH_I386) ? BootLoader.ARCH_X86 : name;
}
}
/**
* @see BootLoader
*/
public static void shutdown() throws Exception {
assertRunning();
// no matter what happens, record that its no longer running
running = false;
Class platform = loader.loadClass(PLATFORM_ENTRYPOINT);
Method method = platform.getDeclaredMethod("loaderShutdown", new Class[0]);
try {
method.invoke(platform, new Object[0]);
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof Error)
throw (Error) e.getTargetException();
else
throw e;
} finally {
PlatformURLHandlerFactory.shutdown();
PlatformConfiguration.shutdown();
loader = null;
}
}
/**
* @see BootLoader
*/
public static String[] startup(URL pluginPathLocation/*R1.0 compatibility*/, String location, String[] args) throws Exception {
assertNotRunning();
starting = true;
commandLine = args;
String[] applicationArgs = initialize(pluginPathLocation, location, args);
Class platform = loader.loadClass(PLATFORM_ENTRYPOINT);
Method method = platform.getDeclaredMethod("loaderStartup", new Class[] { URL[].class, String.class, Properties.class, String[].class });
try {
URL[] pluginPath = internalGetPluginPath();
method.invoke(platform, new Object[] { pluginPath, baseLocation, options, args });
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof Error)
throw (Error) e.getTargetException();
else
throw e;
}
// only record the platform as running if everything went swimmingly
running = true;
starting = false;
return applicationArgs;
}
}