Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnjum Fatima2019-11-06 16:32:25 +0000
committerAnjum Fatima2019-11-13 20:42:36 +0000
commitdf79d6707569c92d25cb2d347bab6e7ee062da58 (patch)
treeae601d15932bd6aafbc5c40a9a3f6b8b63dab389
parent7b23229cd7b2fece15ce03a1032041074db6c2bb (diff)
downloadrt.equinox.framework-df79d6707569c92d25cb2d347bab6e7ee062da58.tar.gz
rt.equinox.framework-df79d6707569c92d25cb2d347bab6e7ee062da58.tar.xz
rt.equinox.framework-df79d6707569c92d25cb2d347bab6e7ee062da58.zip
Bug 552573 - Remove empty jar creation for connect bundle
Also handle different kinds of bundles (reference, connect etc) using ContentProvider interface. Also fixed connect bundle system fragments to stop trying to add content to framework class loader. Change-Id: Ic77a343bed89c88b4f7df541f20ed3a4352f4bdc Signed-off-by: Anjum Fatima <anjum.eclipse@gmail.com>
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java103
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java105
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectInputStream.java55
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java49
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java9
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java18
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java19
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java2
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java27
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/ContentProvider.java48
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java16
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java136
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java13
15 files changed, 330 insertions, 278 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java
index 3f1507a1c..4338ec7dc 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/cds/CDSHookImpls.java
@@ -37,6 +37,7 @@ import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
import org.eclipse.osgi.internal.loader.classpath.FragmentClasspath;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
@@ -192,6 +193,9 @@ public class CDSHookImpls extends ClassLoaderHook implements BundleFileWrapperFa
//////////////// BundleFileWrapperFactoryHook //////////////
@Override
public BundleFileWrapper wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) {
+ if (generation.getContentType() == Type.CONNECT) {
+ return null;
+ }
// wrap the real bundle file for purposes of loading shared classes.
CDSBundleFile newBundleFile;
if (!base && generation.getBundleInfo().getBundleId() != 0) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java
deleted file mode 100644
index a5cae1bb8..000000000
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectBundleFileFactory.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2019 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.internal.connect;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Enumeration;
-import org.eclipse.osgi.internal.connect.ConnectHookConfigurator.ConnectModules;
-import org.eclipse.osgi.internal.debug.Debug;
-import org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook;
-import org.eclipse.osgi.storage.BundleInfo.Generation;
-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.MRUBundleFileList;
-import org.osgi.framework.connect.ConnectModule;
-
-public class ConnectBundleFileFactory implements BundleFileWrapperFactoryHook {
- final ConnectModules connectModules;
- final Debug debug;
-
- public ConnectBundleFileFactory(ConnectModules connectModules, Debug debug) {
- this.connectModules = connectModules;
- this.debug = debug;
- }
-
- @Override
- public BundleFileWrapper wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) {
- ConnectModule m = connectModules.getConnectModule(generation.getBundleInfo().getLocation());
- if (m == null) {
- return null;
- }
- MRUBundleFileList mruList = generation.getBundleInfo().getStorage().getMRUBundleFileList();
- try {
- ConnectBundleFile connectBundleFile = new ConnectBundleFile(m, bundleFile.getBaseFile(), generation, mruList, debug);
- return new ConnectBundleFileWrapper(bundleFile, connectBundleFile);
- } catch (IOException e) {
- // TODO should log this
- }
- return null;
- }
-
- public static class ConnectBundleFileWrapper extends BundleFileWrapper {
- private final ConnectBundleFile connectBundleFile;
-
- public ConnectBundleFileWrapper(BundleFile bundleFile, ConnectBundleFile connectBundleFile) {
- super(bundleFile);
- this.connectBundleFile = connectBundleFile;
- }
-
- @Override
- public BundleEntry getEntry(final String path) {
- return connectBundleFile.getEntry(path);
- }
-
- @Override
- public File getFile(String path, boolean nativeCode) {
- return connectBundleFile.getFile(path, nativeCode);
- }
-
- @Override
- public Enumeration<String> getEntryPaths(String path) {
- return connectBundleFile.getEntryPaths(path);
- }
-
- @Override
- public Enumeration<String> getEntryPaths(String path, boolean recurse) {
- return connectBundleFile.getEntryPaths(path, recurse);
- }
-
- @Override
- public boolean containsDir(String dir) {
- return connectBundleFile.containsDir(dir);
- }
-
- @Override
- public void open() throws IOException {
- connectBundleFile.open();
- super.open();
- }
-
- @Override
- public void close() throws IOException {
- super.close();
- connectBundleFile.close();
- }
-
- ConnectBundleFile getConnectBundleFile() {
- return connectBundleFile;
- }
- }
-}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java
index c1a7646e8..98948f58c 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java
@@ -13,30 +13,19 @@
*******************************************************************************/
package org.eclipse.osgi.internal.connect;
-import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.net.URL;
import java.net.URLConnection;
-import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.jar.JarOutputStream;
-import java.util.zip.ZipEntry;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
import org.eclipse.osgi.container.ModuleRevisionBuilder;
import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory;
-import org.eclipse.osgi.internal.connect.ConnectBundleFileFactory.ConnectBundleFileWrapper;
-import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
+import org.eclipse.osgi.internal.framework.EquinoxContainer.ConnectModules;
import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
@@ -48,7 +37,6 @@ import org.eclipse.osgi.internal.loader.ModuleClassLoader;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.storage.bundlefile.BundleFileWrapperChain;
-import org.eclipse.osgi.storage.url.reference.ReferenceInputStream;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
@@ -57,45 +45,11 @@ import org.osgi.framework.connect.ConnectFactory;
import org.osgi.framework.connect.ConnectModule;
public class ConnectHookConfigurator implements HookConfigurator {
- static final ConnectModule NULL_MODULE = new ConnectModule() {
- @Override
- public ConnectContent getContent() throws IOException {
- throw new IOException();
- }
- };
-
- static final byte[] EMPTY_JAR;
- static {
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- JarOutputStream jos = new JarOutputStream(baos);
- ZipEntry bootBundlePropsEntry = new ZipEntry("ConnectBundle.properties"); //$NON-NLS-1$
- jos.putNextEntry(bootBundlePropsEntry);
- Properties bootBundleProps = new Properties();
- bootBundleProps.setProperty("ConnectBundle", "true"); //$NON-NLS-1$ //$NON-NLS-2$
- bootBundleProps.store(jos, "ConnectBundle"); //$NON-NLS-1$
- jos.close();
- EMPTY_JAR = baos.toByteArray();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
@Override
public void addHooks(final HookRegistry hookRegistry) {
- ConnectFactory connectFactory = hookRegistry.getContainer().getConnectFactory();
- final ConnectModules connectModules = new ConnectModules(connectFactory);
-
- URL configUrl = hookRegistry.getContainer().getLocations().getConfigurationLocation().getURL();
- final File storage = new File(configUrl.getPath());
- final File emptyJar = new File(storage, "connectEmptyBundle.jar"); //$NON-NLS-1$
- if (connectFactory != null && !emptyJar.exists()) {
- try {
- Files.write(emptyJar.toPath(), EMPTY_JAR);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
+ final ConnectModules connectModules = hookRegistry.getContainer().getConnectModules();
+ ConnectFactory connectFactory = connectModules.getConnectFactory();
hookRegistry.addStorageHookFactory(new StorageHookFactory<Object, Object, StorageHook<Object, Object>>() {
@Override
@@ -118,7 +72,7 @@ public class ConnectHookConfigurator implements HookConfigurator {
@Override
public void validate() throws IllegalStateException {
// make sure we have the module still from the factory
- if (hasModule && connectModules.getConnectModule(generation.getBundleInfo().getLocation()) == null) {
+ if (hasModule && m == null) {
throw new IllegalStateException("Connect Factory no longer has the module at locataion: " + generation.getBundleInfo().getLocation()); //$NON-NLS-1$
}
}
@@ -152,16 +106,7 @@ public class ConnectHookConfigurator implements HookConfigurator {
}
ConnectModule m = connectModules.getConnectModule(location);
if (m != null) {
- return new URLConnection(null) {
- @Override
- public void connect() throws IOException {
- connected = true;
- }
-
- public InputStream getInputStream() throws IOException {
- return new ReferenceInputStream(emptyJar);
- }
- };
+ return ConnectInputStream.URL_CONNECTION_INSTANCE;
}
return null;
}
@@ -178,20 +123,21 @@ public class ConnectHookConfigurator implements HookConfigurator {
if (m != null) {
BundleFile bundlefile = generation.getBundleFile();
if (bundlefile instanceof BundleFileWrapperChain) {
- ConnectBundleFileWrapper content = ((BundleFileWrapperChain) bundlefile).getWrappedType(ConnectBundleFileWrapper.class);
- if (content != null) {
- return content.getConnectBundleFile().getClassLoader().map((l) //
- -> new DelegatingConnectClassLoader(parent, configuration, delegate, generation, l)).orElse(null);
+ BundleFileWrapperChain chain = (BundleFileWrapperChain) bundlefile;
+ while (chain.getNext() != null) {
+ chain = chain.getNext();
}
+ bundlefile = chain.getBundleFile();
+ }
+ if (bundlefile instanceof ConnectBundleFile) {
+ return ((ConnectBundleFile) bundlefile).getClassLoader().map((l) //
+ -> new DelegatingConnectClassLoader(parent, configuration, delegate, generation, l)).orElse(null);
}
}
return null;
}
});
- final Debug debug = hookRegistry.getContainer().getConfiguration().getDebug();
- hookRegistry.addBundleFileWrapperFactoryHook(new ConnectBundleFileFactory(connectModules, debug));
-
hookRegistry.addActivatorHookFactory(new ActivatorHookFactory() {
@Override
@@ -217,31 +163,6 @@ public class ConnectHookConfigurator implements HookConfigurator {
});
}
- static class ConnectModules {
- final ConnectFactory connectFactory;
- private final ConcurrentMap<String, ConnectModule> connectModules = new ConcurrentHashMap<>();
- volatile File emptyJar;
-
- public ConnectModules(ConnectFactory connectFactory) {
- this.connectFactory = connectFactory;
- }
-
- ConnectModule getConnectModule(String location) {
- if (connectFactory == null) {
- return null;
- }
- ConnectModule result = connectModules.computeIfAbsent(location, (l) -> {
- try {
- return connectFactory.getModule(location).orElse(NULL_MODULE);
- } catch (IllegalStateException e) {
- return NULL_MODULE;
- }
- });
- return result == NULL_MODULE ? null : result;
- }
-
- }
-
@SuppressWarnings("unchecked")
public static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
throw (E) e;
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectInputStream.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectInputStream.java
new file mode 100644
index 000000000..1d5ed6992
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectInputStream.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.connect;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+import org.eclipse.osgi.storage.ContentProvider;
+
+public class ConnectInputStream extends InputStream implements ContentProvider {
+ static final ConnectInputStream INSTANCE = new ConnectInputStream();
+ static final URLConnection URL_CONNECTION_INSTANCE = new URLConnection(null) {
+ @Override
+ public void connect() throws IOException {
+ connected = true;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return INSTANCE;
+ }
+ };
+
+ private ConnectInputStream() {
+ }
+
+ /* This method should not be called.
+ */
+ @Override
+ public int read() throws IOException {
+ throw new IOException();
+ }
+
+ public File getContent() {
+ return null;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.CONNECT;
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
index bd06d5f1a..5a846be1d 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java
@@ -24,6 +24,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
@@ -47,7 +49,9 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
+import org.osgi.framework.connect.ConnectContent;
import org.osgi.framework.connect.ConnectFactory;
+import org.osgi.framework.connect.ConnectModule;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
import org.osgi.util.tracker.ServiceTracker;
@@ -56,8 +60,14 @@ import org.osgi.util.tracker.ServiceTracker;
public class EquinoxContainer implements ThreadFactory, Runnable {
public static final String NAME = "org.eclipse.osgi"; //$NON-NLS-1$
static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction());
+ static final ConnectModule NULL_MODULE = new ConnectModule() {
+ @Override
+ public ConnectContent getContent() throws IOException {
+ throw new IOException();
+ }
+ };
- private final ConnectFactory connectFactory;
+ private final ConnectModules connectModules;
private final EquinoxConfiguration equinoxConfig;
private final EquinoxLogServices logServices;
private final Storage storage;
@@ -91,10 +101,10 @@ public class EquinoxContainer implements ThreadFactory, Runnable {
/* boot class loader */};
}
this.bootLoader = platformClassLoader;
- this.connectFactory = connectFactory;
this.equinoxConfig = new EquinoxConfiguration(configuration, new HookRegistry(this));
this.logServices = new EquinoxLogServices(this.equinoxConfig);
this.equinoxConfig.logMessages(this.logServices);
+ this.connectModules = new ConnectModules(connectFactory);
initConnectFactory(connectFactory, this.equinoxConfig);
@@ -153,10 +163,6 @@ public class EquinoxContainer implements ThreadFactory, Runnable {
connectFactory.initialize(fwkStore, Collections.unmodifiableMap(config));
}
- public ConnectFactory getConnectFactory() {
- return connectFactory;
- }
-
public Storage getStorage() {
return storage;
}
@@ -355,4 +361,35 @@ public class EquinoxContainer implements ThreadFactory, Runnable {
public ClassLoader getBootLoader() {
return bootLoader;
}
+
+ public ConnectModules getConnectModules() {
+ return connectModules;
+ }
+
+ public static class ConnectModules {
+ final ConnectFactory connectFactory;
+ private final ConcurrentMap<String, ConnectModule> connectModules = new ConcurrentHashMap<>();
+
+ public ConnectModules(ConnectFactory connectFactory) {
+ this.connectFactory = connectFactory;
+ }
+
+ public ConnectModule getConnectModule(String location) {
+ if (connectFactory == null) {
+ return null;
+ }
+ ConnectModule result = connectModules.computeIfAbsent(location, (l) -> {
+ try {
+ return connectFactory.getModule(location).orElse(NULL_MODULE);
+ } catch (IllegalStateException e) {
+ return NULL_MODULE;
+ }
+ });
+ return result == NULL_MODULE ? null : result;
+ }
+
+ public ConnectFactory getConnectFactory() {
+ return connectFactory;
+ }
+ }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java
index a1cfc662c..e785e2df5 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java
@@ -19,8 +19,11 @@ import java.util.ArrayList;
import org.eclipse.osgi.framework.util.KeyedElement;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
-import org.eclipse.osgi.internal.loader.classpath.*;
+import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
+import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
+import org.eclipse.osgi.internal.loader.classpath.FragmentClasspath;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
public class DevClassLoadingHook extends ClassLoaderHook implements KeyedElement {
@@ -36,6 +39,10 @@ public class DevClassLoadingHook extends ClassLoaderHook implements KeyedElement
@Override
public boolean addClassPathEntry(ArrayList<ClasspathEntry> cpEntries, String cp, ClasspathManager hostmanager, Generation sourceGeneration) {
+ // if this is a connect bundle just ignore
+ if (sourceGeneration.getContentType() == Type.CONNECT) {
+ return false;
+ }
// first check that we are in devmode for this sourcedata
String[] devClassPaths = !configuration.inDevelopmentMode() ? null : configuration.getDevClassPath(sourceGeneration.getRevision().getSymbolicName());
if (devClassPaths == null || devClassPaths.length == 0)
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 04d6abe02..e6b162f8a 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
@@ -14,10 +14,20 @@ package org.eclipse.osgi.internal.signedcontent;
import java.io.IOException;
import java.io.InputStream;
-import java.security.*;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.signedcontent.SignerInfo;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
@@ -94,7 +104,7 @@ public class SignatureBlockProcessor implements SignedContentConstants {
// Step 1, verify the .SF file is signed by the private key that corresponds to the public key
// in the .RSA/.DSA file
- String baseFile = bf.getBaseFile() != null ? bf.getBaseFile().toString() : null;
+ String baseFile = String.valueOf(bf.getBaseFile());
PKCS7Processor processor = new PKCS7Processor(pkcs7Bytes, 0, pkcs7Bytes.length, signer, baseFile);
// call the Step 1 in the Jar File Verification algorithm
processor.verifySFSignature(sfBytes, 0, sfBytes.length);
@@ -158,7 +168,7 @@ public class SignatureBlockProcessor implements SignedContentConstants {
// check if the the computed digest value of manifest file equals to the digest value in the .sf file
if (!digestValue.equals(manifestDigest)) {
- SignatureException se = new SignatureException(NLS.bind(SignedContentMessages.Security_File_Is_Tampered, new String[] {signedBundle.getBaseFile().toString()}));
+ SignatureException se = new SignatureException(NLS.bind(SignedContentMessages.Security_File_Is_Tampered, new String[] {String.valueOf(signedBundle.getBaseFile())}));
signedBundleHook.log(se.getMessage(), FrameworkLogEntry.ERROR, se);
throw se;
}
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 7e9d88cea..5f3cf84c7 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
@@ -17,11 +17,20 @@ package org.eclipse.osgi.internal.signedcontent;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
-import java.security.*;
-import java.security.cert.*;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
import java.util.Date;
-import org.eclipse.osgi.signedcontent.*;
-import org.eclipse.osgi.storage.bundlefile.*;
+import org.eclipse.osgi.signedcontent.SignedContent;
+import org.eclipse.osgi.signedcontent.SignedContentEntry;
+import org.eclipse.osgi.signedcontent.SignerInfo;
+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.util.NLS;
/**
@@ -73,7 +82,7 @@ public class SignedBundleFile extends BundleFileWrapper implements SignedContent
// double check that no signer thinks it should exist
SignedContentEntry signedEntry = signedContent.getSignedEntry(path);
if (signedEntry != null)
- throw new SecurityException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, path, getBaseFile().toString()));
+ throw new SecurityException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, path, String.valueOf(getBaseFile())));
return null;
}
return new SignedBundleEntry(be);
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
index a22b2da50..f8e96da56 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
@@ -195,7 +195,7 @@ public class SignedContentImpl implements SignedContent {
exception = e;
}
if (entry == null)
- throw new InvalidContentException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, entryName, currentContent.getBaseFile().toString()), exception);
+ throw new InvalidContentException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, entryName, String.valueOf(currentContent.getBaseFile())), exception);
entry.getBytes();
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java
index fd100cd18..61b73c03d 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/BundleInfo.java
@@ -45,6 +45,7 @@ import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.hookregistry.StorageHookFactory;
import org.eclipse.osgi.internal.hookregistry.StorageHookFactory.StorageHook;
import org.eclipse.osgi.internal.messages.Msg;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.Storage.StorageException;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
@@ -67,7 +68,6 @@ public final class BundleInfo {
private final Dictionary<String, String> cachedHeaders;
private File content;
private boolean isDirectory;
- private boolean isReference;
private boolean hasPackageInfo;
private BundleFile bundleFile;
private Map<String, String> rawHeaders;
@@ -78,17 +78,18 @@ public final class BundleInfo {
private List<StorageHook<?, ?>> storageHooks;
private long lastModified;
private boolean isMRJar;
+ private Type contentType;
Generation(long generationId) {
this.generationId = generationId;
this.cachedHeaders = new CachedManifest(this, Collections.<String, String> emptyMap());
}
- Generation(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
+ Generation(long generationId, File content, boolean isDirectory, Type contentType, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
this.generationId = generationId;
this.content = content;
this.isDirectory = isDirectory;
- this.isReference = isReference;
+ this.contentType = contentType;
this.hasPackageInfo = hasPackageInfo;
this.cachedHeaders = new CachedManifest(this, cached);
this.lastModified = lastModified;
@@ -211,12 +212,6 @@ public final class BundleInfo {
}
}
- public boolean isReference() {
- synchronized (this.genMonitor) {
- return this.isReference;
- }
- }
-
public boolean hasPackageInfo() {
synchronized (this.genMonitor) {
return this.hasPackageInfo;
@@ -235,11 +230,17 @@ public final class BundleInfo {
}
}
- void setContent(File content, boolean isReference) {
+ public Type getContentType() {
+ synchronized (this.genMonitor) {
+ return this.contentType;
+ }
+ }
+
+ void setContent(File content, Type contentType) {
synchronized (this.genMonitor) {
this.content = content;
this.isDirectory = content == null ? false : Storage.secureAction.isDirectory(content);
- this.isReference = isReference;
+ this.contentType = contentType;
setLastModified(content);
}
}
@@ -488,9 +489,9 @@ public final class BundleInfo {
}
}
- Generation restoreGeneration(long generationId, File content, boolean isDirectory, boolean isReference, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
+ Generation restoreGeneration(long generationId, File content, boolean isDirectory, Type contentType, boolean hasPackageInfo, Map<String, String> cached, long lastModified, boolean isMRJar) {
synchronized (this.infoMonitor) {
- Generation restoredGeneration = new Generation(generationId, content, isDirectory, isReference, hasPackageInfo, cached, lastModified, isMRJar);
+ Generation restoredGeneration = new Generation(generationId, content, isDirectory, contentType, hasPackageInfo, cached, lastModified, isMRJar);
return restoredGeneration;
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/ContentProvider.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/ContentProvider.java
new file mode 100644
index 000000000..50f3f34b3
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/ContentProvider.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.storage;
+
+import java.io.File;
+import org.osgi.framework.BundleException;
+
+/**
+ * A content provider is a marker interface that is used
+ * but the framework internally to handle different kinds of
+ * bundles. For example, reference installed bundles or
+ * connect bundles. The type of the provider indicates
+ * how the framework will handle the install or update
+ * of the bundle content.
+ */
+public interface ContentProvider {
+
+ /**
+ * The type of the provided content
+ */
+ public enum Type {
+ REFERENCE, CONNECT, DEFAULT;
+ }
+
+ /**
+ * A file of the content, may be {@code null}
+ * @return the file, may be {@code null}
+ * @throws BundleException
+ */
+ File getContent() throws BundleException;
+
+ /**
+ * The type of content
+ * @return the type of content
+ */
+ Type getType();
+}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java
index 939e9548f..9cb603f64 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/FrameworkExtensionInstaller.java
@@ -37,6 +37,7 @@ import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
import org.eclipse.osgi.internal.hookregistry.HookRegistry;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
@@ -71,7 +72,7 @@ public class FrameworkExtensionInstaller {
} catch (NoSuchMethodException | RuntimeException e) {
// do nothing look in super class below
// have to avoid blowing up <clinit>
- }
+ }
return findMethod(clazz.getSuperclass(), name, args);
}
@@ -121,16 +122,14 @@ public class FrameworkExtensionInstaller {
for (ModuleRevision revision : revisions) {
File[] files = getExtensionFiles(revision);
- if (files == null) {
- return;
- }
+
for (File file : files) {
if (file == null) {
- continue;
+ continue;
}
try {
callAddURLMethod(StorageUtil.encodeFileURL(file));
- }catch (InvocationTargetException | MalformedURLException e) {
+ } catch (InvocationTargetException | MalformedURLException e) {
throw new BundleException("Error adding extension content.", e); //$NON-NLS-1$
}
}
@@ -158,6 +157,11 @@ public class FrameworkExtensionInstaller {
* @return a list of classpath files for an extension bundle
*/
private File[] getExtensionFiles(ModuleRevision revision) {
+ Generation generation = (Generation) revision.getRevisionInfo();
+ if (generation.getContentType() == Type.CONNECT) {
+ // Don't do anything for connect bundles
+ return new File[0];
+ }
List<ModuleCapability> metaDatas = revision.getModuleCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE);
@SuppressWarnings("unchecked")
List<String> paths = metaDatas.isEmpty() ? null : (List<String>) metaDatas.get(0).getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_CLASSPATH);
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 589b65681..1470c85e6 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
@@ -65,6 +65,7 @@ import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.framework.util.FilePath;
import org.eclipse.osgi.framework.util.ObjectPool;
import org.eclipse.osgi.framework.util.SecureAction;
+import org.eclipse.osgi.internal.connect.ConnectBundleFile;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
@@ -81,6 +82,7 @@ import org.eclipse.osgi.internal.permadmin.SecurityAdmin;
import org.eclipse.osgi.internal.url.URLStreamHandlerFactoryImpl;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.eclipse.osgi.storage.ContentProvider.Type;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.storage.bundlefile.BundleFileWrapper;
@@ -90,7 +92,6 @@ import org.eclipse.osgi.storage.bundlefile.MRUBundleFileList;
import org.eclipse.osgi.storage.bundlefile.NestedDirBundleFile;
import org.eclipse.osgi.storage.bundlefile.ZipBundleFile;
import org.eclipse.osgi.storage.url.reference.Handler;
-import org.eclipse.osgi.storage.url.reference.ReferenceInputStream;
import org.eclipse.osgi.storagemanager.ManagedOutputStream;
import org.eclipse.osgi.storagemanager.StorageManager;
import org.eclipse.osgi.util.ManifestElement;
@@ -102,6 +103,7 @@ import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
+import org.osgi.framework.connect.ConnectModule;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.NativeNamespace;
import org.osgi.framework.namespace.PackageNamespace;
@@ -133,9 +135,10 @@ public class Storage {
}
- public static final int VERSION = 5;
- private static final int MR_JAR_VERSION = 4;
+ public static final int VERSION = 6;
+ private static final int CONTENT_TYPE_VERSION = 6;
private static final int CACHED_SYSTEM_CAPS_VERION = 5;
+ private static final int MR_JAR_VERSION = 4;
private static final int LOWEST_VERSION_SUPPORTED = 3;
public static final String BUNDLE_DATA_DIR = "data"; //$NON-NLS-1$
public static final String BUNDLE_FILE_NAME = "bundleFile"; //$NON-NLS-1$
@@ -362,6 +365,9 @@ public class Storage {
}
}
File content = generation.getContent();
+ if (content == null) {
+ return false;
+ }
if (getConfiguration().inCheckConfigurationMode()) {
if (generation.isDirectory()) {
content = new File(content, "META-INF/MANIFEST.MF"); //$NON-NLS-1$
@@ -384,7 +390,7 @@ public class Storage {
newGeneration = info.createGeneration();
File contentFile = getSystemContent();
- newGeneration.setContent(contentFile, false);
+ newGeneration.setContent(contentFile, Type.DEFAULT);
// First we must make sure the VM profile has been loaded
loadVMProfile(newGeneration);
@@ -410,7 +416,7 @@ public class Storage {
File contentFile = currentGeneration.getContent();
if (systemNeedsUpdate(contentFile, currentRevision, currentGeneration, extraCapabilities, extraExports, cachedInfo)) {
newGeneration = currentGeneration.getBundleInfo().createGeneration();
- newGeneration.setContent(contentFile, false);
+ newGeneration.setContent(contentFile, Type.DEFAULT);
ModuleRevisionBuilder newBuilder = getBuilder(newGeneration, extraCapabilities, extraExports);
moduleContainer.update(systemModule, newBuilder, newGeneration);
moduleContainer.refresh(Collections.singleton(systemModule));
@@ -687,16 +693,18 @@ public class Storage {
return (Generation) existingLocation.getCurrentRevision().getRevisionInfo();
}
- boolean isReference = in instanceof ReferenceInputStream;
- File staged = stageContent(in, sourceURL);
+ ContentProvider contentProvider = getContentProvider(in, sourceURL);
+ Type contentType = contentProvider.getType();
+ File staged = contentProvider.getContent();
+
Generation generation = null;
try {
Long nextID = moduleDatabase.getAndIncrementNextId();
BundleInfo info = new BundleInfo(this, nextID, bundleLocation, 0);
generation = info.createGeneration();
- File contentFile = getContentFile(staged, isReference, nextID, generation.getGenerationId());
- generation.setContent(contentFile, isReference);
+ File contentFile = getContentFile(staged, contentType, nextID, generation.getGenerationId());
+ generation.setContent(contentFile, contentType);
// Check that we can open the bundle file
generation.getBundleFile().open();
setStorageHooks(generation);
@@ -712,7 +720,7 @@ public class Storage {
}
return generation;
} catch (Throwable t) {
- if (!isReference) {
+ if (contentType == Type.DEFAULT) {
try {
delete(staged);
} catch (IOException e) {
@@ -742,6 +750,24 @@ public class Storage {
}
}
+ ContentProvider getContentProvider(final InputStream in, final URL sourceURL) {
+ if (in instanceof ContentProvider) {
+ return (ContentProvider) in;
+ }
+ return new ContentProvider() {
+
+ @Override
+ public Type getType() {
+ return Type.DEFAULT;
+ }
+
+ @Override
+ public File getContent() throws BundleException {
+ return stageContent(in, sourceURL);
+ }
+ };
+ }
+
private void setStorageHooks(Generation generation) throws BundleException {
if (generation.getBundleInfo().getBundleId() == 0) {
return; // ignore system bundle
@@ -879,7 +905,10 @@ public class Storage {
ModuleRevision current = module.getCurrentRevision();
Generation currentGen = (Generation) current.getRevisionInfo();
File content = currentGen.getContent();
- String spec = (currentGen.isReference() ? "reference:" : "") + content.toURI().toString(); //$NON-NLS-1$ //$NON-NLS-2$
+ if (content == null) {
+ return;
+ }
+ String spec = (currentGen.getContentType() == Type.REFERENCE ? "reference:" : "") + content.toURI().toString(); //$NON-NLS-1$ //$NON-NLS-2$
URLConnection contentConn;
try {
contentConn = getContentConnection(spec);
@@ -900,8 +929,11 @@ public class Storage {
} catch (Throwable e) {
throw new BundleException("Error reading bundle content.", e); //$NON-NLS-1$
}
- boolean isReference = in instanceof ReferenceInputStream;
- File staged = stageContent(in, sourceURL);
+
+ ContentProvider contentProvider = getContentProvider(in, sourceURL);
+ Type contentType = contentProvider.getType();
+ File staged = contentProvider.getContent();
+
ModuleRevision current = module.getCurrentRevision();
Generation currentGen = (Generation) current.getRevisionInfo();
@@ -909,8 +941,8 @@ public class Storage {
Generation newGen = bundleInfo.createGeneration();
try {
- File contentFile = getContentFile(staged, isReference, bundleInfo.getBundleId(), newGen.getGenerationId());
- newGen.setContent(contentFile, isReference);
+ File contentFile = getContentFile(staged, contentType, bundleInfo.getBundleId(), newGen.getGenerationId());
+ newGen.setContent(contentFile, contentType);
// Check that we can open the bundle file
newGen.getBundleFile().open();
setStorageHooks(newGen);
@@ -918,7 +950,7 @@ public class Storage {
ModuleRevisionBuilder builder = getBuilder(newGen);
moduleContainer.update(module, builder, newGen);
} catch (Throwable t) {
- if (!isReference) {
+ if (contentType == Type.DEFAULT) {
try {
delete(staged);
} catch (IOException e) {
@@ -944,14 +976,14 @@ public class Storage {
return newGen;
}
- private File getContentFile(final File staged, final boolean isReference, final long bundleID, final long generationID) throws BundleException {
+ private File getContentFile(final File staged, Type contentType, final long bundleID, final long generationID) throws BundleException {
if (System.getSecurityManager() == null)
- return getContentFile0(staged, isReference, bundleID, generationID);
+ return getContentFile0(staged, contentType, bundleID, generationID);
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
@Override
public File run() throws BundleException {
- return getContentFile0(staged, isReference, bundleID, generationID);
+ return getContentFile0(staged, contentType, bundleID, generationID);
}
});
} catch (PrivilegedActionException e) {
@@ -961,9 +993,10 @@ public class Storage {
}
}
- File getContentFile0(File staged, boolean isReference, long bundleID, long generationID) throws BundleException {
- File contentFile;
- if (!isReference) {
+ File getContentFile0(File staged, Type contentType, long bundleID, long generationID) throws BundleException {
+ File contentFile = staged;
+
+ if (contentType == Type.DEFAULT) {
File generationRoot = new File(childRoot, bundleID + "/" + generationID); //$NON-NLS-1$
generationRoot.mkdirs();
if (!generationRoot.isDirectory()) {
@@ -973,8 +1006,6 @@ public class Storage {
if (!StorageUtil.move(staged, contentFile, getConfiguration().getDebug().DEBUG_STORAGE)) {
throw new BundleException("Error while renaming bundle file to final location: " + contentFile); //$NON-NLS-1$
}
- } else {
- contentFile = staged;
}
return contentFile;
}
@@ -1053,7 +1084,7 @@ public class Storage {
return result;
}
- private File stageContent(final InputStream in, final URL sourceURL) throws BundleException {
+ File stageContent(final InputStream in, final URL sourceURL) throws BundleException {
if (System.getSecurityManager() == null)
return stageContent0(in, sourceURL);
try {
@@ -1073,10 +1104,6 @@ public class Storage {
File stageContent0(InputStream in, URL sourceURL) throws BundleException {
File outFile = null;
try {
- if (in instanceof ReferenceInputStream) {
- return ((ReferenceInputStream) in).getReference();
- }
-
outFile = File.createTempFile(BUNDLE_FILE_NAME, ".tmp", childRoot); //$NON-NLS-1$
String protocol = sourceURL == null ? null : sourceURL.getProtocol();
@@ -1133,9 +1160,12 @@ public class Storage {
}
public BundleFile createBundleFile(File content, Generation generation, boolean isDirectory, boolean isBase) {
- BundleFile result;
+ BundleFile result = null;
try {
- if (isDirectory) {
+ ConnectModule connectModule = equinoxContainer.getConnectModules().getConnectModule(generation.getBundleInfo().getLocation());
+ if (connectModule != null && isBase) {
+ result = new ConnectBundleFile(connectModule, content, generation, mruList, getConfiguration().getDebug());
+ } else if (isDirectory) {
boolean strictPath = Boolean.parseBoolean(equinoxContainer.getConfiguration().getConfiguration(EquinoxConfiguration.PROPERTY_STRICT_BUNDLE_ENTRY_PATH, Boolean.FALSE.toString()));
result = new DirBundleFile(content, strictPath);
} else {
@@ -1339,13 +1369,14 @@ public class Storage {
out.writeLong(bundleInfo.getNextGenerationId());
out.writeLong(generation.getGenerationId());
out.writeBoolean(generation.isDirectory());
- out.writeBoolean(generation.isReference());
+ Type contentType = generation.getContentType();
+ out.writeInt(contentType.ordinal());
out.writeBoolean(generation.hasPackageInfo());
- if (bundleInfo.getBundleId() == 0) {
- // just write empty string for system bundle content in this case
+ if (bundleInfo.getBundleId() == 0 || contentType == Type.CONNECT) {
+ // just write empty string for system bundle content and connect content in this case
out.writeUTF(""); //$NON-NLS-1$
} else {
- if (generation.isReference()) {
+ if (contentType == Type.REFERENCE) {
// make reference installs relative to the install path
out.writeUTF(new FilePath(installPath).makeRelative(new FilePath(generation.getContent().getAbsolutePath())));
} else {
@@ -1445,13 +1476,23 @@ public class Storage {
int numInfos = in.readInt();
Map<Long, Generation> result = new HashMap<>(numInfos);
List<Generation> generations = new ArrayList<>(numInfos);
+ Type[] contentTypes = Type.values();
for (int i = 0; i < numInfos; i++) {
long infoId = in.readLong();
String infoLocation = ObjectPool.intern(in.readUTF());
long nextGenId = in.readLong();
long generationId = in.readLong();
boolean isDirectory = in.readBoolean();
- boolean isReference = in.readBoolean();
+
+ Type contentType = Type.DEFAULT;
+ if (version >= CONTENT_TYPE_VERSION) {
+ contentType = contentTypes[in.readInt()];
+ } else {
+ if (in.readBoolean()) {
+ contentType = Type.REFERENCE;
+ }
+ }
+
boolean hasPackageInfo = in.readBoolean();
String contentPath = in.readUTF();
long lastModified = in.readLong();
@@ -1468,29 +1509,34 @@ public class Storage {
}
boolean isMRJar = (version >= MR_JAR_VERSION) ? in.readBoolean() : false;
- File content;
+ File content = null;
if (infoId == 0) {
content = getSystemContent();
isDirectory = content != null ? content.isDirectory() : false;
// Note that we do not do any checking for absolute paths with
// the system bundle. We always take the content as discovered
// by getSystemContent()
- } else {
+ } else if (contentType != Type.CONNECT) {
content = new File(contentPath);
if (!content.isAbsolute()) {
// make sure it has the absolute location instead
- if (isReference) {
- // reference installs are relative to the installPath
- content = new File(installPath, contentPath);
- } else {
- // normal installs are relative to the storage area
- content = getFile(contentPath, true);
+ switch (contentType) {
+ case REFERENCE :
+ // reference installs are relative to the installPath
+ content = new File(installPath, contentPath);
+ break;
+ case DEFAULT :
+ // normal installs are relative to the storage area
+ content = getFile(contentPath, true);
+ break;
+ default :
+ throw new IllegalArgumentException("Unknown type: " + contentType); //$NON-NLS-1$
}
}
}
BundleInfo info = new BundleInfo(this, infoId, infoLocation, nextGenId);
- Generation generation = info.restoreGeneration(generationId, content, isDirectory, isReference, hasPackageInfo, cachedHeaders, lastModified, isMRJar);
+ Generation generation = info.restoreGeneration(generationId, content, isDirectory, contentType, hasPackageInfo, cachedHeaders, lastModified, isMRJar);
result.put(infoId, generation);
generations.add(generation);
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java
index a06223c46..f37d25f08 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/bundlefile/CloseableBundleFile.java
@@ -542,7 +542,9 @@ public abstract class CloseableBundleFile<E> extends BundleFile {
}
private IOException enrichExceptionWithBaseFile(IOException e) {
- return new IOException(getBaseFile().toString(), e);
+ File baseFile = getBaseFile();
+ String extraInfo = baseFile == null ? generation.getBundleInfo().getLocation() : baseFile.toString();
+ return new IOException(extraInfo, e);
}
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java
index b9ff45f04..1ce4ba33c 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/url/reference/ReferenceInputStream.java
@@ -17,12 +17,13 @@ package org.eclipse.osgi.storage.url.reference;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import org.eclipse.osgi.storage.ContentProvider;
/**
* InputStream subclass which provides a reference (via File) to the data
* rather than allowing the input stream to be directly read.
*/
-public class ReferenceInputStream extends InputStream {
+public class ReferenceInputStream extends InputStream implements ContentProvider {
private final File reference;
public ReferenceInputStream(File reference) {
@@ -37,6 +38,16 @@ public class ReferenceInputStream extends InputStream {
}
public File getReference() {
+ return getContent();
+ }
+
+ @Override
+ public File getContent() {
return reference;
}
+
+ @Override
+ public Type getType() {
+ return Type.REFERENCE;
+ }
}

Back to the top