Search in sources :

Example 1 with ShrinkableCollection

use of org.apache.felix.framework.util.ShrinkableCollection 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 2 with ShrinkableCollection

use of org.apache.felix.framework.util.ShrinkableCollection in project felix by apache.

the class Felix method getServiceReferences.

/**
 * Retrieves an array of {@link ServiceReference} objects based on calling bundle,
 * service class name, and filter expression.  Optionally checks for isAssignable to
 * make sure that the service can be cast to the
 * @param bundle Calling Bundle
 * @param className Service Classname or <code>null</code> for all
 * @param expr Filter Criteria or <code>null</code>
 * @return Array of ServiceReference objects that meet the criteria
 * @throws InvalidSyntaxException
 */
ServiceReference[] getServiceReferences(final BundleImpl bundle, final String className, final String expr, final boolean checkAssignable) throws InvalidSyntaxException {
    // Define filter if expression is not null.
    SimpleFilter filter = null;
    if (expr != null) {
        try {
            filter = SimpleFilter.parse(expr);
        } catch (Exception ex) {
            throw new InvalidSyntaxException(ex.getMessage(), expr);
        }
    }
    // Ask the service registry for all matching service references.
    final Collection refList = m_registry.getServiceReferences(className, filter);
    // Filter on assignable references
    if (checkAssignable) {
        for (Iterator refIter = refList.iterator(); refIter.hasNext(); ) {
            // Get the current service reference.
            ServiceReference ref = (ServiceReference) refIter.next();
            // Now check for castability.
            if (!Util.isServiceAssignable(bundle, ref)) {
                refIter.remove();
            }
        }
    }
    // If the requesting bundle is the system bundle, ignore the effects of the findhooks
    Collection resRefList = (bundle == this ? new ArrayList(refList) : refList);
    // activate findhooks
    Set<ServiceReference<org.osgi.framework.hooks.service.FindHook>> findHooks = getHookRegistry().getHooks(org.osgi.framework.hooks.service.FindHook.class);
    for (ServiceReference<org.osgi.framework.hooks.service.FindHook> sr : findHooks) {
        org.osgi.framework.hooks.service.FindHook fh = getService(this, sr, false);
        if (fh != null) {
            try {
                m_secureAction.invokeServiceFindHook(fh, bundle._getBundleContext(), className, expr, !checkAssignable, new ShrinkableCollection(refList));
            } catch (Throwable th) {
                m_logger.log(sr, Logger.LOG_WARNING, "Problem invoking service registry hook", th);
            } finally {
                m_registry.ungetService(this, sr, null);
            }
        }
    }
    // the requestor, resRefList is a copy of the original list before the hooks were invoked.
    if (resRefList.size() > 0) {
        return (ServiceReference[]) resRefList.toArray(new ServiceReference[resRefList.size()]);
    }
    return null;
}
Also used : ArrayList(java.util.ArrayList) ServiceException(org.osgi.framework.ServiceException) BundleException(org.osgi.framework.BundleException) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) FileNotFoundException(java.io.FileNotFoundException) AccessControlException(java.security.AccessControlException) ResolutionException(org.osgi.service.resolver.ResolutionException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) ServiceReference(org.osgi.framework.ServiceReference) SimpleFilter(org.apache.felix.framework.capabilityset.SimpleFilter) Iterator(java.util.Iterator) ShrinkableCollection(org.apache.felix.framework.util.ShrinkableCollection) Collection(java.util.Collection) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) ShrinkableCollection(org.apache.felix.framework.util.ShrinkableCollection)

Example 3 with ShrinkableCollection

use of org.apache.felix.framework.util.ShrinkableCollection in project felix by apache.

the class StatefulResolver method selectSingletonsUsingHooks.

/*
     * Groups singletons based on resolver hook filtering and then selects
     * the singleton from each group with the highest version that is in
     * the resolver hook whitelist. No selection is made if a group already
     * has a resolved singleton in it.
     */
