Search in sources :

Example 1 with BundleRequirementImpl

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;
}
Also used : Bundle(org.osgi.framework.Bundle) ArrayList(java.util.ArrayList) BundleWire(org.osgi.framework.wiring.BundleWire) BundleRequirementImpl(org.apache.felix.framework.wiring.BundleRequirementImpl) ExportedPackage(org.osgi.service.packageadmin.ExportedPackage) BundleRevision(org.osgi.framework.wiring.BundleRevision) List(java.util.List) ArrayList(java.util.ArrayList) BundleCapability(org.osgi.framework.wiring.BundleCapability) BundleRevisions(org.osgi.framework.wiring.BundleRevisions)

Example 2 with BundleRequirementImpl

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;
}
Also used : BundleCapability(org.osgi.framework.wiring.BundleCapability) Capability(org.osgi.resource.Capability) ResolverHook(org.osgi.framework.hooks.resolver.ResolverHook) ArrayList(java.util.ArrayList) BundleRequirementImpl(org.apache.felix.framework.wiring.BundleRequirementImpl) BundleRequirement(org.osgi.framework.wiring.BundleRequirement) CandidateComparator(org.apache.felix.framework.resolver.CandidateComparator) SimpleFilter(org.apache.felix.framework.capabilityset.SimpleFilter) CapabilitySet(org.apache.felix.framework.capabilityset.CapabilitySet) ShrinkableCollection(org.apache.felix.framework.util.ShrinkableCollection) BundleCapability(org.osgi.framework.wiring.BundleCapability)

Example 3 with BundleRequirementImpl

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;
}
Also used : Wire(org.osgi.resource.Wire) BundleWire(org.osgi.framework.wiring.BundleWire) BundleRequirement(org.osgi.framework.wiring.BundleRequirement) BundleRequirementImpl(org.apache.felix.framework.wiring.BundleRequirementImpl) BundleWiring(org.osgi.framework.wiring.BundleWiring) Wiring(org.osgi.resource.Wiring) BundleRevision(org.osgi.framework.wiring.BundleRevision) List(java.util.List) ArrayList(java.util.ArrayList) BundleWireImpl(org.apache.felix.framework.wiring.BundleWireImpl) BundleCapability(org.osgi.framework.wiring.BundleCapability) Capability(org.osgi.resource.Capability) Resource(org.osgi.resource.Resource) BundleWire(org.osgi.framework.wiring.BundleWire) ResolveException(org.apache.felix.framework.resolver.ResolveException) ResolutionException(org.osgi.service.resolver.ResolutionException) BundleRequirement(org.osgi.framework.wiring.BundleRequirement) Requirement(org.osgi.resource.Requirement) BundleCapability(org.osgi.framework.wiring.BundleCapability)

Example 4 with BundleRequirementImpl

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));
    }
}
Also used : Version(org.osgi.framework.Version) SimpleFilter(org.apache.felix.framework.capabilityset.SimpleFilter) ArrayList(java.util.ArrayList) BundleException(org.osgi.framework.BundleException) BundleRequirement(org.osgi.framework.wiring.BundleRequirement) BundleRequirementImpl(org.apache.felix.framework.wiring.BundleRequirementImpl)

Example 5 with BundleRequirementImpl

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;
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) SimpleFilter(org.apache.felix.framework.capabilityset.SimpleFilter) ArrayList(java.util.ArrayList) BundleRequirement(org.osgi.framework.wiring.BundleRequirement) BundleRequirementImpl(org.apache.felix.framework.wiring.BundleRequirementImpl)

Aggregations

BundleRequirementImpl (org.apache.felix.framework.wiring.BundleRequirementImpl)11 ArrayList (java.util.ArrayList)9 BundleRequirement (org.osgi.framework.wiring.BundleRequirement)8 SimpleFilter (org.apache.felix.framework.capabilityset.SimpleFilter)7 BundleCapability (org.osgi.framework.wiring.BundleCapability)5 HashMap (java.util.HashMap)4 LinkedHashMap (java.util.LinkedHashMap)4 BundleException (org.osgi.framework.BundleException)4 BundleRevision (org.osgi.framework.wiring.BundleRevision)3 BundleWire (org.osgi.framework.wiring.BundleWire)3 Capability (org.osgi.resource.Capability)3 List (java.util.List)2 ResolutionException (org.osgi.service.resolver.ResolutionException)2 IOException (java.io.IOException)1 MalformedURLException (java.net.MalformedURLException)1 PrivilegedActionException (java.security.PrivilegedActionException)1 CapabilitySet (org.apache.felix.framework.capabilityset.CapabilitySet)1 CandidateComparator (org.apache.felix.framework.resolver.CandidateComparator)1 ResolveException (org.apache.felix.framework.resolver.ResolveException)1 ResourceNotFoundException (org.apache.felix.framework.resolver.ResourceNotFoundException)1