All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.osgi.internal.framework.legacy.PackageAdminImpl Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2003, 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.legacy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.osgi.container.ModuleCapability;
import org.eclipse.osgi.container.ModuleContainer;
import org.eclipse.osgi.container.ModuleWire;
import org.eclipse.osgi.container.ModuleWiring;
import org.eclipse.osgi.internal.container.Capabilities;
import org.eclipse.osgi.internal.container.InternalUtils;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
//import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.resource.Namespace;
import org.osgi.resource.Requirement;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;

@SuppressWarnings("deprecation")
public class PackageAdminImpl implements PackageAdmin {
	private final FrameworkWiring frameworkWiring;
	private final EquinoxContainer equinoxContainer;

	public PackageAdminImpl(EquinoxContainer equinoxContainer, FrameworkWiring frameworkWiring) {
		this.equinoxContainer = equinoxContainer;
		this.frameworkWiring = frameworkWiring;
	}

	@Override
	public ExportedPackage[] getExportedPackages(Bundle bundle) {
		if (bundle == null) {
			return getExportedPackages((String) null);
		}

		Collection revisions = bundle.adapt(BundleRevisions.class).getRevisions();

		Collection allExports = new ArrayList<>();
		for (BundleRevision revision : revisions) {
			ModuleWiring wiring = (ModuleWiring) revision.getWiring();
			if (wiring != null) {
				List providedPackages = wiring
						.getModuleCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
				if (providedPackages != null) {
					for (ModuleCapability providedPackage : providedPackages) {
						allExports.add(new ExportedPackageImpl(providedPackage, wiring));
					}
				}
			}
		}
		return allExports.isEmpty() ? null : allExports.toArray(new ExportedPackage[allExports.size()]);
	}

	@Override
	public ExportedPackage getExportedPackage(String name) {
		ExportedPackage[] allExports = getExportedPackages(name);
		if (allExports == null)
			return null;
		ExportedPackage result = null;
		for (ExportedPackage allExport : allExports) {
			if (name.equals(allExport.getName())) {
				if (result == null) {
					result = allExport;
				} else {
					Version curVersion = result.getVersion();
					Version newVersion = allExport.getVersion();
					if (newVersion.compareTo(curVersion) >= 0) {
						result = allExport;
					}
				}
			}
		}
		return result;
	}

