package biz.aQute.resolve.internal;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
import org.osgi.service.repository.Repository;
import aQute.bnd.build.model.EE;
import aQute.bnd.build.model.clauses.ExportedPackage;
import aQute.bnd.deployer.repository.CapabilityIndex;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.resource.CapReqBuilder;
import aQute.lib.utf8properties.*;
public class FrameworkResourceRepository implements Repository {
private final CapabilityIndex capIndex = new CapabilityIndex();
private final Resource framework;
private final EE ee;
public FrameworkResourceRepository(Resource frameworkResource, EE ee, List<ExportedPackage> sysPkgsExtra, Parameters sysCapsExtraParams) {
this.framework = frameworkResource;
this.ee = ee;
capIndex.addResource(frameworkResource);
// Add EEs
addEECapability(capIndex, ee);
for (EE compatibleEE : ee.getCompatible()) {
addEECapability(capIndex, compatibleEE);
}
// Add system.bundle alias
Version frameworkVersion = Utils.findIdentityVersion(frameworkResource);
capIndex.addCapability(new CapReqBuilder(BundleNamespace.BUNDLE_NAMESPACE).addAttribute(BundleNamespace.BUNDLE_NAMESPACE, Constants.SYSTEM_BUNDLE_SYMBOLICNAME)
.addAttribute(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, frameworkVersion).setResource(frameworkResource).buildCapability());
capIndex.addCapability(new CapReqBuilder(HostNamespace.HOST_NAMESPACE).addAttribute(HostNamespace.HOST_NAMESPACE, Constants.SYSTEM_BUNDLE_SYMBOLICNAME)
.addAttribute(HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, frameworkVersion).setResource(frameworkResource).buildCapability());
// Add JRE packages
loadJREPackages();
// Add system.packages.extra
if (sysPkgsExtra != null)
for (ExportedPackage sysPkg : sysPkgsExtra) {
CapReqBuilder builder = new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE);
builder.addAttribute(PackageNamespace.PACKAGE_NAMESPACE, sysPkg.getName());
String versionStr = sysPkg.getVersionString();
Version version = versionStr != null ? new Version(versionStr) : Version.emptyVersion;
builder.addAttribute(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, version);
Capability cap = builder.setResource(framework).buildCapability();
capIndex.addCapability(cap);
}
// Add system capabilities extra
if (sysCapsExtraParams != null) {
for (Entry<String,Attrs> entry : sysCapsExtraParams.entrySet()) {
CapReqBuilder builder = new CapReqBuilder(entry.getKey());
for (String attrKey : entry.getValue().keySet()) {
if (attrKey.endsWith(":")) {
String directiveKey = attrKey.substring(0, attrKey.length() - 1);
builder.addDirective(directiveKey, entry.getValue().get(attrKey));
} else {
builder.addAttribute(attrKey, entry.getValue().getTyped(attrKey));
}
}
builder.setResource(frameworkResource);
capIndex.addCapability(builder.buildCapability());
}
}
}
public void addFrameworkCapability(CapReqBuilder builder) {
Capability cap = builder.setResource(framework).buildCapability();
capIndex.addCapability(cap);
}
private void addEECapability(CapabilityIndex index, EE ee) {
CapReqBuilder builder;
// Correct version according to R5 specification section 3.4.1
// BREE J2SE-1.4 ==> osgi.ee=JavaSE, version:Version=1.4
// See bug 329, https://github.com/bndtools/bnd/issues/329
builder = new CapReqBuilder(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
builder.addAttribute(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE, ee.getCapabilityName());
builder.addAttribute(ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE, ee.getCapabilityVersion());
builder.setResource(framework);
index.addCapability(builder.buildCapability());
// Compatibility with old version...
builder = new CapReqBuilder(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
builder.addAttribute(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE, ee.getEEName());
builder.setResource(framework);
index.addCapability(builder.buildCapability());
}
private void loadJREPackages() {
InputStream stream = FrameworkResourceRepository.class.getResourceAsStream(ee.name() + ".properties");
if (stream != null) {
try {
Properties properties = new UTF8Properties();
properties.load(stream);
Parameters params = new Parameters(properties.getProperty("org.osgi.framework.system.packages", ""));
for (String packageName : params.keySet()) {
CapReqBuilder builder = new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE);
builder.addAttribute(PackageNamespace.PACKAGE_NAMESPACE, packageName);
builder.addAttribute(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, new Version(0, 0, 0));
Capability cap = builder.setResource(framework).buildCapability();
capIndex.addCapability(cap);
}
} catch (IOException e) {
throw new IllegalStateException("Error loading JRE package properties", e);
}
}
}
public Map<Requirement,Collection<Capability>> findProviders(Collection< ? extends Requirement> requirements) {
Map<Requirement,Collection<Capability>> result = new HashMap<Requirement,Collection<Capability>>();
for (Requirement requirement : requirements) {
List<Capability> matches = new LinkedList<Capability>();
result.put(requirement, matches);
capIndex.appendMatchingCapabilities(requirement, matches);
}
return result;
}
public CapabilityIndex getCapabilityIndex() {
return capIndex;
}
}