KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > launching > environments > ExecutionEnvironment


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.jdt.internal.launching.environments;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19
20 import org.eclipse.core.resources.ResourcesPlugin;
21 import org.eclipse.core.runtime.IConfigurationElement;
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.core.runtime.NullProgressMonitor;
24 import org.eclipse.core.runtime.Path;
25 import org.eclipse.jdt.core.IAccessRule;
26 import org.eclipse.jdt.core.IClasspathContainer;
27 import org.eclipse.jdt.core.IClasspathEntry;
28 import org.eclipse.jdt.core.IJavaModel;
29 import org.eclipse.jdt.core.IJavaProject;
30 import org.eclipse.jdt.core.JavaCore;
31 import org.eclipse.jdt.core.JavaModelException;
32 import org.eclipse.jdt.internal.launching.LaunchingPlugin;
33 import org.eclipse.jdt.launching.IVMInstall;
34 import org.eclipse.jdt.launching.IVMInstallChangedListener;
35 import org.eclipse.jdt.launching.JavaRuntime;
36 import org.eclipse.jdt.launching.LibraryLocation;
37 import org.eclipse.jdt.launching.PropertyChangeEvent;
38 import org.eclipse.jdt.launching.environments.IAccessRuleParticipant;
39 import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
40
41 import com.ibm.icu.text.MessageFormat;
42
43 /**
44  * A contributed execution environment.
45  *
46  * @since 3.2
47  */

48 class ExecutionEnvironment implements IExecutionEnvironment {
49     
50     /**
51      * Add a vm changed listener to clear cached values when a VM changes or is removed
52      */

53     private IVMInstallChangedListener fListener = new IVMInstallChangedListener() {
54
55         /* (non-Javadoc)
56          * @see org.eclipse.jdt.launching.IVMInstallChangedListener#defaultVMInstallChanged(org.eclipse.jdt.launching.IVMInstall, org.eclipse.jdt.launching.IVMInstall)
57          */

58         public void defaultVMInstallChanged(IVMInstall previous, IVMInstall current) {}
59         
60         /* (non-Javadoc)
61          * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmAdded(org.eclipse.jdt.launching.IVMInstall)
62          */

63         public void vmAdded(IVMInstall newVm) {}
64
65         /* (non-Javadoc)
66          * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmChanged(org.eclipse.jdt.launching.PropertyChangeEvent)
67          */

68         public void vmChanged(PropertyChangeEvent event) {
69             if (event.getSource() != null) {
70                 fParticipantMap.remove(event.getSource());
71                 fRuleCache.remove(event.getSource());
72             }
73         }
74
75         /* (non-Javadoc)
76          * @see org.eclipse.jdt.launching.IVMInstallChangedListener#vmRemoved(org.eclipse.jdt.launching.IVMInstall)
77          */

78         public void vmRemoved(IVMInstall removedVm) {
79             fParticipantMap.remove(removedVm);
80             fRuleCache.remove(removedVm);
81         }
82     };
83         
84     
85     /**
86      * The backing <code>IConfigurationElement</code>
87      */

88     private IConfigurationElement fElement;
89     
90     /**
91      * Environment specific rule participant or <code>null</code> if none.
92      */

93     private IAccessRuleParticipant fRuleParticipant;
94     
95     /**
96      * Set of compatible vm's - just the strictly compatible ones
97      */

98     private Set JavaDoc fStrictlyCompatible = new HashSet JavaDoc();
99     
100     /**
101      * All compatible vm's
102      */

103     private List JavaDoc fCompatibleVMs = new ArrayList JavaDoc();
104     
105     /**
106      * default vm install or <code>null</code> if none
107      */

108     private IVMInstall fDefault = null;
109     
110     /**
111      * Cache of access rule participants to consider for this environment.
112      */

113     private IAccessRuleParticipant[] fParticipants = null;
114     
115     /**
116      * Map of {IVMInstall -> Map of {participant -> IAccessRule[][]}}.
117      * Caches access rules returned by each participant for a given VM.
118      * @since 3.3
119      */

120     private Map JavaDoc fParticipantMap = new HashMap JavaDoc();
121     
122     /**
123      * Cache of VM -> IAccessRule[][] based on the current state of the participant
124      * map. These are the union of the latest rules generated by the participants
125      * for a specific VM.
126      * @since 3.3
127      */

128     private Map JavaDoc fRuleCache = new HashMap JavaDoc();
129     
130     /**
131      * Wild card pattern matching all files
132      */

133     private static final IPath ALL_PATTERN = new Path("**/*"); //$NON-NLS-1$
134

135     /**
136      * Constructor
137      * @param element
138      */

139     ExecutionEnvironment(IConfigurationElement element) {
140         fElement = element;
141         String JavaDoc attribute = fElement.getAttribute(EnvironmentsManager.RULE_PARTICIPANT_ELEMENT);
142         if (attribute != null) {
143             fRuleParticipant = new AccessRuleParticipant(fElement);
144         }
145         JavaRuntime.addVMInstallChangedListener(fListener);
146     }
147     
148     /**
149      * Initializes the <code>EnvironmentsManager</code>
150      */

151     private void init() {
152         EnvironmentsManager.getDefault().initializeCompatibilities();
153     }
154
155     /* (non-Javadoc)
156      * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#getId()
157      */

158     public String JavaDoc getId() {
159         return fElement.getAttribute("id"); //$NON-NLS-1$
160
}
161
162     /* (non-Javadoc)
163      * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#getDescription()
164      */

165     public String JavaDoc getDescription() {
166         return fElement.getAttribute("description"); //$NON-NLS-1$
167
}
168
169     /* (non-Javadoc)
170      * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#getCompatibleVMs()
171      */

172     public IVMInstall[] getCompatibleVMs() {
173         init();
174         return (IVMInstall[]) fCompatibleVMs.toArray(new IVMInstall[fCompatibleVMs.size()]);
175     }
176
177     /* (non-Javadoc)
178      * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#isStrictlyCompatible(org.eclipse.jdt.launching.IVMInstall)
179      */

180     public boolean isStrictlyCompatible(IVMInstall vm) {
181         init();
182         return fStrictlyCompatible.contains(vm);
183     }
184
185     /* (non-Javadoc)
186      * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#getDefaultVM()
187      */

188     public IVMInstall getDefaultVM() {
189         init();
190         return fDefault;
191     }
192
193     /* (non-Javadoc)
194      * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#setDefaultVM(org.eclipse.jdt.launching.IVMInstall)
195      */

196     public void setDefaultVM(IVMInstall vm) {
197         init();
198         if (vm != null && !fCompatibleVMs.contains(vm)) {
199             throw new IllegalArgumentException JavaDoc(MessageFormat.format(EnvironmentMessages.EnvironmentsManager_0, new String JavaDoc[]{getId()}));
200         }
201         if (vm != null && vm.equals(fDefault)) {
202             return;
203         }
204         fDefault = vm;
205         EnvironmentsManager.getDefault().updateDefaultVMs();
206         // update classpath containers
207
rebindClasspathContainers();
208     }
209
210     /**
211      * Updates Java projects referencing this environment, if any.
212      */

213     private void rebindClasspathContainers() {
214         IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
215         if (model != null) {
216             try {
217                 List JavaDoc updates = new ArrayList JavaDoc();
218                 IJavaProject[] javaProjects = model.getJavaProjects();
219                 IPath path = JavaRuntime.newJREContainerPath(this);
220                 for (int i = 0; i < javaProjects.length; i++) {
221                     IJavaProject project = javaProjects[i];
222                     IClasspathEntry[] rawClasspath = project.getRawClasspath();
223                     for (int j = 0; j < rawClasspath.length; j++) {
224                         IClasspathEntry entry = rawClasspath[j];
225                         if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
226                             if (entry.getPath().equals(path)) {
227                                 updates.add(project);
228                             }
229                         }
230                     }
231                 }
232                 if (!updates.isEmpty()) {
233                     JavaCore.setClasspathContainer(path,
234                             (IJavaProject[]) updates.toArray(new IJavaProject[updates.size()]),
235                             new IClasspathContainer[updates.size()],
236                             new NullProgressMonitor());
237                 }
238             } catch (JavaModelException e) {
239                 LaunchingPlugin.log(e);
240             }
241         }
242     }
243
244     /**
245      * Adds the specified vm to the listing of compatible vms, also
246      * adds the vm to the listing of stricly compatible ones based on
247      * the strictlyCompatible flag
248      * @param vm
249      * @param strictlyCompatible
250      */

251     void add(IVMInstall vm, boolean strictlyCompatible) {
252         if (fCompatibleVMs.contains(vm)) {
253             return;
254         }
255         fCompatibleVMs.add(vm);
256         if (strictlyCompatible) {
257             fStrictlyCompatible.add(vm);
258         }
259     }
260     
261     /**
262      * Removes the specified vm from the listings of vms
263      * @param vm
264      */

