use of aQute.bnd.osgi.resource.CapReqBuilder in project bndtools by bndtools.
the class BndBuilderCapReqLoader method loadRequirements.
@Override
public Map<String, List<RequirementWrapper>> loadRequirements() throws Exception {
Builder builder = getBuilder();
if (builder == null)
return Collections.emptyMap();
Jar jar = builder.getJar();
if (jar == null)
return Collections.emptyMap();
Manifest manifest = jar.getManifest();
if (manifest == null)
return Collections.emptyMap();
Attributes attribs = manifest.getMainAttributes();
Map<String, List<RequirementWrapper>> requirements = new HashMap<String, List<RequirementWrapper>>();
// Process imports
String importPkgStr = attribs.getValue(Constants.IMPORT_PACKAGE);
Parameters importsMap = new Parameters(importPkgStr);
for (Entry<String, Attrs> entry : importsMap.entrySet()) {
String pkgName = Processor.removeDuplicateMarker(entry.getKey());
Attrs attrs = entry.getValue();
CapReqBuilder rb = new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE);
String filter = createVersionFilter(PackageNamespace.PACKAGE_NAMESPACE, pkgName, attrs.get(Constants.VERSION_ATTRIBUTE), PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
rb.addDirective(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
if (Constants.RESOLUTION_OPTIONAL.equals(attrs.get(Constants.RESOLUTION_DIRECTIVE + ":")))
rb.addDirective(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE, Namespace.RESOLUTION_OPTIONAL);
Collection<Clazz> importers = findImportingClasses(pkgName, builder);
RequirementWrapper rw = new RequirementWrapper();
rw.requirement = rb.buildSyntheticRequirement();
rw.requirers = importers;
addRequirement(requirements, rw);
}
// Process require-bundle
String requireBundleStr = attribs.getValue(Constants.REQUIRE_BUNDLE);
Parameters requireBundles = new Parameters(requireBundleStr);
for (Entry<String, Attrs> entry : requireBundles.entrySet()) {
String bsn = Processor.removeDuplicateMarker(entry.getKey());
Attrs attrs = entry.getValue();
CapReqBuilder rb = new CapReqBuilder(BundleNamespace.BUNDLE_NAMESPACE);
String filter = createVersionFilter(BundleNamespace.BUNDLE_NAMESPACE, bsn, attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE), BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE);
rb.addDirective(BundleNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
if (Constants.RESOLUTION_OPTIONAL.equals(attrs.get(Constants.RESOLUTION_DIRECTIVE + ":")))
rb.addDirective(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE, Namespace.RESOLUTION_OPTIONAL);
RequirementWrapper rw = new RequirementWrapper();
rw.requirement = rb.buildSyntheticRequirement();
addRequirement(requirements, rw);
}
// Process generic requires
String requiresStr = attribs.getValue(Constants.REQUIRE_CAPABILITY);
Parameters requires = new Parameters(requiresStr);
for (Entry<String, Attrs> entry : requires.entrySet()) {
String ns = Processor.removeDuplicateMarker(entry.getKey());
Attrs attrs = entry.getValue();
CapReqBuilder rb = new CapReqBuilder(ns);
for (String key : attrs.keySet()) {
if (key.endsWith(":"))
rb.addDirective(key.substring(0, key.length() - 1), attrs.get(key));
else
rb.addAttribute(key, attrs.getTyped(key));
}
RequirementWrapper rw = new RequirementWrapper();
rw.requirement = rb.buildSyntheticRequirement();
addRequirement(requirements, rw);
}
return requirements;
}
use of aQute.bnd.osgi.resource.CapReqBuilder in project bndtools by bndtools.
the class ArbitraryNamespaceSearchPanel method validate.
private void validate() {
try {
if (namespace == null || namespace.length() == 0) {
setError(null);
setRequirement(null);
return;
}
for (int i = 0; i < namespace.length(); i++) {
char c = namespace.charAt(i);
if ('.' == c) {
if (i == 0 || i == namespace.length() - 1)
throw new IllegalArgumentException("Namespace cannot have leading or trailing '.' character");
else if ('.' == namespace.charAt(i - 1))
throw new IllegalArgumentException("Namespace cannot have repeated '.' characters");
} else if (!Character.isLetterOrDigit(c) && c != '-' && c != '_')
throw new IllegalArgumentException(String.format("Invalid character in namespace: '%c'", c));
}
updateFilterExpressionHint(namespace);
CapReqBuilder builder = new CapReqBuilder(namespace);
if (filterStr != null && filterStr.trim().length() > 0) {
try {
Filter filter = FrameworkUtil.createFilter(filterStr.trim());
builder.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter.toString());
} catch (InvalidSyntaxException e) {
throw new IllegalArgumentException("Invalid filter string: " + e.getMessage());
}
}
setRequirement(builder.buildSyntheticRequirement());
setError(null);
} catch (Exception e) {
setError(e.getMessage());
setRequirement(null);
}
}
use of aQute.bnd.osgi.resource.CapReqBuilder in project bnd by bndtools.
the class Project method getBundleByHash.
private Container getBundleByHash(String bsn, Map<String, String> attrs) throws Exception {
String hashStr = attrs.get("hash");
String algo = SHA_256;
String hash = hashStr;
int colonIndex = hashStr.indexOf(':');
if (colonIndex > -1) {
algo = hashStr.substring(0, colonIndex);
int afterColon = colonIndex + 1;
hash = (colonIndex < hashStr.length()) ? hashStr.substring(afterColon) : "";
}
for (RepositoryPlugin plugin : workspace.getRepositories()) {
// The plugin *may* understand version=hash directly
DownloadBlocker blocker = new DownloadBlocker(this);
File result = plugin.get(bsn, Version.LOWEST, Collections.unmodifiableMap(attrs), blocker);
// Service, use a capability search on the osgi.content namespace.
if (result == null && plugin instanceof Repository) {
Repository repo = (Repository) plugin;
if (!SHA_256.equals(algo))
// R5 repos only support SHA-256
continue;
Requirement contentReq = new CapReqBuilder(ContentNamespace.CONTENT_NAMESPACE).filter(String.format("(%s=%s)", ContentNamespace.CONTENT_NAMESPACE, hash)).buildSyntheticRequirement();
Set<Requirement> reqs = Collections.singleton(contentReq);
Map<Requirement, Collection<Capability>> providers = repo.findProviders(reqs);
Collection<Capability> caps = providers != null ? providers.get(contentReq) : null;
if (caps != null && !caps.isEmpty()) {
Capability cap = caps.iterator().next();
IdentityCapability idCap = ResourceUtils.getIdentityCapability(cap.getResource());
Map<String, Object> idAttrs = idCap.getAttributes();
String id = (String) idAttrs.get(IdentityNamespace.IDENTITY_NAMESPACE);
Object version = idAttrs.get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
Version bndVersion = version != null ? Version.parseVersion(version.toString()) : Version.LOWEST;
if (!bsn.equals(id)) {
String error = String.format("Resource with requested hash does not match ID '%s' [hash: %s]", bsn, hashStr);
return new Container(this, bsn, "hash", Container.TYPE.ERROR, null, error, null, null);
}
result = plugin.get(id, bndVersion, null, blocker);
}
}
if (result != null)
return toContainer(bsn, "hash", attrs, result, blocker);
}
// If we reach this far, none of the repos found the resource.
return new Container(this, bsn, "hash", Container.TYPE.ERROR, null, "Could not find resource by content hash " + hashStr, null, null);
}
use of aQute.bnd.osgi.resource.CapReqBuilder in project bnd by bndtools.
the class InfoRepositoryWrapper method init.
boolean init() {
try {
if (System.currentTimeMillis() < lastTime + 10000)
return true;
} finally {
lastTime = System.currentTimeMillis();
}
Set<String> errors = new LinkedHashSet<String>();
try {
//
// Get the current repo contents
//
Set<String> toBeDeleted = new HashSet<String>(persistent.keySet());
Map<String, DownloadBlocker> blockers = new HashMap<String, DownloadBlocker>();
for (InfoRepository repo : repos) {
Map<String, ResourceDescriptor> map = collectKeys(repo);
for (final Map.Entry<String, ResourceDescriptor> entry : map.entrySet()) {
final String id = entry.getKey();
toBeDeleted.remove(id);
if (persistent.containsKey(id))
continue;
final ResourceDescriptor rd = entry.getValue();
DownloadBlocker blocker = new DownloadBlocker(null) {
//
// We steal the thread of the downloader to index
//
@Override
public void success(File file) throws Exception {
IndexResult index = null;
try {
index = repoIndexer.indexFile(file);
ResourceBuilder rb = new ResourceBuilder();
for (org.osgi.service.indexer.Capability capability : index.capabilities) {
CapReqBuilder cb = new CapReqBuilder(capability.getNamespace());
cb.addAttributes(capability.getAttributes());
cb.addDirectives(capability.getDirectives());
rb.addCapability(cb.buildSyntheticCapability());
}
for (org.osgi.service.indexer.Requirement requirement : index.requirements) {
CapReqBuilder cb = new CapReqBuilder(requirement.getNamespace());
cb.addAttributes(requirement.getAttributes());
cb.addDirectives(requirement.getDirectives());
rb.addRequirement(cb.buildSyntheticRequirement());
}
Resource resource = rb.build();
PersistentResource pr = new PersistentResource(resource);
persistent.put(id, pr);
} finally {
super.success(file);
if (index != null) {
index.resource.close();
}
}
}
};
blockers.put(entry.getKey(), blocker);
repo.get(rd.bsn, rd.version, null, blocker);
}
}
for (Entry<String, DownloadBlocker> entry : blockers.entrySet()) {
String key = entry.getKey();
DownloadBlocker blocker = entry.getValue();
String reason = blocker.getReason();
if (reason != null) {
errors.add(key + ": " + reason);
}
}
persistent.keySet().removeAll(toBeDeleted);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (!errors.isEmpty())
throw new IllegalStateException("Cannot index " + repos + " due to " + errors);
return true;
}
use of aQute.bnd.osgi.resource.CapReqBuilder in project bnd by bndtools.
the class ResolveTest method testMultipleOptionsNotDuplicated.
/**
* Simple test that resolves a requirement
*
* @throws ResolutionException
*/
public void testMultipleOptionsNotDuplicated() throws ResolutionException {
// Resolve against repo 5
MockRegistry registry = new MockRegistry();
registry.addPlugin(createRepo(IO.getFile("testdata/repo5/index.xml"), "Test-5"));
// Set up a simple Java 7 Felix requirement as per Issue #971
BndEditModel runModel = new BndEditModel();
runModel.setRunFw("org.apache.felix.framework;version='4.2.1'");
runModel.setEE(EE.JavaSE_1_7);
runModel.setSystemPackages(Collections.singletonList(new ExportedPackage("org.w3c.dom.traversal", null)));
runModel.setGenericString("-resolve.effective", "active");
// Require the log service, GoGo shell and GoGo commands
List<Requirement> requirements = new ArrayList<Requirement>();
requirements.add(new CapReqBuilder("osgi.identity").addDirective("filter", "(osgi.identity=org.apache.felix.log)").buildSyntheticRequirement());
requirements.add(new CapReqBuilder("osgi.identity").addDirective("filter", "(osgi.identity=org.apache.felix.gogo.shell)").buildSyntheticRequirement());
requirements.add(new CapReqBuilder("osgi.identity").addDirective("filter", "(osgi.identity=org.apache.felix.gogo.command)").buildSyntheticRequirement());
runModel.setRunRequires(requirements);
// Resolve the bndrun
BndrunResolveContext context = new BndrunResolveContext(runModel, registry, log);
Resolver resolver = new BndResolver(new org.apache.felix.resolver.Logger(4));
Collection<Resource> resolvedResources = new ResolveProcess().resolveRequired(runModel, registry, resolver, Collections.<ResolutionCallback>emptyList(), log).keySet();
Map<String, Resource> mandatoryResourcesBySymbolicName = new HashMap<String, Resource>();
for (Resource r : resolvedResources) {
Capability cap = r.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
// We shouldn't have more than one match for each symbolic name for
// this resolve
String symbolicName = (String) cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE);
assertNull("Multiple results for " + symbolicName, mandatoryResourcesBySymbolicName.put(symbolicName, r));
}
assertEquals(4, resolvedResources.size());
}
Aggregations