	@Override
	public ExportedPackage[] getExportedPackages(String name) {
		String filter = "(" + PackageNamespace.PACKAGE_NAMESPACE + "=" + (name == null ? "*" : name) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
		Map directives = Collections.singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
		Map attributes = Collections.singletonMap(Capabilities.SYNTHETIC_REQUIREMENT, Boolean.TRUE);
		Requirement packageReq = ModuleContainer.createRequirement(PackageNamespace.PACKAGE_NAMESPACE, directives, attributes);
		Collection packageCaps = frameworkWiring.findProviders(packageReq);
		InternalUtils.filterCapabilityPermissions(packageCaps);
		List result = new ArrayList<>();
		for (BundleCapability capability : packageCaps) {
			ModuleWiring wiring = (ModuleWiring) capability.getRevision().getWiring();
			if (wiring != null) {
				Collection wirings = Collections.emptyList();
				if ((capability.getRevision().getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) {
					// This is a fragment, just get all the host wirings
					List hostWires = wiring.getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
					if (hostWires != null && !hostWires.isEmpty()) {
						wirings = new ArrayList<>(hostWires.size());
						for (ModuleWire hostWire : hostWires) {
							ModuleWiring hostWiring = hostWire.getProviderWiring();
							if (hostWiring != null) {
								wirings.add(hostWiring);
							}
						}
					}
				} else {
					// just a single host wiring
					wirings = Collections.singletonList(wiring);
				}
				for (ModuleWiring moduleWiring : wirings) {
					Object pkgName = capability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
					if (pkgName instanceof String
							&& !moduleWiring.isSubstitutedPackage((String) pkgName)) {
						result.add(new ExportedPackageImpl((ModuleCapability) capability, moduleWiring));
					}
				}
			}
		}
		return (result.size() == 0 ? null : result.toArray(new ExportedPackage[result.size()]));
	}

	@Override
	public void refreshPackages(Bundle[] input) {
		frameworkWiring.refreshBundles(input == null ? null : Arrays.asList(input));
	}

	@Override
	public boolean resolveBundles(Bundle[] input) {
		return frameworkWiring.resolveBundles(input == null ? null : Arrays.asList(input));
	}

	@Override
	public RequiredBundle[] getRequiredBundles(String symbolicName) {
		String filter = "(" + BundleNamespace.BUNDLE_NAMESPACE + "=" + (symbolicName == null ? "*" : symbolicName) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
		Map directives = Collections.singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
		Map attributes = Collections.singletonMap(Capabilities.SYNTHETIC_REQUIREMENT, Boolean.TRUE);
		Requirement bundleReq = ModuleContainer.createRequirement(BundleNamespace.BUNDLE_NAMESPACE, directives, attributes);
		Collection bundleCaps = frameworkWiring.findProviders(bundleReq);
		InternalUtils.filterCapabilityPermissions(bundleCaps);
		Collection result = new ArrayList<>();
		for (BundleCapability capability : bundleCaps) {
			ModuleWiring wiring = (ModuleWiring) capability.getRevision().getWiring();
			if (wiring != null) {
				result.add(new RequiredBundleImpl((ModuleCapability) capability, wiring));
			}
		}
		return result.isEmpty() ? null : result.toArray(new RequiredBundle[result.size()]);
	}

	@Override
	public Bundle[] getBundles(String symbolicName, String versionRange) {
		if (symbolicName == null) {
			throw new IllegalArgumentException();
		}
		if (Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(symbolicName)) {
			// need to alias system.bundle to the implementation BSN
			symbolicName = EquinoxContainer.NAME;
		}
		VersionRange range = versionRange == null ? null : new VersionRange(versionRange);
		String filter = (range != null ? "(&" : "") + "(" + IdentityNamespace.IDENTITY_NAMESPACE + "=" + symbolicName + ")" + (range != null ? range.toFilterString(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE) + ")" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
		Requirement identityReq = ModuleContainer.createRequirement(IdentityNamespace.IDENTITY_NAMESPACE, Collections.singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter), Collections.emptyMap());
		Collection identityCaps = frameworkWiring.findProviders(identityReq);

		if (identityCaps.isEmpty()) {
			return null;
		}
		List sorted = new ArrayList<>(identityCaps.size());
		for (BundleCapability capability : identityCaps) {
			Bundle b = capability.getRevision().getBundle();
			// a sanity check incase this is an old revision
			if (symbolicName.equals(b.getSymbolicName()) && !sorted.contains(b)) {
				sorted.add(b);
			}
		}
		Collections.sort(sorted, Comparator.comparing(Bundle::getVersion).reversed());

		if (sorted.isEmpty()) {
			return null;
		}

		return sorted.toArray(new Bundle[sorted.size()]);
	}

	@Override
	public Bundle[] getFragments(Bundle bundle) {
		ModuleWiring wiring = getWiring(bundle);
		if (wiring == null) {
			return null;
		}
		List hostWires = wiring.getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
		if (hostWires == null) {
			// we don't hold locks while checking the graph, just return if no longer valid
			return null;
		}
		Collection fragments = new ArrayList<>(hostWires.size());
		for (ModuleWire wire : hostWires) {
			Bundle fragment = wire.getRequirer().getBundle();
			if (fragment != null) {
				fragments.add(fragment);
			}
		}
		return fragments.isEmpty() ? null : fragments.toArray(new Bundle[fragments.size()]);
	}

	@Override
	public Bundle[] getHosts(Bundle bundle) {
		ModuleWiring wiring = getWiring(bundle);
		if (wiring == null) {
			return null;
		}
		List hostWires = wiring.getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
		if (hostWires == null) {
			// we don't hold locks while checking the graph, just return if no longer valid
			return null;
		}
		Collection hosts = new ArrayList<>(hostWires.size());
		for (ModuleWire wire : hostWires) {
			Bundle host = wire.getProvider().getBundle();
			if (host != null) {
				hosts.add(host);
			}
		}
		return hosts.isEmpty() ? null : hosts.toArray(new Bundle[hosts.size()]);
	}

	private ModuleWiring getWiring(Bundle bundle) {
		BundleRevision current = bundle.adapt(BundleRevision.class);
		if (current == null) {
			return null;
		}
		return (ModuleWiring) current.getWiring();
	}

	@Override
	public Bundle getBundle(final Class clazz) {
		return equinoxContainer.getBundle(clazz);
	}

	@Override
	public int getBundleType(Bundle bundle) {
		BundleRevision current = bundle.adapt(BundleRevision.class);
		if (current == null) {
			return 0;
		}
		return (current.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0 ? PackageAdmin.BUNDLE_TYPE_FRAGMENT : 0;
	}

	public Collection getRemovalPendingBundles() {
		return frameworkWiring.getRemovalPendingBundles();
	}

	public Collection getDependencyClosure(Collection bundles) {
		return frameworkWiring.getDependencyClosure(bundles);
	}

	static class ExportedPackageImpl implements ExportedPackage {

		private final ModuleCapability packageCapability;
		private final ModuleWiring providerWiring;

		public ExportedPackageImpl(ModuleCapability packageCapability, ModuleWiring providerWiring) {
			this.packageCapability = packageCapability;
			this.providerWiring = providerWiring;
		}

		@Override
		public String getName() {
			return (String) packageCapability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
		}

		@Override
		public Bundle getExportingBundle() {
			if (!providerWiring.isInUse())
				return null;
			return providerWiring.getBundle();
		}

		@Override
		public Bundle[] getImportingBundles() {
			if (!providerWiring.isInUse()) {
				return null;
			}
			Set importing = new HashSet<>();

			String packageName = getName();
			addRequirers(importing, providerWiring, packageName);

			List providedPackages = providerWiring
					.getProvidedModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
			if (providedPackages == null) {
				// we don't hold locks while checking the graph, just return if no longer valid
				return null;
			}
			for (ModuleWire packageWire : providedPackages) {
				if (packageCapability.equals(packageWire.getCapability())) {
					importing.add(packageWire.getRequirer().getBundle());
					if (packageWire.getRequirerWiring().isSubstitutedPackage(packageName)) {
						addRequirers(importing, packageWire.getRequirerWiring(), packageName);
					}
				}
			}
			return importing.toArray(new Bundle[importing.size()]);
		}

		private static void addRequirers(Set importing, ModuleWiring wiring, String packageName) {
			List requirerWires = wiring.getProvidedModuleWires(BundleNamespace.BUNDLE_NAMESPACE);
			if (requirerWires == null) {
				// we don't hold locks while checking the graph, just return if no longer isInUse
				return;
			}
			for (ModuleWire requireBundleWire : requirerWires) {
				Bundle requirer = requireBundleWire.getRequirer().getBundle();
				if (importing.contains(requirer)) {
					continue;
				}
				importing.add(requirer);

				// if reexported then need to add any requirers of the reexporter
				String reExport = requireBundleWire.getRequirement().getDirectives().get(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE);
				ModuleWiring requirerWiring = requireBundleWire.getRequirerWiring();
				if (BundleNamespace.VISIBILITY_REEXPORT.equals(reExport)) {
					addRequirers(importing, requirerWiring, packageName);
				}
				// also need to add any importers of the same package as the wiring exports; case of aggregations
				if (!requirerWiring.equals(wiring)) {
					List providedPackages = requirerWiring
							.getProvidedModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
					if (providedPackages != null) {
						for (ModuleWire packageWire : providedPackages) {
							if (packageName.equals(packageWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) {
								importing.add(packageWire.getRequirer().getBundle());
								if (packageWire.getRequirerWiring().isSubstitutedPackage(packageName)) {
									addRequirers(importing, packageWire.getRequirerWiring(), packageName);
								}
							}
						}
					}
				}
			}
		}


		/**
		 * @deprecated
		 */
		@Override
		public String getSpecificationVersion() {
			return getVersion().toString();
		}

		@Override
		public Version getVersion() {
			Version version = (Version) packageCapability.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
			return version == null ? Version.emptyVersion : version;
		}

		@Override
		public boolean isRemovalPending() {
			return !providerWiring.isCurrent();
		}

		@Override
		public String toString() {
			return packageCapability.toString();
		}
	}

	private static class RequiredBundleImpl implements RequiredBundle {
		private final ModuleCapability bundleCapability;
		private final ModuleWiring providerWiring;

		public RequiredBundleImpl(ModuleCapability bundleCapability, ModuleWiring providerWiring) {
			this.bundleCapability = bundleCapability;
			this.providerWiring = providerWiring;
		}

		@Override
		public String getSymbolicName() {
			return (String) bundleCapability.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE);
		}

		@Override
		public Bundle getBundle() {
			if (!providerWiring.isInUse())
				return null;
			return providerWiring.getBundle();
		}

		@Override
		public Bundle[] getRequiringBundles() {
			if (!providerWiring.isInUse()) {
				return null;
			}
			Set requiring = new HashSet<>();

			addRequirers(requiring, providerWiring);

			return requiring.toArray(new Bundle[requiring.size()]);
		}

		private static void addRequirers(Set requiring, ModuleWiring providerWiring) {
			List requirerWires = providerWiring.getProvidedModuleWires(BundleNamespace.BUNDLE_NAMESPACE);
			if (requirerWires == null) {
				// we don't hold locks while checking the graph, just return if no longer isInUse
				return;
			}
			for (ModuleWire requireBundleWire : requirerWires) {
				Bundle requirer = requireBundleWire.getRequirer().getBundle();
				if (requiring.contains(requirer)) {
					continue;
				}
				requiring.add(requirer);
				String reExport = requireBundleWire.getRequirement().getDirectives().get(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE);
				if (BundleNamespace.VISIBILITY_REEXPORT.equals(reExport)) {
					addRequirers(requiring, requireBundleWire.getRequirerWiring());
				}
			}
		}

		@Override
		public Version getVersion() {
			Version version = (Version) bundleCapability.getAttributes().get(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
			return version == null ? Version.emptyVersion : version;
		}

		@Override
		public boolean isRemovalPending() {
			return !providerWiring.isCurrent();
		}

		@Override
		public String toString() {
			return bundleCapability.toString();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy