use of org.apache.karaf.features.internal.resolver.FeatureResource in project karaf by apache.
the class Subsystem method downloadBundles.
@SuppressWarnings("InfiniteLoopStatement")
public void downloadBundles(DownloadManager manager, Set<String> overrides, String featureResolutionRange, final String serviceRequirements, RepositoryManager repos) throws Exception {
for (Subsystem child : children) {
child.downloadBundles(manager, overrides, featureResolutionRange, serviceRequirements, repos);
}
final Map<String, ResourceImpl> bundles = new ConcurrentHashMap<>();
final Downloader downloader = manager.createDownloader();
final Map<BundleInfo, Conditional> infos = new HashMap<>();
if (feature != null) {
for (Conditional cond : feature.getConditional()) {
for (final BundleInfo bi : cond.getBundles()) {
infos.put(bi, cond);
}
}
for (BundleInfo bi : feature.getBundles()) {
infos.put(bi, null);
}
}
boolean removeServiceRequirements;
if (FeaturesService.SERVICE_REQUIREMENTS_DISABLE.equals(serviceRequirements)) {
removeServiceRequirements = true;
} else if (feature != null && FeaturesService.SERVICE_REQUIREMENTS_DEFAULT.equals(serviceRequirements)) {
removeServiceRequirements = FeaturesNamespaces.URI_1_0_0.equals(feature.getNamespace()) || FeaturesNamespaces.URI_1_1_0.equals(feature.getNamespace()) || FeaturesNamespaces.URI_1_2_0.equals(feature.getNamespace()) || FeaturesNamespaces.URI_1_2_1.equals(feature.getNamespace());
} else {
removeServiceRequirements = false;
}
for (Map.Entry<BundleInfo, Conditional> entry : infos.entrySet()) {
final BundleInfo bi = entry.getKey();
final String loc = bi.getLocation();
downloader.download(loc, provider -> {
bundles.put(loc, createResource(loc, getMetadata(provider), removeServiceRequirements));
});
}
for (Clause bundle : Parser.parseClauses(this.bundles.toArray(new String[this.bundles.size()]))) {
final String loc = bundle.getName();
downloader.download(loc, provider -> {
bundles.put(loc, createResource(loc, getMetadata(provider), removeServiceRequirements));
});
}
for (String override : overrides) {
final String loc = Overrides.extractUrl(override);
downloader.download(loc, provider -> {
bundles.put(loc, createResource(loc, getMetadata(provider), removeServiceRequirements));
});
}
if (feature != null) {
for (Library library : feature.getLibraries()) {
if (library.isExport()) {
final String loc = library.getLocation();
downloader.download(loc, provider -> {
bundles.put(loc, createResource(loc, getMetadata(provider), removeServiceRequirements));
});
}
}
}
downloader.await();
Overrides.override(bundles, overrides);
if (feature != null) {
// Add conditionals
Map<Conditional, Resource> resConds = new HashMap<>();
for (Conditional cond : feature.getConditional()) {
FeatureResource resCond = FeatureResource.build(feature, cond, featureResolutionRange, bundles);
addIdentityRequirement(this, resCond, false);
addIdentityRequirement(resCond, this, true);
installable.add(resCond);
resConds.put(cond, resCond);
}
// Add features
FeatureResource resFeature = FeatureResource.build(feature, featureResolutionRange, bundles);
addIdentityRequirement(resFeature, this);
installable.add(resFeature);
// Add dependencies
for (Map.Entry<BundleInfo, Conditional> entry : infos.entrySet()) {
final BundleInfo bi = entry.getKey();
final String loc = bi.getLocation();
final Conditional cond = entry.getValue();
ResourceImpl res = bundles.get(loc);
int sl = bi.getStartLevel() <= 0 ? feature.getStartLevel() : bi.getStartLevel();
if (bi.isDependency()) {
addDependency(res, false, bi.isStart(), sl);
} else {
doAddDependency(res, cond == null, bi.isStart(), sl);
}
if (cond != null) {
addIdentityRequirement(res, resConds.get(cond), true);
}
}
for (Library library : feature.getLibraries()) {
if (library.isExport()) {
final String loc = library.getLocation();
ResourceImpl res = bundles.get(loc);
addDependency(res, false, false, 0);
}
}
for (String uri : feature.getResourceRepositories()) {
BaseRepository repo = repos.getRepository(feature.getRepositoryUrl(), uri);
for (Resource resource : repo.getResources()) {
ResourceImpl res = cloneResource(resource);
addDependency(res, false, true, 0);
}
}
}
for (Clause bundle : Parser.parseClauses(this.bundles.toArray(new String[this.bundles.size()]))) {
final String loc = bundle.getName();
boolean dependency = Boolean.parseBoolean(bundle.getAttribute("dependency"));
boolean start = bundle.getAttribute("start") == null || Boolean.parseBoolean(bundle.getAttribute("start"));
int startLevel = 0;
try {
startLevel = Integer.parseInt(bundle.getAttribute("start-level"));
} catch (NumberFormatException e) {
// Ignore
}
if (dependency) {
addDependency(bundles.get(loc), false, start, startLevel);
} else {
doAddDependency(bundles.get(loc), true, start, startLevel);
addIdentityRequirement(this, bundles.get(loc));
}
}
// Compute dependencies
for (DependencyInfo info : dependencies.values()) {
installable.add(info.resource);
addIdentityRequirement(info.resource, this, info.mandatory);
}
}
use of org.apache.karaf.features.internal.resolver.FeatureResource in project karaf by apache.
the class Subsystem method downloadBundles.
/**
* Downloads bundles for all the features in current and child subsystems. But also collects bundles
* as {@link DependencyInfo}.
*
* @param manager The {@link DownloadManager} to use.
* @param featureResolutionRange The feature resolution range to use.
* @param serviceRequirements The {@link FeaturesService.ServiceRequirementsBehavior} behavior to use.
* @param repos The {@link RepositoryManager} to use.
* @param callback The {@link SubsystemResolverCallback} to use.
*/
@SuppressWarnings("InfiniteLoopStatement")
public void downloadBundles(DownloadManager manager, String featureResolutionRange, final FeaturesService.ServiceRequirementsBehavior serviceRequirements, RepositoryManager repos, SubsystemResolverCallback callback) throws Exception {
for (Subsystem child : children) {
child.downloadBundles(manager, featureResolutionRange, serviceRequirements, repos, callback);
}
// collect BundleInfos for given feature - both direct <feature>/<bundle>s and <feature>/<conditional>/<bundle>s
final Map<BundleInfo, Conditional> infos = new HashMap<>();
final Downloader downloader = manager.createDownloader();
if (feature != null) {
for (Conditional cond : feature.getConditional()) {
if (!cond.isBlacklisted()) {
for (final BundleInfo bi : cond.getBundles()) {
// bundles from conditional features will be added as non-mandatory requirements
infos.put(bi, cond);
}
}
}
for (BundleInfo bi : feature.getBundles()) {
infos.put(bi, null);
}
}
// infos.keySet().removeIf(Blacklisting::isBlacklisted);
for (Iterator<BundleInfo> iterator = infos.keySet().iterator(); iterator.hasNext(); ) {
BundleInfo bi = iterator.next();
if (bi.isBlacklisted()) {
iterator.remove();
if (callback != null) {
callback.bundleBlacklisted(bi);
}
}
}
// all downloaded bundles
final Map<String, ResourceImpl> bundles = new ConcurrentHashMap<>();
// resources for locations that were overriden in OSGi mode - to check whether the override should actually
// take place, by checking resource's headers
final Map<String, ResourceImpl> overrides = new ConcurrentHashMap<>();
boolean removeServiceRequirements = serviceRequirementsBehavior(feature, serviceRequirements);
// download collected BundleInfo locations
for (Map.Entry<BundleInfo, Conditional> entry : infos.entrySet()) {
final BundleInfo bi = entry.getKey();
final String loc = bi.getLocation();
downloader.download(loc, provider -> {
// always download location (could be overriden)
ResourceImpl resource = createResource(loc, getMetadata(provider), removeServiceRequirements);
bundles.put(loc, resource);
if (bi.isOverriden() == BundleInfo.BundleOverrideMode.OSGI) {
// also download original from original bundle URI to check if we should override by comparing
// symbolic name - requires MANIFEST.MF header access. If there should be no override, we'll get
// back to original URI
downloader.download(bi.getOriginalLocation(), provider2 -> {
ResourceImpl originalResource = createResource(bi.getOriginalLocation(), getMetadata(provider2), removeServiceRequirements);
bundles.put(bi.getOriginalLocation(), originalResource);
// an entry in overrides map means that given location was overriden
overrides.put(loc, originalResource);
});
}
});
}
// download direct bundle: requirements - without consulting overrides
for (Clause bundle : Parser.parseClauses(this.bundles.toArray(new String[this.bundles.size()]))) {
final String loc = bundle.getName();
downloader.download(loc, provider -> {
bundles.put(loc, createResource(loc, getMetadata(provider), removeServiceRequirements));
});
}
// resolution process
if (feature != null) {
for (Library library : feature.getLibraries()) {
if (library.isExport()) {
final String loc = library.getLocation();
downloader.download(loc, provider -> {
bundles.put(loc, createResource(loc, getMetadata(provider), removeServiceRequirements));
});
}
}
}
downloader.await();
// opposite to what we had before. Currently bundles are already overriden at model level, but
// as we finally have access to headers, we can compare symbolic names and if override mode is OSGi, then
// we can restore original resource if there should be no override.
Overrides.override(bundles, overrides);
if (feature != null) {
// Add conditionals
Map<Conditional, Resource> resConds = new HashMap<>();
for (Conditional cond : feature.getConditional()) {
if (cond.isBlacklisted()) {
continue;
}
FeatureResource resCond = FeatureResource.build(feature, cond, featureResolutionRange, bundles);
// feature's subsystem will optionally require conditional feature resource
addIdentityRequirement(this, resCond, false);
// but it's a mandatory requirement in other way
addIdentityRequirement(resCond, this, true);
installable.add(resCond);
resConds.put(cond, resCond);
}
// Add features and make it require given subsystem that represents logical feature requirement
FeatureResource resFeature = FeatureResource.build(feature, featureResolutionRange, bundles);
addIdentityRequirement(resFeature, this);
installable.add(resFeature);
// Add dependencies
for (Map.Entry<BundleInfo, Conditional> entry : infos.entrySet()) {
final BundleInfo bi = entry.getKey();
final String loc = bi.getLocation();
final Conditional cond = entry.getValue();
ResourceImpl res = bundles.get(loc);
int sl = bi.getStartLevel() <= 0 ? feature.getStartLevel() : bi.getStartLevel();
if (cond != null) {
// bundle of conditional feature will have mandatory requirement on it
addIdentityRequirement(res, resConds.get(cond), true);
}
boolean mandatory = !bi.isDependency() && cond == null;
if (bi.isDependency()) {
addDependency(res, mandatory, bi.isStart(), sl, bi.isBlacklisted());
} else {
doAddDependency(res, mandatory, bi.isStart(), sl, bi.isBlacklisted());
}
}
for (Library library : feature.getLibraries()) {
if (library.isExport()) {
final String loc = library.getLocation();
ResourceImpl res = bundles.get(loc);
addDependency(res, false, false, 0, false);
}
}
for (String uri : feature.getResourceRepositories()) {
BaseRepository repo = repos.getRepository(feature.getRepositoryUrl(), uri);
for (Resource resource : repo.getResources()) {
ResourceImpl res = cloneResource(resource);
addDependency(res, false, true, 0, false);
}
}
}
for (Clause bundle : Parser.parseClauses(this.bundles.toArray(new String[this.bundles.size()]))) {
final String loc = bundle.getName();
boolean dependency = Boolean.parseBoolean(bundle.getAttribute("dependency"));
boolean start = bundle.getAttribute("start") == null || Boolean.parseBoolean(bundle.getAttribute("start"));
boolean blacklisted = bundle.getAttribute("blacklisted") != null && Boolean.parseBoolean(bundle.getAttribute("blacklisted"));
int startLevel = 0;
try {
startLevel = Integer.parseInt(bundle.getAttribute("start-level"));
} catch (NumberFormatException e) {
// Ignore
}
if (dependency) {
addDependency(bundles.get(loc), false, start, startLevel, blacklisted);
} else {
doAddDependency(bundles.get(loc), true, start, startLevel, blacklisted);
// non dependency bundle will be added as osgi.identity req on type=osgi.bundle
addIdentityRequirement(this, bundles.get(loc));
}
}
// Compute dependencies
for (DependencyInfo info : dependencies.values()) {
installable.add(info.resource);
// bundle resource will have a requirement on its feature's subsystem too
// when bundle is declared with dependency="true", it will have a requirement on its region's subsystem
addIdentityRequirement(info.resource, this, info.mandatory);
}
}
Aggregations