KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > launcher > WebStartMain


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.launcher;
12
13 import java.io.IOException JavaDoc;
14 import java.net.MalformedURLException JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.util.*;
17 import java.util.jar.JarFile JavaDoc;
18 import java.util.jar.Manifest JavaDoc;
19
20 /**
21  * The launcher ot start eclipse using webstart.
22  * To use this launcher, the client must accept to give all security permissions.
23  */

24 //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.
25
public class WebStartMain extends Main {
26     private static final String JavaDoc PROP_WEBSTART_AUTOMATIC_INSTALLATION = "eclipse.webstart.automaticInstallation"; //$NON-NLS-1$
27
private static final String JavaDoc DEFAULT_OSGI_BUNDLES = "org.eclipse.equinox.common@2:start, org.eclipse.core.runtime@start"; //$NON-NLS-1$
28
private static final String JavaDoc PROP_OSGI_BUNDLES = "osgi.bundles"; //$NON-NLS-1$
29
private static final String JavaDoc PROP_WEBSTART_PRECISE_BUNDLEID = "eclipse.webstart.preciseBundleId"; //$NON-NLS-1$
30

31
32     private String JavaDoc[] allJars = null; //List all the jars that are on the classpath
33
private Map bundleList = null; //Map an entry (the part before the @) from the osgi.bundles list to a list of URLs. Ie: org.eclipse.core.runtime --> file:c:/foo/org.eclipse.core.runtime_3.1.0/..., file:c:/bar/org.eclipse.core.runtime/...
34
private Map bundleStartInfo = null; //Keep track of the start level info for each bundle from the osgi.bundle list.
35

36     private boolean preciseIdExtraction = false; //Flag indicating if the extraction of the id must be done by looking at bundle ids.
37

38     public static void main(String JavaDoc[] args) {
39         System.setSecurityManager(null); //TODO Hack so that when the classloader loading the fwk is created we don't have funny permissions. This should be revisited.
40
int result = new WebStartMain().run(args);
41         System.exit(result);
42     }
43
44     private void setDefaultBundles() {
45         if (System.getProperty(PROP_OSGI_BUNDLES) != null)
46             return;
47         System.getProperties().put(PROP_OSGI_BUNDLES, DEFAULT_OSGI_BUNDLES);
48     }
49
50     protected void basicRun(String JavaDoc[] args) throws Exception JavaDoc {
51         preciseIdExtraction = Boolean.getBoolean(PROP_WEBSTART_PRECISE_BUNDLEID);
52         setDefaultBundles();
53         addOSGiBundle();
54         initializeBundleListStructure();
55         mapURLsToBundleList();
56         //Set the fwk location since the regular lookup would not find it
57
String JavaDoc fwkURL = searchFor(framework, null);
58         System.getProperties().put(PROP_FRAMEWORK, fwkURL);
59         super.basicRun(args);
60     }
61
62     private void addOSGiBundle() {
63         //Add osgi to the bundle list, so we can beneficiate of the infrastructure to find its location. It will be removed from the list later on
64
System.getProperties().put(PROP_OSGI_BUNDLES, System.getProperty(PROP_OSGI_BUNDLES) + ',' + framework);
65     }
66
67     protected URL JavaDoc[] getBootPath(String JavaDoc base) throws IOException JavaDoc {
68         URL JavaDoc[] result = super.getBootPath(base);
69         buildOSGiBundleList();
70         cleanup();
71         return result;
72     }
73
74     /*
75      * Null out all the fields containing data
76      */

77     private void cleanup() {
78         allJars = null;
79         bundleList = null;
80         bundleStartInfo = null;
81     }
82
83     /*
84      * Find the target bundle among all the jars that are on the classpath.
85      * The start parameter is not used in this context
86      */

87     protected String JavaDoc searchFor(final String JavaDoc target, String JavaDoc start) {
88         ArrayList matches = (ArrayList) bundleList.get(target);
89         int numberOfURLs = matches.size();
90         if (numberOfURLs == 1) {
91             return extractInnerURL((String JavaDoc) matches.get(0));
92         }
93         if (numberOfURLs == 0)
94             return null;
95         String JavaDoc urls[] = new String JavaDoc[numberOfURLs];
96         return extractInnerURL(urls[findMax((String JavaDoc[]) matches.toArray(urls))]);
97     }
98
99     /*
100      * Get all the jars available on the webstart classpath
101      */

102     private String JavaDoc[] getAllJars() {
103         if (allJars != null)
104             return allJars;
105
106         ArrayList collector = new ArrayList();
107         try {
108             Enumeration resources = WebStartMain.class.getClassLoader().getResources(JarFile.MANIFEST_NAME);
109             while (resources.hasMoreElements()) {
110                 collector.add(((URL JavaDoc) resources.nextElement()).toExternalForm());
111             }
112         } catch (IOException JavaDoc e) {
113             e.printStackTrace();
114         }
115         allJars = new String JavaDoc[collector.size()];
116         collector.toArray(allJars);
117         if (debug)
118             printArray("Jars found on the webstart path:\n", allJars); //$NON-//$NON-NLS-1$
119

120         return allJars;
121     }
122
123     /*
124      * Extract the inner URL from a string representing a JAR url string.
125      */

126     private String JavaDoc extractInnerURL(String JavaDoc url) {
127         if (url.startsWith(JAR_SCHEME)) {
128             url = url.substring(url.indexOf(JAR_SCHEME) + 4);
129         }
130         int lastBang = url.lastIndexOf('!');
131         if (lastBang != -1) {
132             url = url.substring(0, lastBang);
133         }
134         return decode(url);
135     }
136
137     private void printArray(String JavaDoc header, String JavaDoc[] values) {
138         System.err.println(header);
139         for (int i = 0; i < values.length; i++) {
140             System.err.println("\t" + values[i]); //$NON-NLS-1$
141
}
142     }
143
144
145     /*
146      * Initialize the data structure corresponding to the osgi.bundles list
147      */

148     private void initializeBundleListStructure() {
149         final char STARTLEVEL_SEPARATOR = '@';
150
151         //In webstart the bundles list can only contain bundle names with or without a version.
152
String JavaDoc prop = System.getProperty(PROP_OSGI_BUNDLES);
153         if (prop == null || prop.trim().equals("")) { //$NON-NLS-1$
154
bundleList = new HashMap(0);
155             return;
156         }
157
158         bundleList = new HashMap(10);
159         bundleStartInfo = new HashMap(10);
160         StringTokenizer tokens = new StringTokenizer(prop, ","); //$NON-NLS-1$
161
while (tokens.hasMoreTokens()) {
162             String JavaDoc token = tokens.nextToken().trim();
163             String JavaDoc bundleId = token;
164             if (token.equals("")) //$NON-NLS-1$
165
continue;
166             int startLevelSeparator;
167             if ((startLevelSeparator = token.lastIndexOf(STARTLEVEL_SEPARATOR)) != -1) {
168                 bundleId = token.substring(0, startLevelSeparator);
169                 bundleStartInfo.put(bundleId, token.substring(startLevelSeparator));
170             }
171             bundleList.put(bundleId, new ArrayList(1)); // put a list with one element as it is likely that the element will be present
172
}
173         
174     }
175
176     /*
177      * Associate urls from the list of jars with a bundle from the bundle list
178      */

179     private void mapURLsToBundleList() {
180         String JavaDoc[] allJars = getAllJars();
181         for (int i = 0; i < allJars.length; i++) {
182             String JavaDoc bundleId = extractBundleId(allJars[i]);
183             if (bundleId == null)
184                 continue;
185             ArrayList bundleURLs = (ArrayList) bundleList.get(bundleId);
186             if (bundleURLs == null) {
187                 int versionIdPosition = bundleId.lastIndexOf('_');
188                 if (versionIdPosition == -1)
189                     continue;
190                 bundleURLs = (ArrayList) bundleList.get(bundleId.substring(0, versionIdPosition));
191                 if (bundleURLs == null)
192                     continue;
193             }
194             bundleURLs.add(allJars[i]);
195             allJars[i] = null; //Remove the entry from the list
196
}
197     }
198
199     /*
200      * return a string of the form <bundle>_<version>
201      */

202     private String JavaDoc extractBundleId(String JavaDoc url) {
203         if (preciseIdExtraction)
204             return extractBundleIdFromManifest(url);
205         else
206             return extractBundleIdFromBundleURL(url);
207     }
208
209     private String JavaDoc extractBundleIdFromManifest(String JavaDoc url) {
210         final String JavaDoc BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName"; //$NON-NLS-1$
211
final String JavaDoc BUNDLE_VERSION = "Bundle-Version"; //$NON-NLS-1$
212

213         Manifest JavaDoc mf;
214         try {
215             mf = new Manifest JavaDoc(new URL JavaDoc(url).openStream());
216             String JavaDoc symbolicNameString = mf.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
217             if (symbolicNameString==null)
218                 return null;
219             
220             String JavaDoc bundleVersion = mf.getMainAttributes().getValue(BUNDLE_VERSION);
221             if (bundleVersion == null)
222                 bundleVersion = ""; //$NON-NLS-1$
223
else
224                 bundleVersion = '_' + bundleVersion;
225             
226             int pos = symbolicNameString.lastIndexOf(';');
227             if (pos != -1)
228                 return symbolicNameString.substring(0, pos) + bundleVersion;
229             return symbolicNameString + bundleVersion;
230         } catch (MalformedURLException JavaDoc e) {
231             //Ignore
232
} catch (IOException JavaDoc e) {
233             //Ignore
234
}
235         return null;
236
237     }
238
239     private String JavaDoc extractBundleIdFromBundleURL(String JavaDoc url) {
240         int lastBang = url.lastIndexOf('!');
241         if (lastBang == -1)
242             return null;
243         boolean jarSuffix = url.regionMatches(true, lastBang - 4, ".jar", 0, 4); //$NON-NLS-1$
244
int bundleIdStart = url.lastIndexOf('/', lastBang);
245         return url.substring(bundleIdStart + 3, lastBang - (jarSuffix ? 4 : 0)); // + 3 because URLs from webstart have a funny prefix
246
}
247     
248     private void buildOSGiBundleList() {
249         //Remove the framework from the bundle list because it does not need to be installed. See addOSGiBundle
250
bundleList.remove(framework);
251
252         String JavaDoc[] jarsOnClasspath = getAllJars();
253         StringBuffer JavaDoc finalBundleList = new StringBuffer JavaDoc(jarsOnClasspath.length * 25);
254         
255         //Add the bundles from the bundle list.
256
Collection allSelectedBundles = bundleList.entrySet();
257         for (Iterator iter = allSelectedBundles.iterator(); iter.hasNext();) {
258             Map.Entry entry = (Map.Entry) iter.next();
259             ArrayList matches = (ArrayList) entry.getValue();
260             int numberOfURLs = matches.size();
261             
262             //Get the start info
263
String JavaDoc startInfo = (String JavaDoc) bundleStartInfo.get(entry.getKey());
264             if (startInfo == null)
265                 startInfo = ""; //$NON-NLS-1$
266

267             if (numberOfURLs == 1) {
268                 finalBundleList.append(REFERENCE_SCHEME).append(extractInnerURL((String JavaDoc) matches.get(0))).append(startInfo).append(',');
269                 continue;
270             }
271             if (numberOfURLs == 0)
272                 continue;
273             String JavaDoc urls[] = new String JavaDoc[numberOfURLs];
274             int found = findMax((String JavaDoc[]) matches.toArray(urls));
275             for (int i = 0; i < urls.length; i++) {
276                 if (i != found)
277                     continue;
278                 finalBundleList.append(REFERENCE_SCHEME).append(extractInnerURL((String JavaDoc) urls[found])).append(startInfo).append(',');
279             }
280         }
281         
282         //Add all the other bundles if required - the common case is to add those
283
if (! Boolean.FALSE.toString().equalsIgnoreCase(System.getProperties().getProperty(PROP_WEBSTART_AUTOMATIC_INSTALLATION))) {
284             for (int i = 0; i < jarsOnClasspath.length; i++) {
285                 if (jarsOnClasspath[i] != null)
286                     finalBundleList.append(REFERENCE_SCHEME).append(extractInnerURL(jarsOnClasspath[i])).append(',');
287             }
288         }
289
290         System.getProperties().put(PROP_OSGI_BUNDLES, finalBundleList.toString());
291         if (debug)
292             log(finalBundleList.toString());
293     }
294
295 }
296
Popular Tags