private void selectSingletonsUsingHooks(ResolverHookRecord record) throws BundleException {
    // Convert singleton bundle revision map into a map using
    // bundle capabilities instead, since this is what the resolver
    // hooks require.
    Map<BundleCapability, Collection<BundleCapability>> allCollisions = new HashMap<BundleCapability, Collection<BundleCapability>>();
    for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet()) {
        Collection<BundleCapability> bundleCaps = new ArrayList<BundleCapability>();
        for (BundleRevision br : entry.getValue()) {
            List<BundleCapability> caps = br.getDeclaredCapabilities(BundleRevision.BUNDLE_NAMESPACE);
            if (!caps.isEmpty()) {
                bundleCaps.add(caps.get(0));
            }
        }
        for (BundleCapability bc : bundleCaps) {
            Collection<BundleCapability> capCopy = new ShrinkableCollection<BundleCapability>(new ArrayList<BundleCapability>(bundleCaps));
            capCopy.remove(bc);
            allCollisions.put(bc, capCopy);
        }
    }
    // Invoke hooks to allow them to filter singleton collisions.
    for (ResolverHook hook : record.getResolverHooks()) {
        for (Entry<BundleCapability, Collection<BundleCapability>> entry : allCollisions.entrySet()) {
            try {
                Felix.m_secureAction.invokeResolverHookSingleton(hook, entry.getKey(), entry.getValue());
            } catch (Throwable ex) {
                throw new BundleException("Resolver hook exception: " + ex.getMessage(), BundleException.REJECTED_BY_HOOK, ex);
            }
        }
    }
    // Create groups according to how the resolver hooks filtered the
    // collisions.
    List<List<BundleRevision>> groups = new ArrayList<List<BundleRevision>>();
    while (!allCollisions.isEmpty()) {
        BundleCapability target = allCollisions.entrySet().iterator().next().getKey();
        groups.add(groupSingletons(allCollisions, target, new ArrayList<BundleRevision>()));
    }
    // Now select the singletons available for this resolve operation.
    for (List<BundleRevision> group : groups) {
        selectSingleton(record, group);
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ResolverHook(org.osgi.framework.hooks.resolver.ResolverHook) ArrayList(java.util.ArrayList) BundleRevision(org.osgi.framework.wiring.BundleRevision) ShrinkableCollection(org.apache.felix.framework.util.ShrinkableCollection) Collection(java.util.Collection) List(java.util.List) ArrayList(java.util.ArrayList) ShrinkableCollection(org.apache.felix.framework.util.ShrinkableCollection) BundleException(org.osgi.framework.BundleException) BundleCapability(org.osgi.framework.wiring.BundleCapability)

Example 4 with ShrinkableCollection

use of org.apache.felix.framework.util.ShrinkableCollection in project felix by apache.

the class BundleImpl method createRevision.

private BundleRevisionImpl createRevision(boolean isUpdate) throws Exception {
    // Get and parse the manifest from the most recent revision and
    // create an associated revision object for it.
    Map headerMap = Util.getMultiReleaseAwareManifestHeaders(getFramework()._getProperty("java.specification.version"), m_archive.getCurrentRevision());
    // Create the bundle revision instance.
    BundleRevisionImpl revision = new BundleRevisionImpl(this, Long.toString(getBundleId()) + "." + m_archive.getCurrentRevisionNumber().toString(), headerMap, m_archive.getCurrentRevision().getContent());
    // For R4 bundles, verify that the bundle symbolic name + version
    // is unique unless this check has been disabled.
    String allowMultiple = (String) getFramework().getConfig().get(Constants.FRAMEWORK_BSNVERSION);
    allowMultiple = (allowMultiple == null) ? Constants.FRAMEWORK_BSNVERSION_MANAGED : allowMultiple;
    if (revision.getManifestVersion().equals("2") && !allowMultiple.equals(Constants.FRAMEWORK_BSNVERSION_MULTIPLE)) {
        Version bundleVersion = revision.getVersion();
        bundleVersion = (bundleVersion == null) ? Version.emptyVersion : bundleVersion;
        String symName = revision.getSymbolicName();
        List<Bundle> collisionCanditates = new ArrayList<Bundle>();
        Bundle[] bundles = getFramework().getBundles();
        for (int i = 0; (bundles != null) && (i < bundles.length); i++) {
            long id = ((BundleImpl) bundles[i]).getBundleId();
            if (id != getBundleId()) {
                if (symName.equals(bundles[i].getSymbolicName()) && bundleVersion.equals(bundles[i].getVersion())) {
                    collisionCanditates.add(bundles[i]);
                }
            }
        }
        if (!collisionCanditates.isEmpty() && allowMultiple.equals(Constants.FRAMEWORK_BSNVERSION_MANAGED)) {
            Set<ServiceReference<CollisionHook>> hooks = getFramework().getHookRegistry().getHooks(CollisionHook.class);
            if (!hooks.isEmpty()) {
                Collection<Bundle> shrinkableCollisionCandidates = new ShrinkableCollection<Bundle>(collisionCanditates);
                for (ServiceReference<CollisionHook> hook : hooks) {
                    CollisionHook ch = getFramework().getService(getFramework(), hook, false);
                    if (ch != null) {
                        int operationType;
                        Bundle target;
                        if (isUpdate) {
                            operationType = CollisionHook.UPDATING;
                            target = this;
                        } else {
                            operationType = CollisionHook.INSTALLING;
                            target = m_installingBundle == null ? this : m_installingBundle;
                        }
                        Felix.m_secureAction.invokeBundleCollisionHook(ch, operationType, target, shrinkableCollisionCandidates);
                    }
                }
            }
        }
        if (!collisionCanditates.isEmpty()) {
            throw new BundleException("Bundle symbolic name and version are not unique: " + symName + ':' + bundleVersion, BundleException.DUPLICATE_BUNDLE_ERROR);
        }
    }
    return revision;
}
Also used : Bundle(org.osgi.framework.Bundle) ArrayList(java.util.ArrayList) ServiceReference(org.osgi.framework.ServiceReference) Version(org.osgi.framework.Version) ShrinkableCollection(org.apache.felix.framework.util.ShrinkableCollection) BundleException(org.osgi.framework.BundleException) CollisionHook(org.osgi.framework.hooks.bundle.CollisionHook) HashMap(java.util.HashMap) Map(java.util.Map) StringMap(org.apache.felix.framework.util.StringMap)

Aggregations

ArrayList (java.util.ArrayList)4 ShrinkableCollection (org.apache.felix.framework.util.ShrinkableCollection)4 BundleException (org.osgi.framework.BundleException)3 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 SimpleFilter (org.apache.felix.framework.capabilityset.SimpleFilter)2 ServiceReference (org.osgi.framework.ServiceReference)2 ResolverHook (org.osgi.framework.hooks.resolver.ResolverHook)2 BundleCapability (org.osgi.framework.wiring.BundleCapability)2 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 MalformedURLException (java.net.MalformedURLException)1 AccessControlException (java.security.AccessControlException)1 Iterator (java.util.Iterator)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 CapabilitySet (org.apache.felix.framework.capabilityset.CapabilitySet)1 CandidateComparator (org.apache.felix.framework.resolver.CandidateComparator)1 StringMap (org.apache.felix.framework.util.StringMap)1