org.eclipse.osgi.internal.framework.EquinoxBundle Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/*******************************************************************************
* Copyright (c) 2012, 2021 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.framework;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.container.Module.Settings;
import org.eclipse.osgi.container.Module.StartOptions;
import org.eclipse.osgi.container.Module.State;
import org.eclipse.osgi.container.Module.StopOptions;
import org.eclipse.osgi.container.ModuleContainer;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
import org.eclipse.osgi.container.ModuleLoader;
import org.eclipse.osgi.container.ModuleRevision;
import org.eclipse.osgi.container.ModuleWire;
import org.eclipse.osgi.container.ModuleWiring;
import org.eclipse.osgi.container.SystemModule;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.internal.container.InternalUtils;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.loader.ModuleClassLoader;
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.internal.permadmin.EquinoxSecurityManager;
import org.eclipse.osgi.report.resolution.ResolutionReport;
import org.eclipse.osgi.signedcontent.SignedContent;
import org.eclipse.osgi.signedcontent.SignedContentFactory;
import org.eclipse.osgi.signedcontent.SignerInfo;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.Storage;
import org.osgi.framework.AdaptPermission;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleReference;
import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.framework.dto.BundleDTO;
import org.osgi.framework.dto.FrameworkDTO;
import org.osgi.framework.dto.ServiceReferenceDTO;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.startlevel.FrameworkStartLevel;
import org.osgi.framework.startlevel.dto.BundleStartLevelDTO;
import org.osgi.framework.startlevel.dto.FrameworkStartLevelDTO;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.framework.wiring.dto.BundleRevisionDTO;
import org.osgi.framework.wiring.dto.BundleWiringDTO;
import org.osgi.framework.wiring.dto.FrameworkWiringDTO;
public class EquinoxBundle implements Bundle, BundleReference {
static class SystemBundle extends EquinoxBundle implements Framework {
class SystemBundleHeaders extends Dictionary {
private final Dictionary headers;
public SystemBundleHeaders(Dictionary headers) {
this.headers = headers;
}
@Override
public Enumeration elements() {
return headers.elements();
}
@Override
public String get(Object key) {
if (!(key instanceof String))
return null;
String sKey = (String) key;
if (Constants.EXPORT_PACKAGE.equalsIgnoreCase(sKey) || Constants.PROVIDE_CAPABILITY.equalsIgnoreCase(sKey)) {
String systemProvideHeader = getEquinoxContainer().getConfiguration().getConfiguration(EquinoxConfiguration.PROP_SYSTEM_PROVIDE_HEADER, EquinoxConfiguration.SYSTEM_PROVIDE_HEADER_SYSTEM_EXTRA);
boolean useSystemExtra = systemProvideHeader.equals(EquinoxConfiguration.SYSTEM_PROVIDE_HEADER_SYSTEM_EXTRA);
boolean useSystem = systemProvideHeader.equals(EquinoxConfiguration.SYSTEM_PROVIDE_HEADER_SYSTEM) || useSystemExtra;
String systemProp = useSystem ? (Constants.EXPORT_PACKAGE.equalsIgnoreCase(sKey) ? Constants.FRAMEWORK_SYSTEMPACKAGES : Constants.FRAMEWORK_SYSTEMCAPABILITIES) : null;
String systemExtraProp = useSystemExtra ? (Constants.EXPORT_PACKAGE.equalsIgnoreCase(sKey) ? Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA : Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA) : null;
return getExtra(sKey, systemProp, systemExtraProp);
}
return headers.get(key);
}
private String getExtra(String header, String systemProp, String systemExtraProp) {
String systemValue = systemProp != null ? getEquinoxContainer().getConfiguration().getConfiguration(systemProp) : null;
String systemExtraValue = systemExtraProp != null ? getEquinoxContainer().getConfiguration().getConfiguration(systemExtraProp) : null;
if (systemValue == null)
systemValue = systemExtraValue;
else if (systemExtraValue != null && systemExtraValue.trim().length() > 0)
systemValue += ", " + systemExtraValue; //$NON-NLS-1$
String result = headers.get(header);
if (systemValue != null && systemValue.trim().length() > 0) {
if (result != null)
result += ", " + systemValue; //$NON-NLS-1$
else
result = systemValue;
}
return result;
}
@Override
public boolean isEmpty() {
return headers.isEmpty();
}
@Override
public Enumeration keys() {
return headers.keys();
}
@Override
public String put(String key, String value) {
return headers.put(key, value);
}
@Override
public String remove(Object key) {
return headers.remove(key);
}
@Override
public int size() {
return headers.size();
}
}
final List initListeners = new ArrayList<>(0);
class EquinoxSystemModule extends SystemModule {
public EquinoxSystemModule(ModuleContainer container) {
super(container);
}
@Override
public Bundle getBundle() {
return SystemBundle.this;
}
@Override
protected void cleanup(ModuleRevision revision) {
// Nothing to do
}
@Override
protected void initWorker() throws BundleException {
EquinoxConfiguration config = getEquinoxContainer().getConfiguration();
String initUUID = config.setConfiguration(EquinoxConfiguration.PROP_INIT_UUID, Boolean.TRUE.toString());
if (initUUID != null) {
// this is not the first framework init, need to generate a new UUID
config.setConfiguration(Constants.FRAMEWORK_UUID, InternalUtils.newUUID(config));
}
getEquinoxContainer().init();
addInitFrameworkListeners();
startWorker0();
}
@Override
protected void stopWorker() throws BundleException {
super.stopWorker();
stopWorker0();
getEquinoxContainer().close();
}
void asyncStop() throws BundleException {
if (getEquinoxContainer().getConfiguration().getDebug().DEBUG_SYSTEM_BUNDLE) {
Debug.printStackTrace(new Exception("Framework has been requested to stop.")); //$NON-NLS-1$
}
lockStateChange(ModuleEvent.STOPPED);
try {
if (Module.ACTIVE_SET.contains(getState())) {
// TODO this still has a chance of a race condition:
// multiple threads could get started if stop is called over and over
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
stop();
} catch (Throwable e) {
SystemBundle.this.getEquinoxContainer().getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, "Error stopping the framework.", e); //$NON-NLS-1$
}
}
}, "Framework stop - " + getEquinoxContainer().toString()); //$NON-NLS-1$
t.start();
}
} finally {
unlockStateChange(ModuleEvent.STOPPED);
}
}
void asyncUpdate() throws BundleException {
if (getEquinoxContainer().getConfiguration().getDebug().DEBUG_SYSTEM_BUNDLE) {
Debug.printStackTrace(new Exception("Framework has been requested to update (restart).")); //$NON-NLS-1$
}
lockStateChange(ModuleEvent.UPDATED);
try {
if (Module.ACTIVE_SET.contains(getState())) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
update();
} catch (Throwable e) {
SystemBundle.this.getEquinoxContainer().getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.ERROR, "Error updating the framework.", e); //$NON-NLS-1$
}
}
}, "Framework update - " + getEquinoxContainer().toString()); //$NON-NLS-1$
t.start();
}
} finally {
unlockStateChange(ModuleEvent.UPDATED);
}
}
}
SystemBundle(ModuleContainer moduleContainer, EquinoxContainer equinoxContainer) {
super(moduleContainer, equinoxContainer);
}
@Override
public void init() throws BundleException {
this.init((FrameworkListener[]) null);
}
@Override
public void init(FrameworkListener... listeners) throws BundleException {
if (listeners != null) {
if (getEquinoxContainer().getConfiguration().getDebug().DEBUG_SYSTEM_BUNDLE) {
Debug.println("Initializing framework with framework listeners: " + listeners); //$NON-NLS-1$
}
initListeners.addAll(Arrays.asList(listeners));
} else {
if (getEquinoxContainer().getConfiguration().getDebug().DEBUG_SYSTEM_BUNDLE) {
Debug.println("Initializing framework with framework no listeners"); //$NON-NLS-1$
}
}
try {
((SystemModule) getModule()).init();
} finally {
if (!initListeners.isEmpty()) {
getEquinoxContainer().getEventPublisher().flushFrameworkEvents();
removeInitListeners();
}
}
}
void addInitFrameworkListeners() {
BundleContext context = createBundleContext();
for (FrameworkListener initListener : initListeners) {
context.addFrameworkListener(initListener);
}
}
void removeInitListeners() {
BundleContext context = createBundleContext();
for (FrameworkListener initListener : initListeners) {
context.removeFrameworkListener(initListener);
}
initListeners.clear();
}
@Override
public FrameworkEvent waitForStop(long timeout) throws InterruptedException {
ContainerEvent event = ((SystemModule) getModule()).waitForStop(timeout);
return new FrameworkEvent(EquinoxContainerAdaptor.getType(event), this, null);
}
@Override
Module createSystemModule(ModuleContainer moduleContainer) {
return new EquinoxSystemModule(moduleContainer);
}
@Override
public void stop(final int options) throws BundleException {
getEquinoxContainer().checkAdminPermission(this, AdminPermission.EXECUTE);
((EquinoxSystemModule) getModule()).asyncStop();
}
@Override
public void stop() throws BundleException {
stop(0);
}
@Override
public void update(InputStream input) throws BundleException {
getEquinoxContainer().checkAdminPermission(this, AdminPermission.LIFECYCLE);
try {
if (input != null)
input.close();
} catch (IOException e) {
// do nothing
}
((EquinoxSystemModule) getModule()).asyncUpdate();
}
@Override
public void update() throws BundleException {
update(null);
}
@Override
public void uninstall() throws BundleException {
getEquinoxContainer().checkAdminPermission(this, AdminPermission.LIFECYCLE);
throw new BundleException(Msg.BUNDLE_SYSTEMBUNDLE_UNINSTALL_EXCEPTION, BundleException.INVALID_OPERATION);
}
@Override
public Dictionary getHeaders(String locale) {
return new SystemBundleHeaders(super.getHeaders(locale));
}
}
private final EquinoxContainer equinoxContainer;
private final Module module;
private final Object monitor = new Object();
private BundleContextImpl context;
private volatile SignedContent signedContent;
private class EquinoxModule extends Module {
@Override
protected void startWorker() throws BundleException {
startWorker0();
}
@Override
protected void stopWorker() throws BundleException {
stopWorker0();
}
public EquinoxModule(Long id, String location, ModuleContainer container, EnumSet settings, int startlevel) {
super(id, location, container, settings, startlevel);
}
@Override
public Bundle getBundle() {
return EquinoxBundle.this;
}
@Override
protected void cleanup(ModuleRevision revision) {
Generation generation = (Generation) revision.getRevisionInfo();
generation.delete();
if (revision.equals(getCurrentRevision())) {
// uninstall case
generation.getBundleInfo().delete();
}
}
}
EquinoxBundle(ModuleContainer moduleContainer, EquinoxContainer equinoxContainer) {
this.equinoxContainer = equinoxContainer;
this.module = createSystemModule(moduleContainer);
}
public EquinoxBundle(Long id, String location, ModuleContainer moduleContainer, EnumSet settings, int startlevel, EquinoxContainer equinoxContainer) {
this.equinoxContainer = equinoxContainer;
this.module = new EquinoxModule(id, location, moduleContainer, settings, startlevel);
}
Module createSystemModule(ModuleContainer moduleContainer) {
throw new UnsupportedOperationException();
}
@Override
public int compareTo(Bundle bundle) {
long idcomp = getBundleId() - bundle.getBundleId();
return (idcomp < 0L) ? -1 : ((idcomp > 0L) ? 1 : 0);
}
@Override
public int getState() {
switch (module.getState()) {
case INSTALLED :
return Bundle.INSTALLED;
case RESOLVED :
return Bundle.RESOLVED;
case STARTING :
case LAZY_STARTING :
return Bundle.STARTING;
case ACTIVE :
return Bundle.ACTIVE;
case STOPPING :
return Bundle.STOPPING;
case UNINSTALLED :
return Bundle.UNINSTALLED;
default :
throw new IllegalStateException("No valid bundle state for module state: " + module.getState()); //$NON-NLS-1$
}
}
@Override
public void start(int options) throws BundleException {
if (options == 0 && equinoxContainer.getConfiguration().getDebug().MONITOR_ACTIVATION) {
Debug.printStackTrace(new Exception("A persistent start has been called on bundle: " + this)); //$NON-NLS-1$
}
module.start(getStartOptions(options));
}
private static StartOptions[] getStartOptions(int options) {
if (options == 0) {
return new StartOptions[0];
}
Collection result = new ArrayList<>(2);
if ((options & Bundle.START_TRANSIENT) != 0) {
result.add(StartOptions.TRANSIENT);
}
if ((options & Bundle.START_ACTIVATION_POLICY) != 0) {
result.add(StartOptions.USE_ACTIVATION_POLICY);
}
return result.toArray(new StartOptions[result.size()]);
}
@Override
public void start() throws BundleException {
start(0);
}
@Override
public void stop(int options) throws BundleException {
if (options == 0 && equinoxContainer.getConfiguration().getDebug().MONITOR_ACTIVATION) {
Debug.printStackTrace(new Exception("A persistent stop has been called on bundle: " + this)); //$NON-NLS-1$
}
module.stop(getStopOptions(options));
}
private StopOptions[] getStopOptions(int options) {
if ((options & Bundle.STOP_TRANSIENT) == 0) {
return new StopOptions[0];
}
return new StopOptions[] {StopOptions.TRANSIENT};
}
@Override
public void stop() throws BundleException {
stop(0);
}
@Override
public void update(InputStream input) throws BundleException {
Storage storage = equinoxContainer.getStorage();
storage.update(module, input);
signedContent = null;
}
@Override
public void update() throws BundleException {
update(null);
}
@Override
public void uninstall() throws BundleException {
// be sure to prime the headers with default local; calling priv method to avoid permission check
privGetHeaders(null);
Storage storage = equinoxContainer.getStorage();
storage.getModuleContainer().uninstall(module);
}
@Override
public Dictionary getHeaders() {
return getHeaders(null);
}
@Override
public Dictionary getHeaders(String locale) {
equinoxContainer.checkAdminPermission(this, AdminPermission.METADATA);
return privGetHeaders(locale);
}
private Dictionary privGetHeaders(String locale) {
Generation current = (Generation) module.getCurrentRevision().getRevisionInfo();
return current.getHeaders(locale);
}
@Override
public long getBundleId() {
return module.getId();
}
@Override
public String getLocation() {
equinoxContainer.checkAdminPermission(getBundle(), AdminPermission.METADATA);
return module.getLocation();
}
@Override
public ServiceReference>[] getRegisteredServices() {
checkValid();
BundleContextImpl current = getBundleContextImpl();
return current == null ? null : equinoxContainer.getServiceRegistry().getRegisteredServices(current);
}
@Override
public ServiceReference>[] getServicesInUse() {
checkValid();
BundleContextImpl current = getBundleContextImpl();
return current == null ? null : equinoxContainer.getServiceRegistry().getServicesInUse(current);
}
@Override
public boolean hasPermission(Object permission) {
Generation current = (Generation) module.getCurrentRevision().getRevisionInfo();
ProtectionDomain domain = current.getDomain();
if (domain != null) {
if (permission instanceof Permission) {
SecurityManager sm = System.getSecurityManager();
if (sm instanceof EquinoxSecurityManager) {
/*
* If the FrameworkSecurityManager is active, we need to do checks the "right" way.
* We can exploit our knowledge that the security context of FrameworkSecurityManager
* is an AccessControlContext to invoke it properly with the ProtectionDomain.
*/
AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] {domain});
try {
sm.checkPermission((Permission) permission, acc);
return true;
} catch (Exception e) {
return false;
}
}
return domain.implies((Permission) permission);
}
return false;
}
return true;
}
@Override
public URL getResource(String name) {
try {
equinoxContainer.checkAdminPermission(this, AdminPermission.RESOURCE);
} catch (SecurityException e) {
return null;
}
checkValid();
if (isFragment()) {
return null;
}
ModuleClassLoader classLoader = getModuleClassLoader(false);
if (classLoader != null) {
return classLoader.getResource(name);
}
return new ClasspathManager((Generation) module.getCurrentRevision().getRevisionInfo(), null).findLocalResource(name);
}
@Override
public String getSymbolicName() {
return module.getCurrentRevision().getSymbolicName();
}
@Override
public Version getVersion() {
return module.getCurrentRevision().getVersion();
}
@Override
public Class> loadClass(String name) throws ClassNotFoundException {
try {
equinoxContainer.checkAdminPermission(this, AdminPermission.CLASS);
} catch (SecurityException e) {
throw new ClassNotFoundException(name, e);
}
checkValid();
if (isFragment()) {
throw new ClassNotFoundException("Can not load a class from a fragment bundle: " + this); //$NON-NLS-1$
}
try {
ModuleClassLoader classLoader = getModuleClassLoader(true);
if (classLoader != null) {
if (name.length() > 0 && name.charAt(0) == '[')
return Class.forName(name, false, classLoader);
return classLoader.loadClass(name);
}
} catch (ClassNotFoundException e) {
// This is an equinox-ism, check compatibility flag
boolean compatibilityLazyTrigger = equinoxContainer.getConfiguration().compatibilityLazyTriggerOnFailLoad;
// On failure attempt to activate lazy activating bundles.
if (compatibilityLazyTrigger && State.LAZY_STARTING.equals(module.getState())) {
try {
module.start(StartOptions.LAZY_TRIGGER);
} catch (BundleException e1) {
equinoxContainer.getLogServices().log(EquinoxContainer.NAME, FrameworkLogEntry.WARNING, e.getMessage(), e);
}
}
throw e;
}
throw new ClassNotFoundException("No class loader available for the bundle: " + this); //$NON-NLS-1$
}
private ModuleClassLoader getModuleClassLoader(boolean logResolveError) {
ResolutionReport report = resolve();
if (logResolveError && !Module.RESOLVED_SET.contains(module.getState())) {
String reportMessage = report.getResolutionReportMessage(module.getCurrentRevision());
equinoxContainer.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, this, new BundleException(reportMessage, BundleException.RESOLVE_ERROR));
}
return AccessController.doPrivileged(new PrivilegedAction() {
@Override
public ModuleClassLoader run() {
ModuleWiring wiring = getModule().getCurrentRevision().getWiring();
if (wiring != null) {
ModuleLoader moduleLoader = wiring.getModuleLoader();
if (moduleLoader instanceof BundleLoader) {
return ((BundleLoader) moduleLoader).getModuleClassLoader();
}
}
return null;
}
});
}
@Override
public Enumeration getResources(String name) throws IOException {
try {
equinoxContainer.checkAdminPermission(this, AdminPermission.RESOURCE);
} catch (SecurityException e) {
return null;
}
checkValid();
if (isFragment()) {
return null;
}
ModuleClassLoader classLoader = getModuleClassLoader(false);
Enumeration result = null;
if (classLoader != null) {
result = classLoader.getResources(name);
} else {
result = new ClasspathManager((Generation) module.getCurrentRevision().getRevisionInfo(), null).findLocalResources(name);
}
return result != null && result.hasMoreElements() ? result : null;
}
@Override
public Enumeration getEntryPaths(String path) {
try {
equinoxContainer.checkAdminPermission(this, AdminPermission.RESOURCE);
} catch (SecurityException e) {
return null;
}
checkValid();
Generation current = (Generation) getModule().getCurrentRevision().getRevisionInfo();
return current.getBundleFile().getEntryPaths(path);
}
@Override
public URL getEntry(String path) {
try {
equinoxContainer.checkAdminPermission(this, AdminPermission.RESOURCE);
} catch (SecurityException e) {
return null;
}
checkValid();
Generation current = (Generation) getModule().getCurrentRevision().getRevisionInfo();
return current.getEntry(path);
}
@Override
public long getLastModified() {
return module.getLastModified();
}
@Override
public Enumeration findEntries(String path, String filePattern, boolean recurse) {
try {
equinoxContainer.checkAdminPermission(this, AdminPermission.RESOURCE);
} catch (SecurityException e) {
return null;
}
checkValid();
resolve();
return Storage.findEntries(getGenerations(), path, filePattern, recurse ? BundleWiring.FINDENTRIES_RECURSE : 0);
}
@Override
public BundleContext getBundleContext() {
equinoxContainer.checkAdminPermission(this, AdminPermission.CONTEXT);
return createBundleContext();
}
BundleContextImpl createBundleContext() {
if (isFragment()) {
// fragments cannot have contexts
return null;
}
synchronized (this.monitor) {
if (context == null) {
// only create the context if we are starting, active or stopping
// this is so that SCR can get the context for lazy-start bundles
if (Module.ACTIVE_SET.contains(module.getState())) {
context = new BundleContextImpl(this, equinoxContainer);
}
}
return context;
}
}
private BundleContextImpl getBundleContextImpl() {
synchronized (this.monitor) {
return context;
}
}
@Override
public Map> getSignerCertificates(int signersType) {
try {
SignedContent current = getSignedContent();
SignerInfo[] infos = current == null ? null : current.getSignerInfos();
if (infos.length == 0)
return Collections.emptyMap();
Map> results = new HashMap<>(infos.length);
for (SignerInfo info : infos) {
if (signersType == SIGNERS_TRUSTED && !info.isTrusted()) {
continue;
}
Certificate[] certs = info.getCertificateChain();
if (certs == null || certs.length == 0)
continue;
List certChain = new ArrayList<>();
for (Certificate cert : certs) {
certChain.add((X509Certificate) cert);
}
results.put((X509Certificate) certs[0], certChain);
}
return results;
} catch (Exception e) {
return Collections.emptyMap();
}
}
@Override
public final A adapt(Class adapterType) {
checkAdaptPermission(adapterType);
return adapt0(adapterType);
}
private void readLock() {
equinoxContainer.getStorage().getModuleDatabase().readLock();
}
private void readUnlock() {
equinoxContainer.getStorage().getModuleDatabase().readUnlock();
}
@SuppressWarnings("unchecked")
private A adapt0(Class adapterType) {
if (AccessControlContext.class.equals(adapterType)) {
Generation current = (Generation) module.getCurrentRevision().getRevisionInfo();
ProtectionDomain domain = current.getDomain();
return (A) (domain == null ? null : new AccessControlContext(new ProtectionDomain[] {domain}));
}
if (BundleContext.class.equals(adapterType)) {
try {
return (A) getBundleContext();
} catch (SecurityException e) {
return null;
}
}
if (BundleRevision.class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
return (A) module.getCurrentRevision();
}
if (BundleRevisions.class.equals(adapterType)) {
return (A) module.getRevisions();
}
if (BundleStartLevel.class.equals(adapterType)) {
return (A) module;
}
if (BundleWiring.class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
ModuleRevision revision = module.getCurrentRevision();
if (revision == null) {
return null;
}
return (A) revision.getWiring();
}
if (BundleDTO.class.equals(adapterType)) {
// Unfortunately we need to lock here to make sure the BSN and version
// are consistent in case of updates
readLock();
try {
return (A) DTOBuilder.newBundleDTO(this);
} finally {
readUnlock();
}
}
if (BundleStartLevelDTO.class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
return (A) DTOBuilder.newBundleStartLevelDTO(this, module);
}
if (BundleRevisionDTO.class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
return (A) DTOBuilder.newBundleRevisionDTO(module.getCurrentRevision());
}
if (BundleRevisionDTO[].class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
// No need to lock the database here since the ModuleRevisions object does the
// proper locking for us.
return (A) DTOBuilder.newArrayBundleRevisionDTO(module.getRevisions());
}
if (BundleWiringDTO.class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
readLock();
try {
return (A) DTOBuilder.newBundleWiringDTO(module.getCurrentRevision());
} finally {
readUnlock();
}
}
if (BundleWiringDTO[].class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
readLock();
try {
return (A) DTOBuilder.newArrayBundleWiringDTO(module.getRevisions());
} finally {
readUnlock();
}
}
if (ServiceReferenceDTO[].class.equals(adapterType)) {
if (module.getState().equals(State.UNINSTALLED)) {
return null;
}
BundleContextImpl current = getBundleContextImpl();
ServiceReference>[] references = (current == null) ? null : equinoxContainer.getServiceRegistry().getRegisteredServices(current);
return (A) DTOBuilder.newArrayServiceReferenceDTO(references);
}
if (getBundleId() == 0) {
if (Framework.class.equals(adapterType)) {
return (A) this;
}
if (FrameworkStartLevel.class.equals(adapterType)) {
return (A) module.getContainer().getFrameworkStartLevel();
}
if (FrameworkWiring.class.equals(adapterType)) {
return (A) module.getContainer().getFrameworkWiring();
}
if (FrameworkDTO.class.equals(adapterType)) {
BundleContextImpl current = getBundleContextImpl();
Map configuration = equinoxContainer.getConfiguration().getConfiguration();
readLock();
try {
return (A) DTOBuilder.newFrameworkDTO(current, configuration);
} finally {
readUnlock();
}
}
if (FrameworkStartLevelDTO.class.equals(adapterType)) {
return (A) DTOBuilder.newFrameworkStartLevelDTO(module.getContainer().getFrameworkStartLevel());
}
if (FrameworkWiringDTO.class.equals(adapterType)) {
readLock();
try {
Set allWirings = new HashSet<>();
for (Module m : module.getContainer().getModules()) {
for (ModuleRevision revision : m.getRevisions().getModuleRevisions()) {
ModuleWiring wiring = revision.getWiring();
if (wiring != null) {
allWirings.add(wiring);
}
}
}
for (ModuleRevision revision : module.getContainer().getRemovalPending()) {
ModuleWiring wiring = revision.getWiring();
if (wiring != null) {
allWirings.add(wiring);
}
}
return (A) DTOBuilder.newFrameworkWiringDTO(allWirings);
} finally {
readUnlock();
}
}
}
// Equinox extras
if (Module.class.equals(adapterType)) {
return (A) module;
}
if (ProtectionDomain.class.equals(adapterType)) {
Generation current = (Generation) module.getCurrentRevision().getRevisionInfo();
return (A) current.getDomain();
}
if (SignedContent.class.equals(adapterType)) {
return (A) getSignedContent();
}
if (File.class.equals(adapterType)) {
Generation current = (Generation) module.getCurrentRevision().getRevisionInfo();
return (A) current.getContent();
}
return null;
}
private SignedContent getSignedContent() {
SignedContent current = signedContent;
if (current == null) {
SignedContentFactory factory = equinoxContainer.getSignedContentFactory();
if (factory == null) {
return null;
}
try {
signedContent = current = factory.getSignedContent(this);
} catch (InvalidKeyException | SignatureException | CertificateException | NoSuchAlgorithmException
| NoSuchProviderException | IOException e) {
return null;
}
}
return current;
}
/**
* Check for permission to adapt.
*/
private void checkAdaptPermission(Class adapterType) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return;
}
sm.checkPermission(new AdaptPermission(adapterType.getName(), this, AdaptPermission.ADAPT));
}
@Override
public File getDataFile(String filename) {
checkValid();
Generation current = (Generation) module.getCurrentRevision().getRevisionInfo();
return current.getBundleInfo().getDataFile(filename);
}
@Override
public Bundle getBundle() {
return this;
}
public Module getModule() {
return module;
}
private final void checkValid() {
if (module.getState().equals(State.UNINSTALLED))
throw new IllegalStateException("Bundle has been uninstalled: " + this); //$NON-NLS-1$
}
public boolean isFragment() {
return (getModule().getCurrentRevision().getTypes() & BundleRevision.TYPE_FRAGMENT) != 0;
}
void startWorker0() throws BundleException {
BundleContextImpl current = createBundleContext();
if (current == null) {
throw new BundleException("Unable to create bundle context! " + this); //$NON-NLS-1$
}
try {
current.start();
} catch (BundleException e) {
current.close();
synchronized (EquinoxBundle.this.monitor) {
context = null;
}
throw e;
}
}
void stopWorker0() throws BundleException {
BundleContextImpl current = getBundleContextImpl();
if (current != null) {
try {
current.stop();
} finally {
current.close();
}
synchronized (EquinoxBundle.this.monitor) {
context = null;
}
}
}
ResolutionReport resolve() {
if (!Module.RESOLVED_SET.contains(module.getState())) {
return module.getContainer().resolve(Collections.singletonList(module), true);
}
return null;
}
List getGenerations() {
List result = new ArrayList<>();
ModuleRevision current = getModule().getCurrentRevision();
result.add((Generation) current.getRevisionInfo());
ModuleWiring wiring = current.getWiring();
if (wiring != null) {
List hostWires = wiring.getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
if (hostWires != null) {
for (ModuleWire hostWire : hostWires) {
result.add((Generation) hostWire.getRequirer().getRevisionInfo());
}
}
}
return result;
}
EquinoxContainer getEquinoxContainer() {
return equinoxContainer;
}
@Override
public String toString() {
String name = getSymbolicName();
if (name == null)
name = "unknown"; //$NON-NLS-1$
return (name + '_' + getVersion() + " [" + getBundleId() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
}