Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.osgi.compatibility.plugins/src/org/eclipse/osgi/compatibility/plugins/PluginConverterHook.java46
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/BundleFileWrapperFactoryHook.java5
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java7
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java49
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java18
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java30
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/SystemBundleFile.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleEntry.java3
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFile.java28
-rwxr-xr-xbundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapper.java86
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapperChain.java44
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirBundleFile.java42
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirZipBundleEntry.java3
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/FileBundleEntry.java1
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java3
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java7
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleEntry.java3
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleFile.java45
20 files changed, 232 insertions, 200 deletions
diff --git a/bundles/org.eclipse.osgi.compatibility.plugins/src/org/eclipse/osgi/compatibility/plugins/PluginConverterHook.java b/bundles/org.eclipse.osgi.compatibility.plugins/src/org/eclipse/osgi/compatibility/plugins/PluginConverterHook.java
index 392155ee3..b7fd91719 100644
--- a/bundles/org.eclipse.osgi.compatibility.plugins/src/org/eclipse/osgi/compatibility/plugins/PluginConverterHook.java
+++ b/bundles/org.eclipse.osgi.compatibility.plugins/src/org/eclipse/osgi/compatibility/plugins/PluginConverterHook.java
@@ -12,14 +12,23 @@ package org.eclipse.osgi.compatibility.plugins;
import java.io.File;
import java.io.IOException;
-import java.util.Enumeration;
+
import org.eclipse.osgi.framework.util.Headers;
-import org.eclipse.osgi.internal.hookregistry.*;
+import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
+import org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook;
+import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
+import org.eclipse.osgi.internal.hookregistry.HookRegistry;
import org.eclipse.osgi.service.pluginconversion.PluginConversionException;
import org.eclipse.osgi.service.pluginconversion.PluginConverter;
import org.eclipse.osgi.storage.BundleInfo.Generation;
-import org.eclipse.osgi.storage.bundlefile.*;
-import org.osgi.framework.*;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
+import org.eclipse.osgi.storage.bundlefile.FileBundleEntry;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
public class PluginConverterHook implements HookConfigurator {
@Override
@@ -34,26 +43,11 @@ public class PluginConverterHook implements HookConfigurator {
hookRegistry.addBundleFileWrapperFactoryHook(new BundleFileWrapperFactoryHook() {
@Override
- public BundleFile wrapBundleFile(final BundleFile bundleFile, Generation generation, boolean base) {
+ public BundleFileWrapper wrapBundleFile(final BundleFile bundleFile, Generation generation, boolean base) {
if (!base) {
return null;
}
- return new BundleFile(bundleFile.getBaseFile()) {
-
- @Override
- public void open() throws IOException {
- bundleFile.open();
- }
-
- @Override
- public File getFile(String path, boolean nativeCode) {
- return bundleFile.getFile(path, nativeCode);
- }
-
- @Override
- public Enumeration<String> getEntryPaths(String path) {
- return bundleFile.getEntryPaths(path);
- }
+ return new BundleFileWrapper(bundleFile) {
@Override
public BundleEntry getEntry(String path) {
@@ -85,16 +79,6 @@ public class PluginConverterHook implements HookConfigurator {
throw new RuntimeException(e);
}
}
-
- @Override
- public boolean containsDir(String dir) {
- return bundleFile.containsDir(dir);
- }
-
- @Override
- public void close() throws IOException {
- bundleFile.close();
- }
};
}
});
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java
index 77adecca1..c519ad8b1 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/DiscardBundleTests.java
@@ -145,6 +145,10 @@ public class DiscardBundleTests extends AbstractBundleTests {
try {
equinox = restart(equinox, configuration);
assertNotDiscarded(location, equinox);
+ // Attempting to touch the file with equinox still running
+ // will sometimes result in failure presumably due to a locked
+ // file.
+ stop(equinox);
touchFile(bundleFile);
equinox = restart(equinox, configuration);
if (discard)
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/BundleFileWrapperFactoryHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/BundleFileWrapperFactoryHook.java
index d2e4e55d6..cfcfc492c 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/BundleFileWrapperFactoryHook.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/BundleFileWrapperFactoryHook.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 2012, 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
@@ -13,6 +13,7 @@ package org.eclipse.osgi.internal.hookregistry;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
/**
* A factory that wraps bundle file objects.
@@ -27,6 +28,6 @@ public interface BundleFileWrapperFactoryHook {
* @return a wrapped bundle file for the specified content, or null if the bundle content
* is not wrapped.
*/
- BundleFile wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base);
+ BundleFileWrapper wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base);
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java
index b1d50d316..ddda31ffd 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java
@@ -213,10 +213,11 @@ public class BundleLoader implements ModuleLoader {
if (System.getSecurityManager() == null) {
classloader = createClassLoaderPrivledged(parent, generation.getBundleInfo().getStorage().getConfiguration(), this, generation, hooks);
} else {
+ final ClassLoader cl = parent;
classloader = AccessController.doPrivileged(new PrivilegedAction<ModuleClassLoader>() {
@Override
public ModuleClassLoader run() {
- return createClassLoaderPrivledged(parent, generation.getBundleInfo().getStorage().getConfiguration(), BundleLoader.this, generation, hooks);
+ return createClassLoaderPrivledged(cl, generation.getBundleInfo().getStorage().getConfiguration(), BundleLoader.this, generation, hooks);
}
});
}
@@ -678,7 +679,9 @@ public class BundleLoader implements ModuleLoader {
}
boolean localSearch = (options & BundleWiring.LISTRESOURCES_LOCAL) != 0;
- List<String> result = new ArrayList<String>();
+ // Use LinkedHashSet for optimized performance of contains() plus
+ // ordering guarantees.
+ LinkedHashSet<String> result = new LinkedHashSet<String>();
Set<String> importedPackages = new HashSet<String>(0);
for (String name : packages) {
// look for import source
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
index dc20915ba..f1763777f 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2012 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2007, 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 http://www.eclipse.org/legal/epl-v10.html
@@ -36,7 +36,7 @@ public class SignatureBlockProcessor implements SignedContentConstants {
}
public SignedContentImpl process() throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
- BundleFile wrappedBundleFile = signedBundle.getWrappedBundleFile();
+ BundleFile wrappedBundleFile = signedBundle.getBundleFile();
BundleEntry be = wrappedBundleFile.getEntry(META_INF_MANIFEST_MF);
if (be == null)
return createUnsignedContent();
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
index ab610f238..e9127878a 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2012 IBM Corporation and others.
+ * Copyright (c) 2006, 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
@@ -11,15 +11,14 @@
package org.eclipse.osgi.internal.signedcontent;
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.security.*;
import java.security.cert.*;
import java.util.Date;
-import java.util.Enumeration;
import org.eclipse.osgi.signedcontent.*;
-import org.eclipse.osgi.storage.bundlefile.BundleEntry;
-import org.eclipse.osgi.storage.bundlefile.BundleFile;
+import org.eclipse.osgi.storage.bundlefile.*;
import org.eclipse.osgi.util.NLS;
/**
@@ -27,21 +26,19 @@ import org.eclipse.osgi.util.NLS;
* signatures. It requires full signing of the manifest by all signers. If no
* signatures are found, the classes and resources are retrieved without checks.
*/
-public class SignedBundleFile extends BundleFile implements SignedContentConstants, SignedContent {
- private BundleFile wrappedBundleFile;
+public class SignedBundleFile extends BundleFileWrapper implements SignedContentConstants, SignedContent {
SignedContentImpl signedContent;
private final int supportFlags;
private final SignedBundleHook signedBundleHook;
- SignedBundleFile(SignedContentImpl signedContent, int supportFlags, SignedBundleHook signedBundleHook) {
- super(null);
+ SignedBundleFile(BundleFile bundleFile, SignedContentImpl signedContent, int supportFlags, SignedBundleHook signedBundleHook) {
+ super(bundleFile);
this.signedContent = signedContent;
this.supportFlags = supportFlags;
this.signedBundleHook = signedBundleHook;
}
- void setBundleFile(BundleFile bundleFile) throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
- wrappedBundleFile = bundleFile;
+ void initializeSignedContent() throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
if (signedContent == null) {
SignatureBlockProcessor signatureProcessor = new SignatureBlockProcessor(this, supportFlags, signedBundleHook);
signedContent = signatureProcessor.process();
@@ -50,15 +47,11 @@ public class SignedBundleFile extends BundleFile implements SignedContentConstan
}
}
- public File getFile(String path, boolean nativeCode) {
- return wrappedBundleFile.getFile(path, nativeCode);
- }
-
public BundleEntry getEntry(String path) {
// strip off leading slashes so we can ensure the path matches the one provided in the manifest.
if (path.length() > 0 && path.charAt(0) == '/')
path = path.substring(1);
- BundleEntry be = wrappedBundleFile.getEntry(path);
+ BundleEntry be = getBundleFile().getEntry(path);
if ((supportFlags & SignedBundleHook.VERIFY_RUNTIME) == 0 || signedContent == null)
return be;
if (path.startsWith(META_INF)) {
@@ -82,26 +75,6 @@ public class SignedBundleFile extends BundleFile implements SignedContentConstan
return new SignedBundleEntry(be);
}
- public Enumeration<String> getEntryPaths(String path) {
- return wrappedBundleFile.getEntryPaths(path);
- }
-
- public void close() throws IOException {
- wrappedBundleFile.close();
- }
-
- public void open() throws IOException {
- wrappedBundleFile.open();
- }
-
- public boolean containsDir(String dir) {
- return wrappedBundleFile.containsDir(dir);
- }
-
- public File getBaseFile() {
- return wrappedBundleFile.getBaseFile();
- }
-
class SignedBundleEntry extends BundleEntry {
BundleEntry nestedEntry;
@@ -138,10 +111,6 @@ public class SignedBundleFile extends BundleFile implements SignedContentConstan
}
- BundleFile getWrappedBundleFile() {
- return wrappedBundleFile;
- }
-
SignedContentImpl getSignedContent() {
return signedContent;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java
index fe0fcebb3..45ea87b0d 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java
@@ -146,26 +146,26 @@ public class SignedBundleHook implements ActivatorHookFactory, BundleFileWrapper
}
}
- public BundleFile wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) {
+ public BundleFileWrapper wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) {
try {
if (bundleFile != null) {
StorageHookImpl hook = generation.getStorageHook(SignedStorageHook.class);
SignedBundleFile signedBaseFile;
if (base && hook != null) {
- signedBaseFile = new SignedBundleFile(hook.signedContent, supportSignedBundles, this);
+ signedBaseFile = new SignedBundleFile(bundleFile, hook.signedContent, supportSignedBundles, this);
if (hook.signedContent == null) {
- signedBaseFile.setBundleFile(bundleFile);
+ signedBaseFile.initializeSignedContent();
SignedContentImpl signedContent = signedBaseFile.getSignedContent();
hook.signedContent = signedContent != null && signedContent.isSigned() ? signedContent : null;
}
} else
- signedBaseFile = new SignedBundleFile(null, supportSignedBundles, this);
- signedBaseFile.setBundleFile(bundleFile);
+ signedBaseFile = new SignedBundleFile(bundleFile, null, supportSignedBundles, this);
+ signedBaseFile.initializeSignedContent();
SignedContentImpl signedContent = signedBaseFile.getSignedContent();
if (signedContent != null && signedContent.isSigned()) {
// only use the signed file if there are certs
signedContent.setContent(signedBaseFile);
- bundleFile = signedBaseFile;
+ return new BundleFileWrapper(signedBaseFile);
}
}
} catch (IOException e) {
@@ -173,7 +173,7 @@ public class SignedBundleHook implements ActivatorHookFactory, BundleFileWrapper
} catch (GeneralSecurityException e) {
log("Bad bundle file: " + bundleFile.getBaseFile(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
}
- return bundleFile;
+ return null;
}
public void addHooks(HookRegistry hookRegistry) {
@@ -210,9 +210,9 @@ public class SignedBundleHook implements ActivatorHookFactory, BundleFileWrapper
temp.close();
contentBundleFile = new ZipBundleFile(content, null, null, container.getConfiguration().getDebug());
}
- SignedBundleFile result = new SignedBundleFile(null, VERIFY_ALL, this);
+ SignedBundleFile result = new SignedBundleFile(contentBundleFile, null, VERIFY_ALL, this);
try {
- result.setBundleFile(contentBundleFile);
+ result.initializeSignedContent();
} catch (InvalidKeyException e) {
throw (InvalidKeyException) new InvalidKeyException(NLS.bind(SignedContentMessages.Factory_SignedContent_Error, content)).initCause(e);
} catch (SignatureException e) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
index fe4d81c69..318f78bc0 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java
@@ -864,7 +864,7 @@ public class Storage {
List<BundleFileWrapperFactoryHook> wrapperFactories = getConfiguration().getHookRegistry().getBundleFileWrapperFactoryHooks();
BundleFileWrapperChain wrapped = wrapperFactories.isEmpty() ? null : new BundleFileWrapperChain(bundleFile, null);
for (BundleFileWrapperFactoryHook wrapperFactory : wrapperFactories) {
- BundleFile wrapperBundle = wrapperFactory.wrapBundleFile(bundleFile, generation, isBase);
+ BundleFileWrapper wrapperBundle = wrapperFactory.wrapBundleFile(bundleFile, generation, isBase);
if (wrapperBundle != null && wrapperBundle != bundleFile)
bundleFile = wrapped = new BundleFileWrapperChain(wrapperBundle, wrapped);
}
@@ -1473,12 +1473,13 @@ public class Storage {
* @see BundleWiring#listResources(String, String, int)
*/
public static 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>();
+ // 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) {
- // Optimization: If the file pattern does not include a wildcard or escape char then it must represent a single file.
+ // Optimization: If the file pattern does not include a wildcard or escape char then it must represent a single file.
// Avoid pattern matching and use BundleFile.getEntry() if recursion was not requested.
if ((options & BundleWiring.FINDENTRIES_RECURSE) == 0 && filePattern.indexOf('*') == -1 && filePattern.indexOf('\\') == -1) {
if (path.length() == 0)
@@ -1489,7 +1490,7 @@ public class Storage {
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 {
@@ -1501,14 +1502,14 @@ public class Storage {
// TODO 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);
}
public static String sanitizeFilterInput(String filePattern) throws InvalidSyntaxException {
@@ -1551,10 +1552,16 @@ public class Storage {
return buffer == null ? filePattern : buffer.toString();
}
- private static 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 static 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>();
+ Enumeration<String> entryPaths;
+ if ((options & BundleWiring.FINDENTRIES_RECURSE) != 0)
+ entryPaths = bundleFile.getEntryPaths(path, true);
+ else
+ entryPaths = bundleFile.getEntryPaths(path);
if (entryPaths == null)
return pathList;
while (entryPaths.hasMoreElements()) {
@@ -1582,9 +1589,6 @@ public class Storage {
// 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))
- listEntryPaths(bundleFile, entry, patternFilter, patternProps, options, pathList);
}
return pathList;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/SystemBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/SystemBundleFile.java
index c75524400..002ab3739 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/SystemBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/SystemBundleFile.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 IBM Corporation and others.
+ * Copyright (c) 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
@@ -63,7 +63,7 @@ public class SystemBundleFile extends BundleFile {
}
@Override
- public Enumeration<String> getEntryPaths(String path) {
+ public Enumeration<String> getEntryPaths(String path, boolean recurse) {
return null;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleEntry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleEntry.java
index 7930b869a..735a6b2c6 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleEntry.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleEntry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2012 IBM Corporation and others.
+ * Copyright (c) 2004, 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
@@ -21,7 +21,6 @@ import org.eclipse.osgi.storage.StorageUtil;
* <p>
* Clients may extend this class.
* </p>
- * @since 3.2
*/
public abstract class BundleEntry {
protected static final int BUF_SIZE = 8 * 1024;
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFile.java
index 69d27fa32..e4ddde7fc 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFile.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2012 IBM Corporation and others.
+ * Copyright (c) 2004, 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
@@ -25,10 +25,10 @@ import org.eclipse.osgi.storage.url.bundleresource.Handler;
/**
* The BundleFile API is used by Adaptors to read resources out of an
* installed Bundle in the Framework.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.2
+ * <p/>
+ * Clients wishing to modify or extend the functionality of this class at
+ * runtime should extend the associated {@link BundleFileWrapper decorator}
+ * instead.
*/
abstract public class BundleFile {
static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction());
@@ -67,6 +67,18 @@ abstract public class BundleFile {
abstract public BundleEntry getEntry(String path);
/**
+ * Performs the same function as calling
+ * {@link #getEntryPaths(String, boolean)} with <code>recurse</code> equal
+ * to <code>false</code>.
+ * @param path path of the entry to locate in the bundle
+ * @return an Enumeration of Strings that indicate the paths found or
+ * null if the path does not exist.
+ */
+ public Enumeration<String> getEntryPaths(String path) {
+ return getEntryPaths(path, false);
+ }
+
+ /**
* Allows to access the entries of the bundle.
* Since the bundle content is usually a jar, this
* allows to access the jar contents.
@@ -77,10 +89,14 @@ abstract public class BundleFile {
* themselves. If a returned name is a directory, it finishes with a
* slash. If a returned name is a file, it does not finish with a slash.
* @param path path of the entry to locate in the bundle
+ * @param recurse - If <code>true</code>, provide entries for the files and
+ * directories within the directory denoted by <code>path</code> plus
+ * all sub-directories and files; otherwise, provide only the entries
+ * within the immediate directory.
* @return an Enumeration of Strings that indicate the paths found or
* null if the path does not exist.
*/
- abstract public Enumeration<String> getEntryPaths(String path);
+ abstract public Enumeration<String> getEntryPaths(String path, boolean recurse);
/**
* Closes the BundleFile.
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapper.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapper.java
new file mode 100755
index 000000000..33f59380e
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapper.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.storage.bundlefile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook;
+import org.eclipse.osgi.storage.BundleInfo;
+
+/**
+ * A {@link BundleFile bundle file} decorator.
+ * <p/>
+ * Clients wishing to modify or extend the behavior of a bundle file at runtime
+ * should extend this class instead. A hook is provided by the related {@link
+ * BundleFileWrapperFactoryHook abstract factory} class in response to a
+ * {@link BundleFileWrapperFactoryHook#wrapBundleFile(BundleFile,
+ * BundleInfo.Generation, boolean) call} from the framework.
+ */
+public class BundleFileWrapper extends BundleFile {
+ private final BundleFile bundleFile;
+
+ /**
+ * Creates a new <code>BundleFileWrapper</code> instance wrapping the
+ * given {@link BundleFile bundle file}.
+ *
+ * @param bundleFile - The bundle file to wrap.
+ * @throws NullPointerException - If the bundle file is <code>null</code>.
+ */
+ public BundleFileWrapper(BundleFile bundleFile) {
+ super(bundleFile.getBaseFile());
+ this.bundleFile = bundleFile;
+ }
+
+ @Override
+ public File getFile(String path, boolean nativeCode) {
+ return bundleFile.getFile(path, nativeCode);
+ }
+
+ @Override
+ public BundleEntry getEntry(String path) {
+ return bundleFile.getEntry(path);
+ }
+
+ @Override
+ public Enumeration<String> getEntryPaths(String path) {
+ return bundleFile.getEntryPaths(path);
+ }
+
+ @Override
+ public Enumeration<String> getEntryPaths(String path, boolean recurse) {
+ return bundleFile.getEntryPaths(path, recurse);
+ }
+
+ /**
+ * Get the wrapped bundle file.
+ *
+ * @return The wrapped bundle file.
+ */
+ public BundleFile getBundleFile() {
+ return bundleFile;
+ }
+
+ @Override
+ public void close() throws IOException {
+ bundleFile.close();
+ }
+
+ @Override
+ public void open() throws IOException {
+ bundleFile.open();
+ }
+
+ @Override
+ public boolean containsDir(String dir) {
+ return bundleFile.containsDir(dir);
+ }
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapperChain.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapperChain.java
index 3edf2eae0..6ad57ade2 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapperChain.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/BundleFileWrapperChain.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2012 IBM Corporation and others.
+ * Copyright (c) 2008, 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
@@ -11,59 +11,23 @@
package org.eclipse.osgi.storage.bundlefile;
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Enumeration;
-import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook;
/**
* Used to chain the BundleFile objects returned from {@link BundleFileWrapperFactoryHook}.
* This class is useful for traversing the chain of wrapped bundle files.
*/
-public class BundleFileWrapperChain extends BundleFile {
+public class BundleFileWrapperChain extends BundleFileWrapper {
private final BundleFile wrapped;
private final BundleFileWrapperChain next;
public BundleFileWrapperChain(BundleFile wrapped, BundleFileWrapperChain next) {
- super(null);
+ super(wrapped);
this.wrapped = wrapped;
this.next = next;
}
- public void close() throws IOException {
- wrapped.close();
- }
-
- public boolean containsDir(String dir) {
- return wrapped.containsDir(dir);
- }
-
- public BundleEntry getEntry(String path) {
- return wrapped.getEntry(path);
- }
-
- public Enumeration<String> getEntryPaths(String path) {
- return wrapped.getEntryPaths(path);
- }
-
- public File getFile(String path, boolean nativeCode) {
- return wrapped.getFile(path, nativeCode);
- }
-
- public void open() throws IOException {
- wrapped.open();
- }
-
- public File getBaseFile() {
- return wrapped.getBaseFile();
- }
-
- public URL getResourceURL(String path, Module hostModule, int index) {
- return wrapped.getResourceURL(path, hostModule, index);
- }
-
+ @Override
public String toString() {
return wrapped.toString();
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirBundleFile.java
index da8c15109..462892cd7 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirBundleFile.java
@@ -13,14 +13,12 @@ package org.eclipse.osgi.storage.bundlefile;
import java.io.File;
import java.io.IOException;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
+import java.util.*;
import org.eclipse.osgi.storage.StorageMsg;
import org.eclipse.osgi.util.NLS;
/**
* A BundleFile that uses a directory as its base file.
- * @since 3.2
*/
public class DirBundleFile extends BundleFile {
@@ -116,35 +114,29 @@ public class DirBundleFile extends BundleFile {
return dirPath != null && BundleFile.secureAction.isDirectory(dirPath);
}
- public Enumeration<String> getEntryPaths(String path) {
+ public Enumeration<String> getEntryPaths(String path, boolean recurse) {
if (path.length() > 0 && path.charAt(0) == '/')
path = path.substring(1);
- final File pathFile = getFile(path, false);
+ File pathFile = getFile(path, false);
if (pathFile == null || !BundleFile.secureAction.isDirectory(pathFile))
return null;
- final String[] fileList = BundleFile.secureAction.list(pathFile);
+ String[] fileList = BundleFile.secureAction.list(pathFile);
if (fileList == null || fileList.length == 0)
return null;
- final String dirPath = path.length() == 0 || path.charAt(path.length() - 1) == '/' ? path : path + '/';
- return new Enumeration<String>() {
- int cur = 0;
-
- public boolean hasMoreElements() {
- return fileList != null && cur < fileList.length;
- }
-
- public String nextElement() {
- if (!hasMoreElements()) {
- throw new NoSuchElementException();
- }
- java.io.File childFile = new java.io.File(pathFile, fileList[cur]);
- StringBuffer sb = new StringBuffer(dirPath).append(fileList[cur++]);
- if (BundleFile.secureAction.isDirectory(childFile)) {
- sb.append("/"); //$NON-NLS-1$
- }
- return sb.toString();
+ String dirPath = path.length() == 0 || path.charAt(path.length() - 1) == '/' ? path : path + '/';
+
+ LinkedHashSet<String> entries = new LinkedHashSet<String>();
+ for (String s : fileList) {
+ java.io.File childFile = new java.io.File(pathFile, s);
+ StringBuilder sb = new StringBuilder(dirPath).append(s);
+ if (BundleFile.secureAction.isDirectory(childFile)) {
+ sb.append("/"); //$NON-NLS-1$
+ if (recurse)
+ entries.addAll(Collections.list(getEntryPaths(sb.toString(), true)));
}
- };
+ entries.add(sb.toString());
+ }
+ return Collections.enumeration(entries);
}
public void close() {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirZipBundleEntry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirZipBundleEntry.java
index 0bb1cee5c..a4a7d261c 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirZipBundleEntry.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/DirZipBundleEntry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2012 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
@@ -19,7 +19,6 @@ import java.net.URL;
* Represents a directory entry in a ZipBundleFile. This object is used to
* reference a directory entry in a ZipBundleFile when the directory entries are
* not included in the zip file.
- * @since 3.2
*/
public class DirZipBundleEntry extends BundleEntry {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/FileBundleEntry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/FileBundleEntry.java
index 94bc8ee90..8a4f00a07 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/FileBundleEntry.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/FileBundleEntry.java
@@ -18,7 +18,6 @@ import java.net.URL;
/**
* A BundleEntry represented by a File object. The FileBundleEntry class is
* used for bundles that are installed as extracted zips on a file system.
- * @since 3.2
*/
public class FileBundleEntry extends BundleEntry {
/**
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java
index fcf148f75..06885d5e9 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/MRUBundleFileList.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2012 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
@@ -20,7 +20,6 @@ import org.eclipse.osgi.framework.eventmgr.*;
* track of open BundleFiles. The MRU will use the file limit specified by the property
* &quot;osgi.bundlefile.limit&quot; by default unless the MRU is constructed with a specific
* file limit.
- * @since 3.2
*/
public class MRUBundleFileList implements EventDispatcher<Object, Object, BundleFile> {
private static final int MIN = 10;
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java
index dea0669ce..718441417 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/NestedDirBundleFile.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2012 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
@@ -25,7 +25,6 @@ import java.util.Enumeration;
* <pre>
* Bundle-ClassPath: nested.jar,nesteddir/
* </pre>
- * @since 3.2
*/
public class NestedDirBundleFile extends BundleFile {
private final BundleFile baseBundleFile;
@@ -66,8 +65,8 @@ public class NestedDirBundleFile extends BundleFile {
return new StringBuffer(cp).append(path).toString();
}
- public Enumeration<String> getEntryPaths(String path) {
- final Enumeration<String> basePaths = baseBundleFile.getEntryPaths(prependNestedDir(path));
+ public Enumeration<String> getEntryPaths(String path, boolean recurse) {
+ final Enumeration<String> basePaths = baseBundleFile.getEntryPaths(prependNestedDir(path), recurse);
final int cpLength = cp.length();
if (basePaths == null)
return null;
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleEntry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleEntry.java
index 727e59d43..2c8671a4d 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleEntry.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleEntry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2012 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
@@ -19,7 +19,6 @@ import java.util.zip.ZipEntry;
/**
* A BundleEntry represented by a ZipEntry in a ZipFile. The ZipBundleEntry
* class is used for bundles that are installed as a ZipFile on a file system.
- * @since 3.2
*/
public class ZipBundleEntry extends BundleEntry {
/**
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleFile.java
index d8f796a48..eb291d8bc 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/ZipBundleFile.java
@@ -24,7 +24,6 @@ import org.eclipse.osgi.util.NLS;
/**
* A BundleFile that uses a ZipFile as it base file.
- * @since 3.2
*/
public class ZipBundleFile extends BundleFile {
@@ -255,39 +254,55 @@ public class ZipBundleFile extends BundleFile {
}
- public synchronized Enumeration<String> getEntryPaths(String path) {
- if (!checkedOpen())
- return null;
+ @Override
+ public synchronized Enumeration<String> getEntryPaths(String path, boolean recurse) {
if (path == null)
throw new NullPointerException();
+ // Is the zip file already open or, if not, can it be opened?
+ if (!checkedOpen())
+ return null;
+ // Strip any leading '/' off of path.
if (path.length() > 0 && path.charAt(0) == '/')
path = path.substring(1);
+ // Append a '/', if not already there, to path if not an empty string.
if (path.length() > 0 && path.charAt(path.length() - 1) != '/')
- path = new StringBuffer(path).append("/").toString(); //$NON-NLS-1$
+ path = new StringBuilder(path).append("/").toString(); //$NON-NLS-1$
- List<String> vEntries = new ArrayList<String>();
+ Set<String> vEntries = new HashSet<String>();
+ // Get all zip file entries and add the ones of interest.
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();
String entryPath = zipEntry.getName();
+ // Is the entry of possible interest? Note that
+ // string.startsWith("") == true.
if (entryPath.startsWith(path)) {
+ // If we get here, we know that the entry is either (1) equal to
+ // path, (2) a file under path, or (3) a subdirectory of path.
if (path.length() < entryPath.length()) {
- if (entryPath.lastIndexOf('/') < path.length()) {
- vEntries.add(entryPath);
- } else {
- entryPath = entryPath.substring(path.length());
- int slash = entryPath.indexOf('/');
- entryPath = path + entryPath.substring(0, slash + 1);
- if (!vEntries.contains(entryPath))
- vEntries.add(entryPath);
- }
+ // If we get here, we know that entry is not equal to path.
+ getEntryPaths(path, entryPath.substring(path.length()), recurse, vEntries);
}
}
}
return vEntries.size() == 0 ? null : Collections.enumeration(vEntries);
}
+ private void getEntryPaths(String path, String entry, boolean recurse, Set<String> entries) {
+ if (entry.length() == 0)
+ return;
+ int slash = entry.indexOf('/');
+ if (slash == -1)
+ entries.add(path + entry);
+ else {
+ path = path + entry.substring(0, slash + 1);
+ entries.add(path);
+ if (recurse)
+ getEntryPaths(path, entry.substring(slash + 1), true, entries);
+ }
+ }
+
public synchronized void close() throws IOException {
if (!closed) {
if (referenceCount > 0 && isMruListClosing()) {

Back to the top