KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 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.equinox.launcher;
12
13 import java.io.IOException JavaDoc;
14 import java.net.JarURLConnection JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.net.URLConnection JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Enumeration JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.StringTokenizer JavaDoc;
24 import java.util.jar.JarFile JavaDoc;
25 import java.util.jar.Manifest JavaDoc;
26
27 /**
28  * The launcher to start eclipse using webstart. To use this launcher, the client
29  * must accept to give all security permissions.
30  * <p>
31  * <b>Note:</b> This class should not be referenced programmatically by
32  * other Java code. This class exists only for the purpose of launching Eclipse
33  * using Java webstart. To launch Eclipse programmatically, use
34  * org.eclipse.core.runtime.adaptor.EclipseStarter. The fields and methods
35  * on this class are not API.
36  */

37 //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.
38
public class WebStartMain extends Main {
39     private static final String JavaDoc PROP_WEBSTART_AUTOMATIC_INSTALLATION = "eclipse.webstart.automaticInstallation"; //$NON-NLS-1$
40
private static final String JavaDoc DEFAULT_OSGI_BUNDLES = "org.eclipse.equinox.common@2:start, org.eclipse.core.runtime@start"; //$NON-NLS-1$
41
private static final String JavaDoc PROP_OSGI_BUNDLES = "osgi.bundles"; //$NON-NLS-1$
42
private static final String JavaDoc PROP_CHECK_CONFIG = "osgi.checkConfiguration"; //$NON-NLS-1$
43

44     private Map JavaDoc allBundles = null; // Map of all the bundles found on the classpath. Id -> ArrayList of BundleInfo
45
private List JavaDoc bundleList = null; //The list of bundles found on the osgi.bundle list
46

47     private class BundleInfo {
48         String JavaDoc bsn;
49         String JavaDoc version;
50         String JavaDoc startData;
51         String JavaDoc location;
52     }
53
54     public static void main(String JavaDoc[] args) {
55         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.
56
int result = new WebStartMain().run(args);
57         if (!Boolean.getBoolean(PROP_NOSHUTDOWN))
58             System.exit(result);
59     }
60
61     private void setDefaultBundles() {
62         if (System.getProperty(PROP_OSGI_BUNDLES) != null)
63             return;
64         System.getProperties().put(PROP_OSGI_BUNDLES, DEFAULT_OSGI_BUNDLES);
65     }
66
67     protected void basicRun(String JavaDoc[] args) throws Exception JavaDoc {
68         setDefaultBundles();
69         initializeBundleListStructure();
70         discoverBundles();
71         //Set the fwk location since the regular lookup would not find it
72
String JavaDoc fwkURL = searchFor(framework, null);
73         if (fwkURL == null) {
74             //MESSAGE CAN"T FIND THE FWK
75
}
76         allBundles.remove(framework);
77         System.getProperties().put(PROP_FRAMEWORK, fwkURL);
78         super.basicRun(args);
79     }
80
81     protected void beforeFwkInvocation() {
82         // set the check config option so we pick up modified bundle jars (bug 152825)
83
if (System.getProperty(PROP_CHECK_CONFIG) == null)
84             System.getProperties().put(PROP_CHECK_CONFIG, "true"); //$NON-NLS-1$
85
buildOSGiBundleList();
86         cleanup();
87     }
88
89     /*
90      * Null out all the fields containing data
91      */

92     private void cleanup() {
93         allBundles = null;
94         bundleList = null;
95     }
96
97     /*
98      * Find the target bundle among all the bundles that are on the classpath.
99      * The start parameter is not used in this context
100      */

101     protected String JavaDoc searchFor(final String JavaDoc target, String JavaDoc start) {
102         ArrayList JavaDoc matches = (ArrayList JavaDoc) allBundles.get(target);
103         if (matches == null)
104             return null;
105         int numberOfMatches = matches.size();
106         if (numberOfMatches == 1) {
107             return ((BundleInfo) matches.get(0)).location;
108         }
109         if (numberOfMatches == 0)
110             return null;
111
112         String JavaDoc[] versions = new String JavaDoc[numberOfMatches];
113         int highest = 0;
114         for (int i = 0; i < versions.length; i++) {
115             versions[i] = ((BundleInfo) matches.get(i)).version;
116             highest = findMax(versions);
117         }
118         return ((BundleInfo) matches.get(highest)).location;
119     }
120
121     private BundleInfo findBundle(final String JavaDoc target, String JavaDoc version, boolean removeMatch) {
122         ArrayList JavaDoc matches = (ArrayList JavaDoc) allBundles.get(target);
123         int numberOfMatches = matches.size();
124         if (numberOfMatches == 1) {
125             //TODO Need to check the version
126
return (BundleInfo) matches.remove(0);
127         }
128         if (numberOfMatches == 0)
129             return null;
130
131         if (version != null) {
132             for (Iterator JavaDoc iterator = matches.iterator(); iterator.hasNext();) {
133                 BundleInfo bi = (BundleInfo) iterator.next();
134                 if (bi.version.equals(version)) {
135                     iterator.remove();
136                     return bi;
137                 }
138             }
139             //TODO Need to log the fact that we could not find the version mentioned
140
return null;
141         }
142         String JavaDoc[] versions = new String JavaDoc[numberOfMatches];
143         int highest = 0;
144         for (int i = 0; i < versions.length; i++) {
145             versions[i] = ((BundleInfo) matches.get(i)).version;
146             highest = findMax(versions);
147         }
148         return (BundleInfo) matches.remove(highest);
149     }
150
151     /*
152      * Get all the bundles available on the webstart classpath
153      */

154     private void discoverBundles() {
155         allBundles = new HashMap JavaDoc();
156         try {
157             Enumeration JavaDoc resources = WebStartMain.class.getClassLoader().getResources(JarFile.MANIFEST_NAME);
158             while (resources.hasMoreElements()) {
159                 BundleInfo found = getBundleInfo((URL JavaDoc) resources.nextElement());
160                 if (found == null)
161                     continue;
162                 ArrayList JavaDoc matching = (ArrayList JavaDoc) allBundles.get(found.bsn);
163                 if (matching == null) {
164                     matching = new ArrayList JavaDoc(1);
165                     allBundles.put(found.bsn, matching);
166                 }
167                 matching.add(found);
168             }
169         } catch (IOException JavaDoc e) {
170             e.printStackTrace();
171         }
172     }
173
174     private String JavaDoc extractInnerURL(URL JavaDoc url) {
175         try {
176             URLConnection JavaDoc connection = null;
177             try {
178                 connection = url.openConnection();
179                 if (connection instanceof JarURLConnection JavaDoc) {
180                     return "file:" + ((JarURLConnection JavaDoc) connection).getJarFile().getName();
181                 }
182             } finally {
183                 if (connection != null)
184                     connection.getInputStream().close();
185             }
186         } catch (IOException JavaDoc e) {
187             //Ignore and return the external form
188
}
189         return url.toExternalForm();
190     }
191
192     /*
193      * Construct bundle info objects from items found on the osgi.bundles list
194      */

195     private void initializeBundleListStructure() {
196         final char STARTLEVEL_SEPARATOR = '@';
197
198         //In webstart the bundles list can only contain bundle names with or without a version.
199
String JavaDoc prop = System.getProperty(PROP_OSGI_BUNDLES);
200         if (prop == null || prop.trim().equals("")) { //$NON-NLS-1$
201
bundleList = new ArrayList JavaDoc(0);
202             return;
203         }
204
205         bundleList = new ArrayList JavaDoc(10);
206         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(prop, ","); //$NON-NLS-1$
207
while (tokens.hasMoreTokens()) {
208             String JavaDoc token = tokens.nextToken().trim();
209             String JavaDoc bundleId = token;
210             if (token.equals("")) //$NON-NLS-1$
211
continue;
212             int startLevelSeparator;
213             BundleInfo toAdd = new BundleInfo();
214             toAdd.bsn = bundleId;
215             if ((startLevelSeparator = token.lastIndexOf(STARTLEVEL_SEPARATOR)) != -1) {
216                 toAdd.bsn = token.substring(0, startLevelSeparator);
217                 toAdd.startData = token.substring(startLevelSeparator);
218                 //Note that here we don't try to parse the start attribute since this info is then used to recompose the value for osgi.bundles
219
}
220             bundleList.add(toAdd);
221         }
222     }
223
224     private BundleInfo getBundleInfo(URL JavaDoc manifestURL) {
225         final String JavaDoc BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName"; //$NON-NLS-1$
226
final String JavaDoc BUNDLE_VERSION = "Bundle-Version"; //$NON-NLS-1$
227
final String JavaDoc DEFAULT_VERSION = "0.0.0"; //$NON-NLS-1$
228

229         Manifest JavaDoc mf;
230         try {
231             mf = new Manifest JavaDoc(manifestURL.openStream());
232             String JavaDoc symbolicNameString = mf.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
233             if (symbolicNameString == null)
234                 return null;
235
236             BundleInfo result = new BundleInfo();
237             String JavaDoc version = mf.getMainAttributes().getValue(BUNDLE_VERSION);
238             result.version = (version != null) ? version : DEFAULT_VERSION;
239             result.location = extractInnerURL(manifestURL);
240             int pos = symbolicNameString.lastIndexOf(';');
241             if (pos != -1) {
242                 result.bsn = symbolicNameString.substring(0, pos);
243                 return result;
244             }
245             result.bsn = symbolicNameString;
246             return result;
247         } catch (IOException JavaDoc e) {
248             if (debug)
249                 e.printStackTrace();
250         }
251         return null;
252     }
253
254     //Build the osgi bundle list. The allbundles data structure is changed during the process.
255
private void buildOSGiBundleList() {
256         StringBuffer JavaDoc finalBundleList = new StringBuffer JavaDoc(allBundles.size() * 30);
257         //First go through all the bundles of the bundle
258
for (Iterator JavaDoc iterator = bundleList.iterator(); iterator.hasNext();) {
259             BundleInfo searched = (BundleInfo) iterator.next();
260             BundleInfo found = findBundle(searched.bsn, searched.version, true);
261             finalBundleList.append(REFERENCE_SCHEME).append(found.location).append(searched.startData).append(',');
262         }
263
264         if (!Boolean.FALSE.toString().equalsIgnoreCase(System.getProperties().getProperty(PROP_WEBSTART_AUTOMATIC_INSTALLATION))) {
265             for (Iterator JavaDoc iterator = allBundles.values().iterator(); iterator.hasNext();) {
266                 ArrayList JavaDoc toAdd = (ArrayList JavaDoc) iterator.next();
267                 for (Iterator JavaDoc iterator2 = toAdd.iterator(); iterator2.hasNext();) {
268                     BundleInfo bi = (BundleInfo) iterator2.next();
269                     finalBundleList.append(REFERENCE_SCHEME).append(bi.location).append(',');
270                 }
271             }
272         }
273         System.getProperties().put(PROP_OSGI_BUNDLES, finalBundleList.toString());
274     }
275 }
276
Popular Tags