Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2004, 2017 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.internal.loader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.container.ModuleCapability;
import org.eclipse.osgi.container.ModuleLoader;
import org.eclipse.osgi.container.ModuleRequirement;
import org.eclipse.osgi.container.ModuleRevision;
import org.eclipse.osgi.container.ModuleRevisionBuilder;
import org.eclipse.osgi.container.ModuleWire;
import org.eclipse.osgi.container.ModuleWiring;
import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory;
import org.eclipse.osgi.container.namespaces.EquinoxModuleDataNamespace;
import org.eclipse.osgi.framework.util.KeyedElement;
import org.eclipse.osgi.framework.util.KeyedHashSet;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
import org.eclipse.osgi.internal.loader.buddy.PolicyHandler;
import org.eclipse.osgi.internal.loader.sources.MultiSourcePackage;
import org.eclipse.osgi.internal.loader.sources.NullPackageSource;
import org.eclipse.osgi.internal.loader.sources.PackageSource;
import org.eclipse.osgi.internal.loader.sources.SingleSourcePackage;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.framework.wiring.BundleWiring;
/**
* This object is responsible for all classloader delegation for a bundle.
* It represents the loaded state of the bundle. BundleLoader objects
* are created lazily; care should be taken not to force the creation
* of a BundleLoader unless it is necessary.
* @see org.eclipse.osgi.internal.loader.BundleLoaderSources
*/
public class BundleLoader extends ModuleLoader {
public final static String DEFAULT_PACKAGE = "."; //$NON-NLS-1$
public final static String JAVA_PACKAGE = "java."; //$NON-NLS-1$
public final static ClassContext CLASS_CONTEXT = AccessController.doPrivileged(new PrivilegedAction() {
public ClassContext run() {
return new ClassContext();
}
});
public final static ClassLoader FW_CLASSLOADER = getClassLoader(EquinoxContainer.class);
private static final int PRE_CLASS = 1;
private static final int POST_CLASS = 2;
private static final int PRE_RESOURCE = 3;
private static final int POST_RESOURCE = 4;
private static final int PRE_RESOURCES = 5;
private static final int POST_RESOURCES = 6;
private static final Pattern PACKAGENAME_FILTER = Pattern.compile("\\(osgi.wiring.package\\s*=\\s*([^)]+)\\)"); //$NON-NLS-1$
// TODO needed instead of using Collections.emptyEnumertion until we no longer support Java 6
@SuppressWarnings("rawtypes")
private final static Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.emptyList());
private final ModuleWiring wiring;
private final EquinoxContainer container;
private final Debug debug;
private final PolicyHandler policy;
/* List of package names that are exported by this BundleLoader */
private final Collection exportedPackages;
private final BundleLoaderSources exportSources;
/* cache of required package sources. Key is packagename, value is PackageSource */
private final KeyedHashSet requiredSources = new KeyedHashSet(false);
/* cache of imported packages. Key is packagename, Value is PackageSource */
private final KeyedHashSet importedSources = new KeyedHashSet(false);
private final List requiredBundleWires;
/* @GuardedBy("importedSources") */
private boolean importsInitialized = false;
/* @GuardedBy("importedSources") */
private boolean dynamicAllPackages;
/* If not null, list of package stems to import dynamically. */
/* @GuardedBy("importedSources") */
private String[] dynamicImportPackageStems;
/* @GuardedBy("importedSources") */
/* If not null, list of package names to import dynamically. */
private String[] dynamicImportPackages;
private final Object classLoaderCreatedMonitor = new Object();
/* @GuardedBy("classLoaderCreatedMonitor") */
private ModuleClassLoader classLoaderCreated;
private volatile ModuleClassLoader classloader;
private final ClassLoader parent;
private final AtomicBoolean triggerClassLoaded = new AtomicBoolean(false);
/**
* Returns the package name from the specified class name.
* The returned package is dot seperated.
*
* @param name Name of a class.
* @return Dot separated package name or null if the class
* has no package name.
*/
public final static String getPackageName(String name) {
if (name != null) {
int index = name.lastIndexOf('.'); /* find last period in class name */
if (index > 0)
return name.substring(0, index);
}
return DEFAULT_PACKAGE;
}
/**
* Returns the package name from the specified resource name.
* The returned package is dot seperated.
*
* @param name Name of a resource.
* @return Dot separated package name or null if the resource
* has no package name.
*/
public final static String getResourcePackageName(String name) {
if (name != null) {
/* check for leading slash*/
int begin = ((name.length() > 1) && (name.charAt(0) == '/')) ? 1 : 0;
int end = name.lastIndexOf('/'); /* index of last slash */
if (end > begin)
return name.substring(begin, end).replace('/', '.');
}
return DEFAULT_PACKAGE;
}
public BundleLoader(ModuleWiring wiring, EquinoxContainer container, ClassLoader parent) {
this.wiring = wiring;
this.container = container;
this.debug = container.getConfiguration().getDebug();
this.parent = parent;
// init the provided packages set
exportSources = new BundleLoaderSources(this);
List exports = wiring.getModuleCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
exports = exports == null ? new ArrayList(0) : exports;
exportedPackages = Collections.synchronizedCollection(exports.size() > 10 ? new HashSet(exports.size()) : new ArrayList(exports.size()));
initializeExports(exports, exportSources, exportedPackages);
// init the dynamic imports tables
addDynamicImportPackage(wiring.getModuleRequirements(PackageNamespace.PACKAGE_NAMESPACE));
// initialize the required bundle wires
List currentRequireBundleWires = wiring.getRequiredModuleWires(BundleNamespace.BUNDLE_NAMESPACE);
requiredBundleWires = currentRequireBundleWires == null || currentRequireBundleWires.isEmpty() ? Collections. emptyList() : Collections.unmodifiableList(currentRequireBundleWires);
//Initialize the policy handler
List moduleDatas = wiring.getRevision().getModuleCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE);
@SuppressWarnings("unchecked")
List buddyList = (List) (moduleDatas.isEmpty() ? null : moduleDatas.get(0).getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_BUDDY_POLICY));
policy = buddyList != null ? new PolicyHandler(this, buddyList, container.getPackageAdmin()) : null;
if (policy != null) {
Module systemModule = container.getStorage().getModuleContainer().getModule(0);
Bundle systemBundle = systemModule.getBundle();
policy.open(systemBundle.getBundleContext());
}
}
public ModuleWiring getWiring() {
return wiring;
}
public void addFragmentExports(List exports) {
initializeExports(exports, exportSources, exportedPackages);
}
private static void initializeExports(List exports, BundleLoaderSources sources, Collection exportNames) {
if (exports != null) {
for (ModuleCapability export : exports) {
String name = (String) export.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
if (sources.forceSourceCreation(export)) {
if (!exportNames.contains(name)) {
// must force filtered and reexport sources to be created early
// to prevent lazy normal package source creation.
// We only do this for the first export of a package name.
sources.createPackageSource(export, true);
}
}
exportNames.add(name);
}
}
}
final PackageSource createExportPackageSource(ModuleWire importWire, Collection visited) {
String name = (String) importWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
BundleLoader providerLoader = (BundleLoader) importWire.getProviderWiring().getModuleLoader();
if (providerLoader == null) {
return createMultiSource(name, new PackageSource[0]);
}
PackageSource requiredSource = providerLoader.findRequiredSource(name, visited);
PackageSource exportSource = providerLoader.exportSources.createPackageSource(importWire.getCapability(), false);
if (requiredSource == null)
return exportSource;
return createMultiSource(name, new PackageSource[] {requiredSource, exportSource});
}
private static PackageSource createMultiSource(String packageName, PackageSource[] sources) {
if (sources.length == 1)
return sources[0];
List sourceList = new ArrayList<>(sources.length);
for (int i = 0; i < sources.length; i++) {
SingleSourcePackage[] innerSources = sources[i].getSuppliers();
for (int j = 0; j < innerSources.length; j++)
if (!sourceList.contains(innerSources[j]))
sourceList.add(innerSources[j]);
}
return new MultiSourcePackage(packageName, sourceList.toArray(new SingleSourcePackage[sourceList.size()]));
}
public ModuleClassLoader getModuleClassLoader() {
ModuleClassLoader result = classloader;
if (result != null) {
return result;
}
// doing optimistic class loader creating here to avoid holding any locks,
// this may result in multiple classloaders being constructed but only one will be used.
final List hooks = container.getConfiguration().getHookRegistry().getClassLoaderHooks();
final Generation generation = (Generation) wiring.getRevision().getRevisionInfo();
if (System.getSecurityManager() == null) {
result = createClassLoaderPrivledged(parent, generation.getBundleInfo().getStorage().getConfiguration(), this, generation, hooks);
} else {
final ClassLoader cl = parent;
result = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public ModuleClassLoader run() {
return createClassLoaderPrivledged(cl, generation.getBundleInfo().getStorage().getConfiguration(), BundleLoader.this, generation, hooks);
}
});
}
// Synchronize on classLoaderCreatedMonitor in order to ensure hooks are called before returning.
// Note that we do hold a lock here while calling hooks.
// Not ideal, but hooks really should do little work from classLoaderCreated method.
synchronized (classLoaderCreatedMonitor) {
if (classLoaderCreated == null) {
// must set createdClassloader before calling hooks; otherwise we could enter
// and endless loop if the hook causes re-entry (that would be a bad hook impl)
classLoaderCreated = result;
// only send to hooks if this thread wins in creating the class loader.
final ModuleClassLoader cl = result;
// protect with doPriv to avoid bubbling up permission checks that hooks may require
AccessController.doPrivileged(new PrivilegedAction