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

org.eclipse.osgi.container.ModuleRevision 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) 2012, 2016 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.container;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import org.eclipse.osgi.container.ModuleRevisionBuilder.GenericInfo;
import org.eclipse.osgi.container.namespaces.EquinoxModuleDataNamespace;
import org.eclipse.osgi.internal.container.InternalUtils;
import org.eclipse.osgi.internal.container.NamespaceList;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;

/**
 * An implementation of {@link BundleRevision}.
 * @since 3.10
 */
public final class ModuleRevision implements BundleRevision {
	private final String symbolicName;
	private final Version version;
	private final int types;
	private final NamespaceList capabilities;
	private final NamespaceList requirements;
	private final ModuleRevisions revisions;
	private final Object revisionInfo;
	private volatile Boolean lazyActivationPolicy = null;

	ModuleRevision(String symbolicName, Version version, int types, NamespaceList.Builder capabilityInfos, NamespaceList.Builder requirementInfos, ModuleRevisions revisions, Object revisionInfo) {
		this.symbolicName = symbolicName;
		this.version = version;
		this.types = types;
		this.capabilities = createCapabilities(capabilityInfos);
		this.requirements = createRequirements(requirementInfos);
		this.revisions = revisions;
		this.revisionInfo = revisionInfo;
	}

	private NamespaceList createCapabilities(NamespaceList.Builder capabilityInfos) {
		return capabilityInfos.transformIntoCopy(new Function()  {
			public ModuleCapability apply(GenericInfo i) {
				Map directives = i.mutable ? copyUnmodifiableMap(i.directives) : i.directives;
				Map attributes = i.mutable ? copyUnmodifiableMap(i.attributes) : i.attributes;
				return new ModuleCapability(i.namespace, directives, attributes, ModuleRevision.this);
			}
		}, NamespaceList.CAPABILITY).build();
	}

	private static  Map copyUnmodifiableMap(Map map) {
		int size = map.size();
		if (size == 0) {
			return Collections.emptyMap();
		}
		if (size == 1) {
			Map.Entry entry = map.entrySet().iterator().next();
			return Collections.singletonMap(entry.getKey(), entry.getValue());
		}
		return Collections.unmodifiableMap(new HashMap<>(map));
	}

	private NamespaceList createRequirements(NamespaceList.Builder infos) {
		return infos.transformIntoCopy(new Function()  {
			public ModuleRequirement apply(GenericInfo i) {
				return new ModuleRequirement(i.namespace, i.directives, i.attributes, ModuleRevision.this);
			}
		}, NamespaceList.REQUIREMENT).build();
	}

	@Override
	public Bundle getBundle() {
		return revisions.getBundle();
	}

	@Override
	public String getSymbolicName() {
		return symbolicName;
	}

	@Override
	public Version getVersion() {
		return version;
	}

	@Override
	public List getDeclaredCapabilities(String namespace) {
		return InternalUtils.asList(getModuleCapabilities(namespace));
	}

	@Override
	public List getDeclaredRequirements(String namespace) {
		return InternalUtils.asList(getModuleRequirements(namespace));
	}

	/**
	 * Returns the capabilities declared by this revision
	 * @param namespace The namespace of the declared capabilities to return or
	 * {@code null} to return the declared capabilities from all namespaces.
	 * @return An unmodifiable list containing the declared capabilities.
	 */
	public List getModuleCapabilities(String namespace) {
		return capabilities.getList(namespace);
	}

	/**
	 * Returns the requirements declared by this revision
	 * @param namespace The namespace of the declared requirements to return or
	 * {@code null} to return the declared requirements from all namespaces.
	 * @return An unmodifiable list containing the declared requirements.
	 */
	public List getModuleRequirements(String namespace) {
		return requirements.getList(namespace);
	}

	@Override
	public int getTypes() {
		return types;
	}

	@Override
	public ModuleWiring getWiring() {
		return revisions.getContainer().getWiring(this);
	}

	@Override
	public List getCapabilities(String namespace) {
		return InternalUtils.asList(getDeclaredCapabilities(namespace));
	}

	@Override
	public List getRequirements(String namespace) {
		return InternalUtils.asList(getDeclaredRequirements(namespace));
	}

	/**
	 * Returns the {@link ModuleRevisions revisions} for this revision.
	 * @return the {@link ModuleRevisions revisions} for this revision.
	 */
	public ModuleRevisions getRevisions() {
		return revisions;
	}

	/**
	 * Returns the revision info for this revision.  The revision info is
	 * assigned when a revision is created to install a module or update module
	 * @return the revision info for this revision, may be {@code null}.
	 */
	public Object getRevisionInfo() {
		return revisionInfo;
	}

	/**
	 * A convenience method to quickly determine if this revision
	 * has declared the lazy activation policy.
	 * @return true if the lazy activation policy has been declared by this module; otherwise false is returned.
	 */
	public boolean hasLazyActivatePolicy() {
		Boolean currentPolicy = lazyActivationPolicy;
		if (currentPolicy != null) {
			return currentPolicy.booleanValue();
		}
		boolean lazyPolicy = false;
		List data = getCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE);
		if (!data.isEmpty()) {
			Capability moduleData = data.get(0);
			lazyPolicy = EquinoxModuleDataNamespace.CAPABILITY_ACTIVATION_POLICY_LAZY.equals(moduleData.getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_ACTIVATION_POLICY));
		}
		lazyActivationPolicy = Boolean.valueOf(lazyPolicy);
		return lazyPolicy;
	}

	boolean isCurrent() {
		return !revisions.isUninstalled() && this.equals(revisions.getCurrentRevision());
	}

	@Override
	public String toString() {
		List identities = getModuleCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
		if (identities.isEmpty())
			return super.toString();
		return identities.get(0).toString();
	}

	static  String toString(Map map, boolean directives) {
		return toString(map, directives, false);
	}

	static  String toString(Map map, boolean directives, boolean stringsOnly) {
		if (map.size() == 0)
			return ""; //$NON-NLS-1$
		String assignment = directives ? ":=" : "="; //$NON-NLS-1$ //$NON-NLS-2$
		Set> set = map.entrySet();
		StringBuilder sb = new StringBuilder();
		for (Entry entry : set) {
			sb.append("; "); //$NON-NLS-1$
			String key = entry.getKey();
			Object value = entry.getValue();
			if (value instanceof List) {
				@SuppressWarnings("unchecked")
				List list = (List) value;
				if (list.isEmpty())
					continue;
				Object component = list.get(0);
				String className = component.getClass().getName();
				String type = className.substring(className.lastIndexOf('.') + 1);
				sb.append(key).append(':').append("List<").append(type).append(">").append(assignment).append('"'); //$NON-NLS-1$ //$NON-NLS-2$
				for (Object object : list)
					sb.append(object).append(',');
				sb.setLength(sb.length() - 1);
				sb.append('"');
			} else {
				String type = ""; //$NON-NLS-1$
				if (!(value instanceof String) && !stringsOnly) {
					String className = value.getClass().getName();
					type = ":" + className.substring(className.lastIndexOf('.') + 1); //$NON-NLS-1$
				}
				sb.append(key).append(type).append(assignment).append('"').append(value).append('"');
			}
		}
		return sb.toString();
	}

	NamespaceList getCapabilities() {
		return capabilities;
	}

	NamespaceList getRequirements() {
		return requirements;
	}
}