265     void remove(IVMInstall vm) {
266         fCompatibleVMs.remove(vm);
267         fStrictlyCompatible.remove(vm);
268     }
269     
270     /**
271      * Sets the default vm to be the one specified
272      * @param vm
273      */

274     void initDefaultVM(IVMInstall vm) {
275         fDefault = vm;
276     }
277
278     /* (non-Javadoc)
279      * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#getAccessRules(org.eclipse.jdt.launching.IVMInstall, org.eclipse.jdt.launching.LibraryLocation[], org.eclipse.jdt.core.IJavaProject)
280      */

281     public IAccessRule[][] getAccessRules(IVMInstall vm, LibraryLocation[] libraries, IJavaProject project) {
282         IAccessRuleParticipant[] participants = getParticipants();
283         Map JavaDoc rulesByParticipant = collectRulesByParticipant(participants, vm, libraries, project);
284         synchronized (this) {
285             Map JavaDoc cachedRules = (Map JavaDoc) fParticipantMap.get(vm);
286             if (cachedRules == null || !cachedRules.equals(rulesByParticipant)) {
287                 List JavaDoc[] libLists = new List JavaDoc[libraries.length]; // array of lists of access rules
288
for (int i = 0; i < libLists.length; i++) {
289                     libLists[i] = new ArrayList JavaDoc();
290                 }
291                 for (int i = 0; i < participants.length; i++) {
292                     IAccessRuleParticipant participant = participants[i];
293                     addRules((IAccessRule[][]) rulesByParticipant.get(participant), libLists);
294                 }
295                 IAccessRule[][] allRules = new IAccessRule[libraries.length][];
296                 for (int i = 0; i < libLists.length; i++) {
297                     allRules[i] = (IAccessRule[]) libLists[i].toArray(new IAccessRule[libLists[i].size()]);
298                 }
299                 fParticipantMap.put(vm, rulesByParticipant);
300                 fRuleCache.put(vm, allRules);
301                 return allRules;
302             } else {
303                 return (IAccessRule[][]) fRuleCache.get(vm);
304             }
305         }
306     }
307     
308     /**
309      * Returns all access rule participants to consider for this environment.
310      * Includes any participant contributed with this environment and all other
311      * stand alone participants.
312      *
313      * @return access rule participants to consider for this environment
314      */

315     private synchronized IAccessRuleParticipant[] getParticipants() {
316         if (fParticipants == null) {
317             // check participants first
318
IAccessRuleParticipant[] participants = EnvironmentsManager.getDefault().getAccessRuleParticipants();
319             if (fRuleParticipant != null) {
320                 // check default provider last
321
IAccessRuleParticipant[] copy = new IAccessRuleParticipant[participants.length + 1];
322                 System.arraycopy(participants, 0, copy, 0, participants.length);
323                 copy[participants.length] = fRuleParticipant;
324                 participants = copy;
325             }
326             fParticipants = participants;
327         }
328         return fParticipants;
329     }
330     
331     /**
332      * Returns a map of participant to the access rules for that participant for the given
333      * vm, libraries, and project.
334      *
335      * @param participants
336      * @return
337      */

338     private Map JavaDoc collectRulesByParticipant(IAccessRuleParticipant[] participants, IVMInstall vm, LibraryLocation[] libraries, IJavaProject project) {
339         Map JavaDoc map = new HashMap JavaDoc();
340         for (int i = 0; i < participants.length; i++) {
341             // TODO: use safe runnable
342
map.put(participants[i], participants[i].getAccessRules(this, vm, libraries, project));
343         }
344         return map;
345     }
346     
347     /**
348      * Adds the access rules to each list in the given collection. If the last rule in a
349      * given collection is the wild card pattern then no more rules are added to that collection.
350      */

351     private void addRules(IAccessRule[][] accessRules, List JavaDoc[] collect) {
352         for (int i = 0; i < accessRules.length; i++) {
353             IAccessRule[] libRules = accessRules[i];
354             List JavaDoc list = collect[i];
355             // if the last rule is a **/* pattern, don't add any more rules, as they will have no effect
356
if (!list.isEmpty()) {
357                 IAccessRule lastRule = (IAccessRule) list.get(list.size() - 1);
358                 if(lastRule.getPattern().equals(ALL_PATTERN)) {
359                     continue;
360                 }
361             }
362             for (int j = 0; j < libRules.length; j++) {
363                 list.add(libRules[j]);
364             }
365         }
366     }
367     
368 }
369
Popular Tags