### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.launching Index: launching/org/eclipse/jdt/internal/launching/JREContainer.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JREContainer.java,v retrieving revision 1.24 diff -u -r1.24 JREContainer.java --- launching/org/eclipse/jdt/internal/launching/JREContainer.java 13 Dec 2006 21:46:12 -0000 1.24 +++ launching/org/eclipse/jdt/internal/launching/JREContainer.java 17 Apr 2007 21:26:24 -0000 @@ -65,6 +65,30 @@ public static boolean DEBUG_JRE_CONTAINER = false; /** + * Map of {IVMInstall -> Map of {{IExeuctionEnvironment, IAccessRule[][]} -> {IClasspathEntry[]}} + */ + private static Map fgClasspathEntriesWithRules = new HashMap(10); + + static class RuleKey { + String environmentId; + IAccessRule[][] accessRules; + public RuleKey(String id, IAccessRule[][] r) { + environmentId = id; + accessRules = r; + } + public boolean equals(Object obj) { + if (obj instanceof RuleKey) { + RuleKey key = (RuleKey) obj; + return environmentId.equals(key.environmentId) && accessRules.equals(key.accessRules); + } + return false; + } + public int hashCode() { + return environmentId.hashCode() + accessRules.hashCode(); + } + } + + /** * Add a vm changed listener to clear cached values when a VM changes or is removed */ static { @@ -75,6 +99,7 @@ public void vmChanged(PropertyChangeEvent event) { if (event.getSource() != null) { fgClasspathEntries.remove(event.getSource()); + fgClasspathEntriesWithRules.remove(event.getSource()); } } @@ -83,6 +108,7 @@ public void vmRemoved(IVMInstall removedVm) { fgClasspathEntries.remove(removedVm); + fgClasspathEntriesWithRules.remove(removedVm); } }; JavaRuntime.addVMInstallChangedListener(listener); @@ -149,6 +175,21 @@ rules = environment.getAccessRules(vm, libs, project); } } + RuleKey key = null; + Map map = null; + IClasspathEntry[] cachedEntries = null; + if (rules != null && environmentId != null) { + key = new RuleKey(environmentId, rules); + map = (Map) fgClasspathEntriesWithRules.get(vm); + if (map == null) { + map = new HashMap(); + fgClasspathEntriesWithRules.put(vm, map); + } + cachedEntries = (IClasspathEntry[]) map.get(key); + } + if (cachedEntries != null) { + return cachedEntries; + } List entries = new ArrayList(libs.length); for (int i = 0; i < libs.length; i++) { if (!libs[i].getSystemLibraryPath().isEmpty()) { @@ -179,10 +220,23 @@ entries.add(JavaCore.newLibraryEntry(libs[i].getSystemLibraryPath(), sourcePath, rootPath, libRules, attributes, false)); } } - return (IClasspathEntry[])entries.toArray(new IClasspathEntry[entries.size()]); + IClasspathEntry[] cpEntries = (IClasspathEntry[])entries.toArray(new IClasspathEntry[entries.size()]); + if (key != null && map != null) { + map.put(key, cpEntries); + } + return cpEntries; } /** + * @param vm + * @return + */ + private static Map fgClasspathEntriesWithRules(IVMInstall vm) { + // TODO Auto-generated method stub + return null; + } + + /** * Constructs a JRE classpath container on the given VM install * * @param vm vm install - cannot be null Index: launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java,v retrieving revision 1.10 diff -u -r1.10 ExecutionEnvironment.java --- launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java 1 Dec 2006 16:37:42 -0000 1.10 +++ launching/org/eclipse/jdt/internal/launching/environments/ExecutionEnvironment.java 17 Apr 2007 21:26:24 -0000 @@ -11,8 +11,10 @@ package org.eclipse.jdt.internal.launching.environments; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.core.resources.ResourcesPlugin; @@ -66,6 +68,24 @@ private IVMInstall fDefault = null; /** + * Cache of access rule participants to consider for this environment. + */ + private IAccessRuleParticipant[] fParticipants = null; + + /** + * Map of {IVMInstall -> Map of {participant -> IAccessRule[][]}}. + * Caches access rules returned by each participant for a given VM. + */ + private Map fParticipantMap = new HashMap(); + + /** + * Cache of VM -> IAccessRule[][] based on the current state of the participant + * map. These are the union of the latest rules generated by the participants + * for a specific VM. + */ + private Map fRuleCache = new HashMap(); + + /** * Wild card pattern matching all files */ private static final IPath ALL_PATTERN = new Path("**/*"); //$NON-NLS-1$ @@ -195,29 +215,77 @@ * @see org.eclipse.jdt.launching.environments.IExecutionEnvironment#getAccessRules(org.eclipse.jdt.launching.IVMInstall, org.eclipse.jdt.launching.LibraryLocation[], org.eclipse.jdt.core.IJavaProject) */ public IAccessRule[][] getAccessRules(IVMInstall vm, LibraryLocation[] libraries, IJavaProject project) { - List[] libLists = new List[libraries.length]; // array of lists of access rules - for (int i = 0; i < libLists.length; i++) { - libLists[i] = new ArrayList(); - } - // check participants first - IAccessRuleParticipant[] participants = EnvironmentsManager.getDefault().getAccessRuleParticipants(); - for (int i = 0; i < participants.length; i++) { - processParticipant(participants[i], libLists, vm, libraries, project); + IAccessRuleParticipant[] participants = getParticipants(); + Map rulesByParticipant = collectRulesByParticipant(participants, vm, libraries, project); + synchronized (this) { + Map cachedRules = (Map) fParticipantMap.get(vm); + if (cachedRules == null || !cachedRules.equals(rulesByParticipant)) { + List[] libLists = new List[libraries.length]; // array of lists of access rules + for (int i = 0; i < libLists.length; i++) { + libLists[i] = new ArrayList(); + } + for (int i = 0; i < participants.length; i++) { + IAccessRuleParticipant participant = participants[i]; + addRules((IAccessRule[][]) rulesByParticipant.get(participant), libLists); + } + IAccessRule[][] allRules = new IAccessRule[libraries.length][]; + for (int i = 0; i < libLists.length; i++) { + allRules[i] = (IAccessRule[]) libLists[i].toArray(new IAccessRule[libLists[i].size()]); + } + fParticipantMap.put(vm, rulesByParticipant); + fRuleCache.put(vm, allRules); + return allRules; + } else { + return (IAccessRule[][]) fRuleCache.get(vm); + } } - // check default provider last - if (fRuleParticipant != null) { - processParticipant(fRuleParticipant, libLists, vm, libraries, project); + } + + /** + * Returns all access rule participants to consider for this environment. + * Includes any participant contributed with this environment and all other + * stand alone participants. + * + * @return access rule participants to consider for this environment + */ + private synchronized IAccessRuleParticipant[] getParticipants() { + if (fParticipants == null) { + // check participants first + IAccessRuleParticipant[] participants = EnvironmentsManager.getDefault().getAccessRuleParticipants(); + if (fRuleParticipant != null) { + // check default provider last + IAccessRuleParticipant[] copy = new IAccessRuleParticipant[participants.length + 1]; + System.arraycopy(participants, 0, copy, 0, participants.length); + copy[participants.length] = fRuleParticipant; + participants = copy; + } + fParticipants = participants; } - IAccessRule[][] allRules = new IAccessRule[libraries.length][]; - for (int i = 0; i < libLists.length; i++) { - allRules[i] = (IAccessRule[]) libLists[i].toArray(new IAccessRule[libLists[i].size()]); + return fParticipants; + } + + /** + * Returns a map of participant to the access rules for that participant for the given + * vm, libraries, and project. + * + * @param participants + * @return + */ + private Map collectRulesByParticipant(IAccessRuleParticipant[] participants, IVMInstall vm, LibraryLocation[] libraries, IJavaProject project) { + Map map = new HashMap(); + for (int i = 0; i < participants.length; i++) { + IAccessRuleParticipant participant = participants[i]; + // TODO: use safe runnable + map.put(participant, participant.getAccessRules(this, vm, libraries, project)); } - return allRules; + return map; } - private void processParticipant(IAccessRuleParticipant participant, List[] collect, IVMInstall vm, LibraryLocation[] libraries, IJavaProject project) { - // TODO: use safe runnables - IAccessRule[][] accessRules = participant.getAccessRules(this, vm, libraries, project); + /** + * Adds the access rules to each list in the given collection. If the last rule in a + * given collection is the wild card pattern then no more rules are added to that collection. + */ + private void addRules(IAccessRule[][] accessRules, List[] collect) { for (int i = 0; i < accessRules.length; i++) { IAccessRule[] libRules = accessRules[i]; List list = collect[i]; @@ -233,4 +301,5 @@ } } } + }