use of org.apache.felix.framework.wiring.BundleRequirementImpl in project felix by apache.
the class Felix method getExportedPackages.
/**
* Returns the exported packages associated with the specified
* package name. This is used by the PackageAdmin service
* implementation.
*
* @param pkgName The name of the exported package to find.
* @return The exported package or null if no matching package was found.
*/
ExportedPackage[] getExportedPackages(String pkgName) {
// First, get all exporters of the package.
Map<String, Object> attrs = Collections.singletonMap(BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
BundleRequirementImpl req = new BundleRequirementImpl(null, BundleRevision.PACKAGE_NAMESPACE, Collections.EMPTY_MAP, attrs);
List<BundleCapability> exports = m_resolver.findProviders(req, false);
// We only want resolved capabilities.
for (Iterator<BundleCapability> it = exports.iterator(); it.hasNext(); ) {
if (it.next().getRevision().getWiring() == null) {
it.remove();
}
}
if (exports != null) {
List pkgs = new ArrayList();
for (Iterator<BundleCapability> it = exports.iterator(); it.hasNext(); ) {
// Get the bundle associated with the current exporting revision.
Bundle bundle = it.next().getRevision().getBundle();
// We need to find the version of the exported package, but this
// is tricky since there may be multiple versions of the package
// offered by a given bundle, since multiple revisions of the
// bundle JAR file may exist if the bundle was updated without
// refreshing the framework. In this case, each revision of the
// bundle JAR file is represented as a revision ordered from
// newest to oldest. We assume that the first revision found to
// be exporting the package is the provider of the package,
// which makes sense since it must have been resolved first.
List<BundleRevision> originRevisions = bundle.adapt(BundleRevisions.class).getRevisions();
for (int i = originRevisions.size() - 1; i >= 0; i--) {
BundleRevision originBr = originRevisions.get(i);
List<BundleRevision> revisions = Collections.singletonList(originBr);
if ((originBr.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) {
// If it's a fragment, find the revisions of the attached
// bundle(s) and work with those instead. Note that fragments
// can be attached to multiple hosts...
revisions = new ArrayList<BundleRevision>();
for (BundleWire bw : originBr.getWiring().getRequiredWires(HostNamespace.HOST_NAMESPACE)) {
revisions.add(bw.getProviderWiring().getRevision());
}
}
for (BundleRevision br : revisions) {
List<BundleCapability> caps = (br.getWiring() == null) ? br.getDeclaredCapabilities(null) : br.getWiring().getCapabilities(null);
for (BundleCapability cap : caps) {
if (cap.getNamespace().equals(req.getNamespace()) && CapabilitySet.matches(cap, req.getFilter())) {
pkgs.add(new ExportedPackageImpl(this, (BundleImpl) br.getBundle(), br, cap));
}
}
}
}
}
return (pkgs.isEmpty()) ? null : (ExportedPackage[]) pkgs.toArray(new ExportedPackage[pkgs.size()]);
}
return null;
}
use of org.apache.felix.framework.wiring.BundleRequirementImpl in project felix by apache.
the class StatefulResolver method findProvidersInternal.
synchronized List<BundleCapability> findProvidersInternal(final ResolverHookRecord record, final Requirement req, final boolean obeyMandatory, final boolean invokeHooksAndSecurity) {
List<BundleCapability> result = new ArrayList<BundleCapability>();
CapabilitySet capSet = m_capSets.get(req.getNamespace());
if (capSet != null) {
// Get the requirement's filter; if this is our own impl we
// have a shortcut to get the already parsed filter, otherwise
// we must parse it from the directive.
SimpleFilter sf;
if (req instanceof BundleRequirementImpl) {
sf = ((BundleRequirementImpl) req).getFilter();
} else {
String filter = req.getDirectives().get(Constants.FILTER_DIRECTIVE);
if (filter == null) {
sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
} else {
sf = SimpleFilter.parse(filter);
}
}
// Find the matching candidates.
Set<Capability> matches = capSet.match(sf, obeyMandatory);
// Filter matching candidates.
for (Capability cap : matches) {
if (!(cap instanceof BundleCapability))
continue;
BundleCapability bcap = (BundleCapability) cap;
// Filter according to security.
if (invokeHooksAndSecurity && filteredBySecurity((BundleRequirement) req, bcap)) {
continue;
}
// dynamic attachment of fragments.
if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE) && (bcap.getRevision().getWiring() != null)) {
continue;
}
result.add(bcap);
}
}
if (invokeHooksAndSecurity) {
// based on a whitelist and/or fine-grained candidate filtering.
if (!result.isEmpty() && !record.getResolverHookRefs().isEmpty()) {
// from disallowed revisions.
if (record.getBundleRevisionWhitelist() != null) {
for (Iterator<BundleCapability> it = result.iterator(); it.hasNext(); ) {
if (!record.getBundleRevisionWhitelist().contains(it.next().getRevision())) {
it.remove();
}
}
}
// Now give the hooks a chance to do fine-grained filtering.
ShrinkableCollection<BundleCapability> shrinkable = new ShrinkableCollection<BundleCapability>(result);
for (ResolverHook hook : record.getResolverHooks()) {
try {
Felix.m_secureAction.invokeResolverHookMatches(hook, (BundleRequirement) req, shrinkable);
} catch (Throwable th) {
m_logger.log(Logger.LOG_WARNING, "Resolver hook exception.", th);
}
}
}
}
Collections.sort(result, new CandidateComparator());
return result;
}
use of org.apache.felix.framework.wiring.BundleRequirementImpl in project felix by apache.
the class StatefulResolver method resolve.
BundleRevision resolve(BundleRevision revision, String pkgName) throws ResolutionException, BundleException {
BundleRevision provider = null;
// acquired the global lock below.
if ((revision.getWiring() != null) && isAllowedDynamicImport(revision, pkgName)) {
// Acquire global lock.
boolean locked = m_felix.acquireGlobalLock();
if (!locked) {
throw new ResolveException("Unable to acquire global lock for resolve.", revision, null);
}
// the case if a resolver hook does something bad.
if (m_isResolving) {
m_felix.releaseGlobalLock();
throw new IllegalStateException("Nested resolve operations not allowed.");
}
m_isResolving = true;
Map<Resource, List<Wire>> wireMap = null;
try {
// Double check to make sure that someone hasn't beaten us to
// dynamically importing the package, which can happen if two
// threads are racing to do so. If we have an existing wire,
// then just return it instead.
provider = ((BundleWiringImpl) revision.getWiring()).getImportedPackageSource(pkgName);
if (provider == null) {
// Prepare resolver hooks, if any.
ResolverHookRecord record = prepareResolverHooks(Collections.singleton(revision), Collections.EMPTY_SET);
// Select any singletons in the resolver state.
selectSingletons(record);
// Catch any resolve exception to rethrow later because
// we may need to call end() on resolver hooks.
ResolutionException rethrow = null;
try {
List<BundleRequirement> dynamics = Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
// Loop through the importer's dynamic requirements to determine if
// there is a matching one for the package from which we want to
// load a class.
Map<String, Object> attrs = Collections.singletonMap(BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
BundleRequirementImpl req = new BundleRequirementImpl(revision, BundleRevision.PACKAGE_NAMESPACE, Collections.EMPTY_MAP, attrs);
final List<BundleCapability> candidates = findProvidersInternal(record, req, false, true);
// Try to find a dynamic requirement that matches the capabilities.
BundleRequirementImpl dynReq = null;
for (int dynIdx = 0; (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size()); dynIdx++) {
for (Iterator<BundleCapability> itCand = candidates.iterator(); (dynReq == null) && itCand.hasNext(); ) {
Capability cap = itCand.next();
if (CapabilitySet.matches(cap, ((BundleRequirementImpl) dynamics.get(dynIdx)).getFilter())) {
dynReq = (BundleRequirementImpl) dynamics.get(dynIdx);
}
}
}
// any candidates that do not match it.
if (dynReq != null) {
for (Iterator<BundleCapability> itCand = candidates.iterator(); itCand.hasNext(); ) {
Capability cap = itCand.next();
if (!CapabilitySet.matches(cap, dynReq.getFilter())) {
itCand.remove();
}
}
} else {
candidates.clear();
}
Map<Resource, Wiring> wirings = getWirings();
wireMap = wirings.containsKey(revision) ? m_resolver.resolveDynamic(new ResolveContextImpl(this, wirings, record, Collections.<BundleRevision>emptyList(), Collections.<BundleRevision>emptyList(), getFragments()) {
@Override
public List<Capability> findProviders(Requirement br) {
return (List) candidates;
}
}, revision.getWiring(), dynReq) : Collections.<Resource, List<Wire>>emptyMap();
} catch (ResolutionException ex) {
rethrow = ex;
}
// Release resolver hooks, if any.
releaseResolverHooks(record);
// If the resolve failed, rethrow the exception.
if (rethrow != null) {
throw rethrow;
}
if ((wireMap != null) && wireMap.containsKey(revision)) {
List<Wire> dynamicWires = wireMap.remove(revision);
Wire dynamicWire = dynamicWires.get(0);
// Mark all revisions as resolved.
markResolvedRevisions(wireMap);
// Dynamically add new wire to importing revision.
if (dynamicWire != null) {
// TODO can we optimize this?
if (dynamicWire.getRequirer() instanceof BundleRevision && dynamicWire.getRequirement() instanceof BundleRequirement && dynamicWire.getProvider() instanceof BundleRevision && dynamicWire.getCapability() instanceof BundleCapability) {
BundleRevision dwRequirer = (BundleRevision) dynamicWire.getRequirer();
BundleRequirement dwRequirement = (BundleRequirement) dynamicWire.getRequirement();
BundleRevision dwProvider = (BundleRevision) dynamicWire.getProvider();
BundleCapability dwCapability = (BundleCapability) dynamicWire.getCapability();
BundleWire bw = new BundleWireImpl(dwRequirer, dwRequirement, dwProvider, dwCapability);
m_felix.getDependencies().addDependent(bw);
((BundleWiringImpl) revision.getWiring()).addDynamicWire(bw);
m_felix.getLogger().log(Logger.LOG_DEBUG, "DYNAMIC WIRE: " + dynamicWire);
provider = ((BundleWiringImpl) revision.getWiring()).getImportedPackageSource(pkgName);
}
}
}
}
} finally {
// Clear resolving flag.
m_isResolving = false;
// Always release the global lock.
m_felix.releaseGlobalLock();
}
fireResolvedEvents(wireMap);
}
return provider;
}
use of org.apache.felix.framework.wiring.BundleRequirementImpl in project felix by apache.
the class ManifestParser method parseBreeHeader.
private static List<BundleRequirement> parseBreeHeader(String header, BundleRevision owner) {
List<String> filters = new ArrayList<String>();
for (String entry : parseDelimitedString(header, ",")) {
List<String> names = parseDelimitedString(entry, "/");
List<String> left = parseDelimitedString(names.get(0), "-");
String lName = left.get(0);
Version lVer;
try {
lVer = Version.parseVersion(left.get(1));
} catch (Exception ex) {
// Version doesn't parse. Make it part of the name.
lName = names.get(0);
lVer = null;
}
String rName = null;
Version rVer = null;
if (names.size() > 1) {
List<String> right = parseDelimitedString(names.get(1), "-");
rName = right.get(0);
try {
rVer = Version.parseVersion(right.get(1));
} catch (Exception ex) {
rName = names.get(1);
rVer = null;
}
}
String versionClause;
if (lVer != null) {
if ((rVer != null) && (!rVer.equals(lVer))) {
// Both versions are defined, but different. Make each of them part of the name
lName = names.get(0);
rName = names.get(1);
versionClause = null;
} else {
versionClause = getBreeVersionClause(lVer);
}
} else {
versionClause = getBreeVersionClause(rVer);
}
if ("J2SE".equals(lName)) {
// J2SE is not used in the Capability variant of BREE, use JavaSE here
// This can only happen with the lName part...
lName = "JavaSE";
}
String nameClause;
if (rName != null)
nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + "/" + rName + ")";
else
nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + ")";
String filter;
if (versionClause != null)
filter = "(&" + nameClause + versionClause + ")";
else
filter = nameClause;
filters.add(filter);
}
if (filters.size() == 0) {
return Collections.emptyList();
} else {
String reqFilter;
if (filters.size() == 1) {
reqFilter = filters.get(0);
} else {
// If there are more BREE filters, we need to or them together
StringBuilder sb = new StringBuilder("(|");
for (String f : filters) {
sb.append(f);
}
sb.append(")");
reqFilter = sb.toString();
}
SimpleFilter sf = SimpleFilter.parse(reqFilter);
return Collections.<BundleRequirement>singletonList(new BundleRequirementImpl(owner, ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE, Collections.singletonMap(ExecutionEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, reqFilter), Collections.<String, Object>emptyMap(), sf));
}
}
use of org.apache.felix.framework.wiring.BundleRequirementImpl in project felix by apache.
the class ManifestParser method convertNativeCode.
static List<BundleRequirement> convertNativeCode(BundleRevision owner, List<NativeLibraryClause> nativeLibraryClauses, boolean hasOptionalLibraryDirective) {
List<BundleRequirement> result = new ArrayList<BundleRequirement>();
List<SimpleFilter> nativeFilterClauseList = new ArrayList<SimpleFilter>();
if (nativeLibraryClauses != null && !nativeLibraryClauses.isEmpty()) {
for (NativeLibraryClause clause : nativeLibraryClauses) {
String[] osNameArray = clause.getOSNames();
String[] osVersionArray = clause.getOSVersions();
String[] processorArray = clause.getProcessors();
String[] languageArray = clause.getLanguages();
String currentSelectionFilter = clause.getSelectionFilter();
List<SimpleFilter> nativeFilterList = new ArrayList<SimpleFilter>();
if (osNameArray != null && osNameArray.length > 0) {
nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE, osNameArray, SimpleFilter.APPROX));
}
if (osVersionArray != null && osVersionArray.length > 0) {
nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE, osVersionArray, SimpleFilter.EQ));
}
if (processorArray != null && processorArray.length > 0) {
nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE, processorArray, SimpleFilter.APPROX));
}
if (languageArray != null && languageArray.length > 0) {
nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE, languageArray, SimpleFilter.APPROX));
}
if (currentSelectionFilter != null) {
nativeFilterList.add(SimpleFilter.parse(currentSelectionFilter));
}
if (!nativeFilterList.isEmpty()) {
SimpleFilter nativeClauseFilter = new SimpleFilter(null, nativeFilterList, SimpleFilter.AND);
nativeFilterClauseList.add(nativeClauseFilter);
}
}
Map<String, String> requirementDirectives = new HashMap<String, String>();
SimpleFilter consolidatedNativeFilter = null;
if (hasOptionalLibraryDirective) {
requirementDirectives.put(NativeNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, NativeNamespace.RESOLUTION_OPTIONAL);
}
if (nativeFilterClauseList.size() > 1) {
consolidatedNativeFilter = new SimpleFilter(null, nativeFilterClauseList, SimpleFilter.OR);
requirementDirectives.put(NativeNamespace.REQUIREMENT_FILTER_DIRECTIVE, consolidatedNativeFilter.toString());
} else if (nativeFilterClauseList.size() == 1) {
consolidatedNativeFilter = nativeFilterClauseList.get(0);
requirementDirectives.put(NativeNamespace.REQUIREMENT_FILTER_DIRECTIVE, consolidatedNativeFilter.toString());
}
if (requirementDirectives.size() > 0) {
result.add(new BundleRequirementImpl(owner, NativeNamespace.NATIVE_NAMESPACE, requirementDirectives, Collections.<String, Object>emptyMap(), consolidatedNativeFilter));
}
}
return result;
}
Aggregations