KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > launching > JREContainer


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.jdt.internal.launching;
12
13
14 import java.net.URL JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.Platform;
23 import org.eclipse.jdt.core.IAccessRule;
24 import org.eclipse.jdt.core.IClasspathAttribute;
25 import org.eclipse.jdt.core.IClasspathContainer;
26 import org.eclipse.jdt.core.IClasspathEntry;
27 import org.eclipse.jdt.core.IJavaProject;
28 import org.eclipse.jdt.core.JavaCore;
29 import org.eclipse.jdt.launching.IVMInstall;
30 import org.eclipse.jdt.launching.IVMInstallChangedListener;
31 import org.eclipse.jdt.launching.JavaRuntime;
32 import org.eclipse.jdt.launching.LibraryLocation;
33 import org.eclipse.jdt.launching.PropertyChangeEvent;
34 import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
35
36 import com.ibm.icu.text.MessageFormat;
37
38 /**
39  * JRE Container - resolves a classpath container variable to a JRE
40  */

41 public class JREContainer implements IClasspathContainer {
42
43     /**
44      * Corresponding JRE
45      */

46     private IVMInstall fVMInstall = null;
47     
48     /**
49      * Container path used to resolve to this JRE
50      */

51     private IPath fPath = null;
52     
53     /**
54      * The project this container is for
55      */

56     private IJavaProject fProject = null;
57     
58     /**
59      * Cache of classpath entries per VM install. Cleared when a VM changes.
60      */

61     private static Map JavaDoc fgClasspathEntries = new HashMap JavaDoc(10);
62     
63     /**
64      * Variable to return an empty array of <code>IAccessRule</code>s
65      */

66     private static IAccessRule[] EMPTY_RULES = new IAccessRule[0];
67     
68     // debug flags
69
public static boolean DEBUG_JRE_CONTAINER = false;
70     
71     /**
72      * Map of {IVMInstall -> Map of {{IExeuctionEnvironment, IAccessRule[][]} -> {IClasspathEntry[]}}
73      */

74     private static Map JavaDoc fgClasspathEntriesWithRules = new HashMap JavaDoc(10);
75     
76     /**
77      * A single key entry for the cache of access rules and classpath entries
78      * A rule key is made up of an <code>IVMInstall</code> and an execution environment id
79      * @since 3.3
80      */

81     static class RuleKey {
82         private String JavaDoc fEnvironmentId = null;
83         private IVMInstall fInstall = null;
84         
85         /**
86          * Constructor
87          * @param install
88          * @param environmentId
89          */

90         public RuleKey(IVMInstall install, String JavaDoc environmentId) {
91             fInstall = install;
92             fEnvironmentId = environmentId;
93         }
94         
95         /* (non-Javadoc)
96          * @see java.lang.Object#equals(java.lang.Object)
97          */

98         public boolean equals(Object JavaDoc obj) {
99             if (obj instanceof RuleKey) {
100                 RuleKey key = (RuleKey) obj;
101                 return fEnvironmentId.equals(key.fEnvironmentId) && fInstall.equals(key.fInstall);
102             }
103             return false;
104         }
105         
106         /* (non-Javadoc)
107          * @see java.lang.Object#hashCode()
108          */

109         public int hashCode() {
110             return fEnvironmentId.hashCode() + fInstall.hashCode();
111         }
112     }
113     
114     /**
115      * Holds an entry for the cache of access rules/classpath entries.
116      * An entry is made up of an array of classpath entries and the collection of access rules.
117      * @since 3.3
118      */

119     static class RuleEntry {
120         private IAccessRule[][] fRules = null;
121         private IClasspathEntry[] fEntries = null;
122         
123         /**
124          * Constructor
125          * @param rules
126          * @param entries
127          */

128         public RuleEntry(IAccessRule[][] rules, IClasspathEntry[] entries) {
129             fRules = rules;
130             fEntries = entries;
131         }
132         
133         /**
134          * Returns the collection oof classpath entries for this RuleEntry
135          * @return the cached aray of classpath entries
136          */

137         public IClasspathEntry[] getClasspathEntries() {
138             return fEntries;
139         }
140         
141         /* (non-Javadoc)
142          * @see java.lang.Object#equals(java.lang.Object)
143          */

144         public boolean equals(Object JavaDoc obj) {
145             IAccessRule[][] rules = null;
146             if(obj instanceof RuleEntry) {
147                 rules = ((RuleEntry)obj).fRules;
148             }
149             if(obj instanceof IAccessRule[][]) {
150                 rules = (IAccessRule[][]) obj;
151             }
152             if(rules != null) {
153                 if (fRules == rules) {
154                     return true;
155                 }
156                 if (fRules.length == rules.length) {
157                     boolean equal = true;
158                     IAccessRule[] originalrule, comparerule = null;
159                     for (int i = 0; i < fRules.length; i++) {
160                         originalrule = fRules[i];
161                         comparerule = rules[i];
162                         equal &= (originalrule == comparerule);
163                         if(!equal) {
164                             if (originalrule.length == comparerule.length) {
165                                 for (int j = 0; j < originalrule.length; j++) {
166                                     if (!originalrule[j].equals(comparerule[j])) {
167                                         return false;
168                                     }
169                                 }
170                                 return true;
171                             }
172                             else {
173                                 return false;
174                             }
175                         }
176                     }
177                     return equal;
178                 }
179             }
180             return false;
181         }
182     }
183     
184     /**
185      * Add a vm changed listener to clear cached values when a VM changes or is removed
186      */

187     static {
188         IVMInstallChangedListener listener = new IVMInstallChangedListener() {
189
190             /* (non-Javadoc)
191              * @see org.eclipse.jdt.launching.IVMInstallChangedListener#defaultVMInstallChanged(org.eclipse.jdt.launching.IVMInstall, org.eclipse.jdt.launching.IVMInstall)
192              */

193             public void defaultVMInstallChanged(IVMInstall previous, IVMInstall current) {}
194             
195             /* (non-Javadoc)
196              * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmAdded(org.eclipse.jdt.launching.IVMInstall)
197              */

198             public void vmAdded(IVMInstall newVm) {}
199
200             /* (non-Javadoc)
201              * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmChanged(org.eclipse.jdt.launching.PropertyChangeEvent)
202              */

203             public void vmChanged(PropertyChangeEvent event) {
204                 if (event.getSource() != null) {
205                     fgClasspathEntries.remove(event.getSource());
206                     removeRuleEntry(event.getSource());
207                 }
208             }
209
210             /* (non-Javadoc)
211              * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmRemoved(org.eclipse.jdt.launching.IVMInstall)
212              */

213             public void vmRemoved(IVMInstall removedVm) {
214                 fgClasspathEntries.remove(removedVm);
215                 removeRuleEntry(removedVm);
216             }
217             
218             /**
219              * Removes all occurances of the given vm found as part key members in the current
220              * cache for classpath entries
221              * @param obj an object which should be castable to IVMInstall
222              */

223             private void removeRuleEntry(Object JavaDoc obj) {
224                 if(obj instanceof IVMInstall) {
225                     IVMInstall install = (IVMInstall) obj;
226                     RuleKey key = null;
227                     ArrayList JavaDoc list = new ArrayList JavaDoc();
228                     for(Iterator JavaDoc iter = fgClasspathEntriesWithRules.keySet().iterator(); iter.hasNext();) {
229                         key = (RuleKey) iter.next();
230                         if(key.fInstall.equals(install)) {
231                             list.add(key);
232                         }
233                     }
234                     for(int i = 0; i < list.size(); i++) {
235                         fgClasspathEntriesWithRules.remove(list.get(i));
236                     }
237                 }
238             }
239         };
240         JavaRuntime.addVMInstallChangedListener(listener);
241     }
242     
243     /**
244      * Initialize debug flags
245      */

246     static {
247         DEBUG_JRE_CONTAINER =LaunchingPlugin.DEBUG && "true".equals( //$NON-NLS-1$
248
Platform.getDebugOption("org.eclipse.jdt.launching/debug/classpath/jreContainer")); //$NON-NLS-1$
249
}
250     
251     /**
252      * Returns the classpath entries associated with the given VM
253      * in the context of the given path and project.
254      *
255      * @param vm
256      * @param containerPath the container path resolution is for
257      * @param project project the resolution is for
258      * @return classpath entries
259      */

260     private static IClasspathEntry[] getClasspathEntries(IVMInstall vm, IPath containerPath, IJavaProject project) {
261         String JavaDoc id = JavaRuntime.getExecutionEnvironmentId(containerPath);
262         IClasspathEntry[] entries = null;
263         if (id == null) {
264             // cache classpath entries per JRE when not bound to an EE
265
entries = (IClasspathEntry[])fgClasspathEntries.get(vm);
266             if (entries == null) {
267                 entries = computeClasspathEntries(vm, project, id);
268                 fgClasspathEntries.put(vm, entries);
269             }
270         } else {
271             if (DEBUG_JRE_CONTAINER) {
272                 System.out.println("\tEE:\t" + id); //$NON-NLS-1$
273
}
274             // dynamically compute entries when bound to an EE
275
entries = computeClasspathEntries(vm, project, id);
276         }
277         return entries;
278     }
279     
280     /**
281      * Computes the classpath entries associated with a VM - one entry per library
282      * in the context of the given path and project.
283      *
284      * @param vm
285      * @param project the project the resolution is for
286      * @param environmentId execution environment the resolution is for, or <code>null</code>
287      * @return classpath entries
288      */

289     private static IClasspathEntry[] computeClasspathEntries(IVMInstall vm, IJavaProject project, String JavaDoc environmentId) {
290         LibraryLocation[] libs = vm.getLibraryLocations();
291         boolean overrideJavaDoc = false;
292         if (libs == null) {
293             libs = JavaRuntime.getLibraryLocations(vm);
294             overrideJavaDoc = true;
295         }
296         IAccessRule[][] rules = null;
297         if (environmentId != null) {
298             // compute access rules for execution environment
299
IExecutionEnvironment environment = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(environmentId);
300             if (environment != null) {
301                 rules = environment.getAccessRules(vm, libs, project);
302             }
303         }
304         RuleKey key = null;
305         if (vm != null && rules != null && environmentId != null) {
306             key = new RuleKey(vm, environmentId);
307             RuleEntry entry = (RuleEntry) fgClasspathEntriesWithRules.get(key);
308             if(entry != null && entry.equals(rules)) {
309                 return entry.getClasspathEntries();
310             }
311         }
312         List JavaDoc entries = new ArrayList JavaDoc(libs.length);
313         for (int i = 0; i < libs.length; i++) {
314             if (!libs[i].getSystemLibraryPath().isEmpty()) {
315                 IPath sourcePath = libs[i].getSystemLibrarySourcePath();
316                 if (sourcePath.isEmpty()) {
317                     sourcePath = null;
318                 }
319                 IPath rootPath = libs[i].getPackageRootPath();
320                 if (rootPath.isEmpty()) {
321                     rootPath = null;
322                 }
323                 URL JavaDoc javadocLocation = libs[i].getJavadocLocation();
324                 if (overrideJavaDoc && javadocLocation == null) {
325                     javadocLocation = vm.getJavadocLocation();
326                 }
327                 IClasspathAttribute[] attributes = null;
328                 if (javadocLocation == null) {
329                     attributes = new IClasspathAttribute[0];
330                 } else {
331                     attributes = new IClasspathAttribute[]{JavaCore.newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, javadocLocation.toExternalForm())};
332                 }
333                 IAccessRule[] libRules = null;
334                 if (rules != null) {
335                     libRules = rules[i];
336                 } else {
337                     libRules = EMPTY_RULES;
338                 }
339                 entries.add(JavaCore.newLibraryEntry(libs[i].getSystemLibraryPath(), sourcePath, rootPath, libRules, attributes, false));
340             }
341         }
342         IClasspathEntry[] cpEntries = (IClasspathEntry[])entries.toArray(new IClasspathEntry[entries.size()]);
343         if (key != null && rules != null) {
344             fgClasspathEntriesWithRules.put(key, new RuleEntry(rules, cpEntries));
345         }
346         return cpEntries;
347     }
348
349     /**
350      * Constructs a JRE classpath container on the given VM install
351      *
352      * @param vm vm install - cannot be <code>null</code>
353      * @param path container path used to resolve this JRE
354      */

