Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java')
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java49
1 files changed, 38 insertions, 11 deletions
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java
index 0c2aebb92..98c20127d 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -580,8 +580,9 @@ public class BaseAdaptor implements FrameworkAdaptor {
* @see BundleWiring#listResources(String, String, int)
*/
public List<String> listEntryPaths(List<BundleFile> bundleFiles, String path, String filePattern, int options) {
- // a list used to store the results of the search
- List<String> pathList = new ArrayList<String>();
+ // Store the results of the search. Use LinkedHashSet for optimized
+ // performance of contains() plus ordering guarantees.
+ LinkedHashSet<String> pathList = new LinkedHashSet<String>();
Filter patternFilter = null;
Hashtable<String, String> patternProps = null;
if (filePattern != null) {
@@ -596,7 +597,7 @@ public class BaseAdaptor implements FrameworkAdaptor {
if (bundleFile.getEntry(path) != null && !pathList.contains(path))
pathList.add(path);
}
- return pathList;
+ return new ArrayList<String>(pathList);
}
// For when the file pattern includes a wildcard.
try {
@@ -608,14 +609,14 @@ public class BaseAdaptor implements FrameworkAdaptor {
// something unexpected happened; log error and return nothing
Bundle b = context == null ? null : context.getBundle();
eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, b, e);
- return pathList;
+ return new ArrayList<String>(pathList);
}
}
// find the entry paths for the datas
for (BundleFile bundleFile : bundleFiles) {
listEntryPaths(bundleFile, path, patternFilter, patternProps, options, pathList);
}
- return pathList;
+ return new ArrayList<String>(pathList);
}
private String sanitizeFilterInput(String filePattern) throws InvalidSyntaxException {
@@ -658,10 +659,35 @@ public class BaseAdaptor implements FrameworkAdaptor {
return buffer == null ? filePattern : buffer.toString();
}
- private List<String> listEntryPaths(BundleFile bundleFile, String path, Filter patternFilter, Hashtable<String, String> patternProps, int options, List<String> pathList) {
+ // Use LinkedHashSet for optimized performance of contains() plus ordering
+ // guarantees.
+ private LinkedHashSet<String> listEntryPaths(BundleFile bundleFile, String path, Filter patternFilter, Hashtable<String, String> patternProps, int options, LinkedHashSet<String> pathList) {
if (pathList == null)
- pathList = new ArrayList<String>();
- Enumeration<String> entryPaths = bundleFile.getEntryPaths(path);
+ pathList = new LinkedHashSet<String>();
+ // Set a local flag indicating whether or not this method should use the
+ // original, unoptimized recursion at the end.
+ boolean isRecursive = false;
+ if ((options & BundleWiring.FINDENTRIES_RECURSE) != 0) {
+ // Recursion was requested. Set the thread local to indicate that
+ // participating bundle files should return entry paths
+ // recursively on the first call.
+ ListEntryPathsThreadLocal.setRecursive(true);
+ }
+ Enumeration<String> entryPaths;
+ // Let the bundle file do its work.
+ try {
+ entryPaths = bundleFile.getEntryPaths(path);
+ if ((options & BundleWiring.FINDENTRIES_RECURSE) != 0) {
+ // Since recursion was requested, set the value of the local
+ // recursion flag to the value of the thread local. If the bundle
+ // file used recursion, it will set the thread local back to false;
+ // otherwise, it will still be true.
+ isRecursive = ListEntryPathsThreadLocal.isRecursive();
+ }
+ } finally {
+ // Reset the thread local value to its default.
+ ListEntryPathsThreadLocal.setRecursive(false);
+ }
if (entryPaths == null)
return pathList;
while (entryPaths.hasMoreElements()) {
@@ -689,8 +715,9 @@ public class BaseAdaptor implements FrameworkAdaptor {
// prevent duplicates and match on the patternFilter
if (!pathList.contains(entry) && (patternFilter == null || patternFilter.matchCase(patternProps)))
pathList.add(entry);
- // recurse only into entries that are directories
- if (((options & BundleWiring.FINDENTRIES_RECURSE) != 0) && !entry.equals(path) && entry.length() > 0 && lastSlash == (entry.length() - 1))
+ // recurse only into entries that are directories and only if the
+ // bundle file did not do the recursion itself
+ if (isRecursive && !entry.equals(path) && entry.length() > 0 && lastSlash == (entry.length() - 1))
listEntryPaths(bundleFile, entry, patternFilter, patternProps, options, pathList);
}
return pathList;

Back to the top