package org.eclipse.osgi.container;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.osgi.container.ModuleRevisionBuilder.GenericInfo;
import org.eclipse.osgi.container.namespaces.EquinoxModuleDataNamespace;
import org.eclipse.osgi.internal.container.InternalUtils;
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;
public final class ModuleRevision implements BundleRevision {
private final String symbolicName;
private final Version version;
private final int types;
private final List<ModuleCapability> capabilities;
private final List<ModuleRequirement> requirements;
private final ModuleRevisions revisions;
private final Object revisionInfo;
private volatile Boolean lazyActivationPolicy = null;
ModuleRevision(String symbolicName, Version version, int types, List<GenericInfo> capabilityInfos, List<GenericInfo> 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 List<ModuleCapability> createCapabilities(List<GenericInfo> capabilityInfos) {
if (capabilityInfos == null || capabilityInfos.isEmpty())
return Collections.emptyList();
List<ModuleCapability> result = new ArrayList<>(capabilityInfos.size());
for (GenericInfo info : capabilityInfos) {
result.add(new ModuleCapability(info.namespace, info.directives, info.attributes, this));
}
return result;
}
private List<ModuleRequirement> createRequirements(List<GenericInfo> requirementInfos) {
if (requirementInfos == null || requirementInfos.isEmpty())
return Collections.emptyList();
List<ModuleRequirement> result = new ArrayList<>(requirementInfos.size());
for (GenericInfo info : requirementInfos) {
result.add(new ModuleRequirement(info.namespace, info.directives, info.attributes, this));
}
return result;
}
@Override
public Bundle getBundle() {
return revisions.getBundle();
}
@Override
public String getSymbolicName() {
return symbolicName;
}
@Override
public Version getVersion() {
return version;
}
@Override
public List<BundleCapability> getDeclaredCapabilities(String namespace) {
return InternalUtils.asListBundleCapability(getModuleCapabilities(namespace));
}
@Override
public List<BundleRequirement> getDeclaredRequirements(String namespace) {
return InternalUtils.asListBundleRequirement(getModuleRequirements(namespace));
}
public List<ModuleCapability> getModuleCapabilities(String namespace) {
if (namespace == null)
return Collections.unmodifiableList(capabilities);
List<ModuleCapability> result = new ArrayList<>();
for (ModuleCapability capability : capabilities) {
if (namespace.equals(capability.getNamespace())) {
result.add(capability);
}
}
return Collections.unmodifiableList(result);
}
public List<ModuleRequirement> getModuleRequirements(String namespace) {
if (namespace == null)
return Collections.unmodifiableList(requirements);
List<ModuleRequirement> result = new ArrayList<>();
for (ModuleRequirement requirement : requirements) {
if (namespace.equals(requirement.getNamespace())) {
result.add(requirement);
}
}
return Collections.unmodifiableList(result);
}
@Override
public int getTypes() {
return types;
}
@Override
public ModuleWiring getWiring() {
return revisions.getContainer().getWiring(this);
}
@Override
public List<Capability> getCapabilities(String namespace) {
return InternalUtils.asListCapability(getDeclaredCapabilities(namespace));
}
@Override
public List<Requirement> getRequirements(String namespace) {
return InternalUtils.asListRequirement(getDeclaredRequirements(namespace));
}
public ModuleRevisions getRevisions() {
return revisions;
}
public Object getRevisionInfo() {
return revisionInfo;
}
public boolean hasLazyActivatePolicy() {
Boolean currentPolicy = lazyActivationPolicy;
if (currentPolicy != null) {
return currentPolicy.booleanValue();
}
boolean lazyPolicy = false;
List<Capability> 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<ModuleCapability> identities = getModuleCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
if (identities.isEmpty())
return super.toString();
return identities.get(0).toString();
}
static <V> String toString(Map<String, V> map, boolean directives) {
return toString(map, directives, false);
}
static <V> String toString(Map<String, V> map, boolean directives, boolean stringsOnly) {
if (map.size() == 0)
return "";
String assignment = directives ? ":=" : "=";
Set<Entry<String, V>> set = map.entrySet();
StringBuilder sb = new StringBuilder();
for (Entry<String, V> entry : set) {
sb.append("; ");
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof List) {
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) value;
if (list.size() == 0)
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('"');
for (Object object : list)
sb.append(object).append(',');
sb.setLength(sb.length() - 1);
sb.append('"');
} else {
String type = "";
if (!(value instanceof String) && !stringsOnly) {
String className = value.getClass().getName();
type = ":" + className.substring(className.lastIndexOf('.') + 1);
}
sb.append(key).append(type).append(assignment).append('"').append(value).append('"');
}
}
return sb.toString();
}
}