355     public JREContainer(IVMInstall vm, IPath path, IJavaProject project) {
356         fVMInstall = vm;
357         fPath = path;
358         fProject = project;
359     }
360     
361     /**
362      * @see IClasspathContainer#getClasspathEntries()
363      */

364     public IClasspathEntry[] getClasspathEntries() {
365         if (DEBUG_JRE_CONTAINER) {
366             System.out.println("<JRE_CONTAINER> getClasspathEntries() " + this.toString()); //$NON-NLS-1$
367
System.out.println("\tJRE:\t" + fVMInstall.getName()); //$NON-NLS-1$
368
System.out.println("\tPath:\t" + getPath().toString()); //$NON-NLS-1$
369
System.out.println("\tProj:\t" + fProject.getProject().getName()); //$NON-NLS-1$
370
}
371         IClasspathEntry[] entries = getClasspathEntries(fVMInstall, getPath(), fProject);
372         if (DEBUG_JRE_CONTAINER) {
373             System.out.println("\tResolved " + entries.length + " entries:"); //$NON-NLS-1$//$NON-NLS-2$
374
}
375         return entries;
376     }
377
378     /**
379      * @see IClasspathContainer#getDescription()
380      */

381     public String JavaDoc getDescription() {
382         String JavaDoc environmentId = JavaRuntime.getExecutionEnvironmentId(getPath());
383         String JavaDoc tag = null;
384         if (environmentId == null) {
385             tag = fVMInstall.getName();
386         } else {
387             tag = environmentId;
388         }
389         return MessageFormat.format(LaunchingMessages.JREContainer_JRE_System_Library_1, new String JavaDoc[]{tag});
390     }
391
392     /**
393      * @see IClasspathContainer#getKind()
394      */

395     public int getKind() {
396         return IClasspathContainer.K_DEFAULT_SYSTEM;
397     }
398
399     /**
400      * @see IClasspathContainer#getPath()
401      */

402     public IPath getPath() {
403         return fPath;
404     }
405
406 }
407
Popular Tags