blob: 549f5888b12843b3db6da2769b5f2572fde98040 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.launcher;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.jar.JarFile;
/**
* The launcher ot start eclipse using webstart.
* To use this launcher, the client must accept to give all security permissions.
*/
//The bundles are discovered by finding all the jars on the classpath. Then they are added with their full path to the osgi.bundles list.
public class WebStartMain extends Main {
private static final String PROP_WEBSTART_AUTOMATIC_INSTALLATION = "eclipse.webstart.automaticInstallation"; //$NON-NLS-1$
private static final String DEFAULT_OSGI_BUNDLES = "org.eclipse.core.runtime@2:start"; //$NON-NLS-1$
private static final String PROP_OSGI_BUNDLES = "osgi.bundles"; //$NON-NLS-1$
//List all the jars that are on the classpath
private String[] allJars = null;
//The list all the bundles that have been to the bundle list
private Set onTheBundleList = new HashSet();
public static void main(String[] args) {
System.setSecurityManager(null); //Hack so that when the classloader loading the fwk is created we don't have funny permissions. This should be revisited.
int result = new WebStartMain().run(args);
System.exit(result);
}
private void setDefaultBundles() {
if (System.getProperty(PROP_OSGI_BUNDLES) != null)
return;
System.getProperties().put(PROP_OSGI_BUNDLES, DEFAULT_OSGI_BUNDLES);
}
protected void basicRun(String[] args) throws Exception {
//Set the fwk location since the regular lookup would not find it
String fwkURL = searchFor(framework, null);
System.setProperty(PROP_FRAMEWORK, fwkURL);
onTheBundleList.add(fwkURL);
super.basicRun(args);
}
protected URL[] getBootPath(String base) throws IOException {
URL[] result = super.getBootPath(base);
setDefaultBundles();
convertBundleList();
addAllBundlesToBundleList();
cleanup();
return result;
}
/*
* Null out all the fields containing data
*/
private void cleanup() {
allJars = null;
onTheBundleList = null;
}
protected String searchFor(final String target, String start) {
//The searching can be improved
String[] jars = getAllJars();
ArrayList selected = new ArrayList(3);
for (int i = 0; i < jars.length; i++) {
if (jars[i].indexOf(target) != -1)
selected.add(jars[i]);
}
if (selected.size() == 0)
return null;
String[] selectedJars = new String[selected.size()];
for (int i = 0; i < selected.size(); i++) {
selectedJars[i] = extractFileName((String) selected.get(i));
}
if (debug)
System.out.println(extractInnerURL((String) selected.get(findMax(selectedJars))));
return extractInnerURL((String) selected.get(findMax(selectedJars)));
}
/*
* Extract the file name of the url - given that a file name
*/
private String extractFileName(String url) {
String innerURL = extractInnerURL(url);
return innerURL.substring(innerURL.lastIndexOf("/") + 1);
}
/*
* Find all the jars available on the webstart classpath
*/
private String[] getAllJars() {
if (allJars != null)
return allJars;
ArrayList collector = new ArrayList();
try {
Enumeration resources = WebStartMain.class.getClassLoader().getResources(JarFile.MANIFEST_NAME);
while (resources.hasMoreElements()) {
collector.add(((URL) resources.nextElement()).toExternalForm());
}
} catch (IOException e) {
e.printStackTrace();
}
allJars = new String[collector.size()];
collector.toArray(allJars);
if (debug)
printArray("Jars found on the webstart path:\n", allJars); //$NON-//$NON-NLS-1$
return allJars;
}
private String extractInnerURL(String url) {
if (url.startsWith(JAR_SCHEME)) {
url = url.substring(url.indexOf(JAR_SCHEME) + 4);
}
int lastBang = url.lastIndexOf('!');
if (lastBang != -1) {
url = url.substring(0, lastBang);
}
return decode(url);
}
/*
* convert the values on the osgi bundle list from: name@... to <bundleurl>@...
*/
private void convertBundleList() {
final char SEPARATOR = '@';
if (debug)
System.out.println("Osgi bundles before conversion:\n" + System.getProperty(PROP_OSGI_BUNDLES)); //$NON-NLS-1$
String[] bundles = getArrayFromList(System.getProperty(PROP_OSGI_BUNDLES));
String result = "";
for (int i = 0; i < bundles.length; i++) {
//a entry in the bundle list is made of two parts: the bundle to install followed by an optional info. The separator for those is @
String bundle = bundles[i];
int positionExtraInfo = bundle.indexOf(SEPARATOR);
String bundleName = null;
if (positionExtraInfo == -1)
bundleName = bundle;
else
bundleName = bundle.substring(0, positionExtraInfo);
String bundleURL = searchFor(bundleName, null);
if (bundleURL == null) {
if (debug)
System.out.println("Could not find " + bundleName); //$NON-NLS-1$
continue;
}
onTheBundleList.add(bundleURL);
bundleURL = REFERENCE_SCHEME + bundleURL;
result += bundleURL;
if (positionExtraInfo != -1)
result += bundle.substring(positionExtraInfo);
result += ',';
}
System.setProperty(PROP_OSGI_BUNDLES, result);
}
/*
* Add to the bundle list all the jars found the webstart classpath
*/
//This code can be improved
private void addAllBundlesToBundleList() {
if ("false".equalsIgnoreCase(System.getProperties().getProperty(PROP_WEBSTART_AUTOMATIC_INSTALLATION))) //$NON-NLS-1$
return;
String[] jarsOnClasspath = getAllJars();
String[] result = new String[jarsOnClasspath.length];
for (int i = 0; i < jarsOnClasspath.length; i++) {
onTheBundleList.contains(jarsOnClasspath[i]);
result[i] = REFERENCE_SCHEME + extractInnerURL(jarsOnClasspath[i]);
}
System.setProperty(PROP_OSGI_BUNDLES, System.getProperty(PROP_OSGI_BUNDLES) + arrayToString(result, ','));
if (debug)
printArray("Bundles list:\n", result);
}
private void printArray(String header, String[] values) {
System.out.println(header); //$NON-NLS-1$
for (int i = 0; i < values.length; i++) {
System.out.println("\t" + values[i]); //$NON-NLS-1$
}
}
private String arrayToString(String[] array, char separator) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < array.length - 1; i++) {
result.append(array[i]).append(separator);
}
result.append(array[array.length - 1]);
return new String(result);
}
}