public void execute()

in src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java [51:144]


    public void execute(AnalyserTaskContext ctx) throws Exception {
        final SortedMap<Integer, List<Descriptor>> artifactsMap = new TreeMap<>();
        for(final BundleDescriptor bi : ctx.getFeatureDescriptor().getBundleDescriptors()) {
            List<Descriptor> list = getDescriptorList(bi.getArtifact().getStartOrder(), artifactsMap);
            list.add(bi);
        }

        if (!ctx.getFeatureDescriptor().getArtifactDescriptors().isEmpty()) {
            artifactsMap.put(
                    (artifactsMap.isEmpty() ? 0 : artifactsMap.lastKey()) + 1,
                    new ArrayList<>(ctx.getFeatureDescriptor().getArtifactDescriptors())
                    );
        }

        String featureMavenID = ctx.getFeature().getId().toMvnId();

        // Add descriptor for feature capabilties. These are added at start level 0
        Descriptor featureCaps = new ReqCapDescriptor(featureMavenID);
        featureCaps.getCapabilities().addAll(ctx.getFeature().getCapabilities());
        getDescriptorList(0, artifactsMap).add(featureCaps);

        // Add descriptor for feature requirements. These are added at the highest start level found
        Descriptor featureReqs = new ReqCapDescriptor(featureMavenID);
        featureReqs.getRequirements().addAll(ctx.getFeature().getRequirements());
        Integer highestStartLevel = artifactsMap.lastKey();
        getDescriptorList(highestStartLevel, artifactsMap).add(featureReqs);

        // add system artifact
        final List<Descriptor> artifacts = new ArrayList<>();
        if ( ctx.getFrameworkDescriptor() != null ) {
            artifacts.add(ctx.getFrameworkDescriptor());
        }

        boolean errorReported = false;
        for(final Map.Entry<Integer, List<Descriptor>> entry : artifactsMap.entrySet()) {
            // first add all providing artifacts
            for (final Descriptor info : entry.getValue()) {
                if (info.getCapabilities() != null) {
                    artifacts.add(info);
                }
            }
            // check requiring artifacts
            for (final Descriptor info : entry.getValue()) {
                if (info.getRequirements() != null)
                {
                    for (Requirement requirement : info.getRequirements()) {
                        String ns = requirement.getNamespace();

                        // Package namespace is handled by the CheckBundleExportsImports analyzer.
                        // Service namespace is special - we don't provide errors or warnings in this case
                        if (!BundleRevision.PACKAGE_NAMESPACE.equals(ns) && !ServiceNamespace.SERVICE_NAMESPACE.equals(ns))
                        {
                            List<Descriptor> candidates = getCandidates(artifacts, requirement);

                            if (candidates.isEmpty())
                            {
                                if (!RequirementImpl.isOptional(requirement))
                                {
                                    String message = String.format(format, info.getName(), requirement.toString(), entry.getKey(), "no artifact is providing a matching capability in this start level.");
                                    if (info instanceof ArtifactDescriptor) {
                                        ctx.reportArtifactError(((ArtifactDescriptor) info).getArtifact().getId(), message);
                                    } else {
                                        ctx.reportError(message);
                                    }
                                    errorReported = true;
                                }
                                else
                                {
                                    String message = String.format(format, info.getName(), requirement.toString(), entry.getKey(), "while the requirement is optional no artifact is providing a matching capability in this start level.");
                                    if (info instanceof ArtifactDescriptor) {
                                        ctx.reportArtifactWarning(((ArtifactDescriptor) info).getArtifact().getId(), message);
                                    } else {
                                        ctx.reportWarning(message);
                                    }
                                }
                            }
                            else if (candidates.size() > 1)
                            {
                                String message = String.format(format, info.getName(), requirement.toString(), entry.getKey(), "there is more than one matching capability in this start level: " + candidates);
                                if (info instanceof ArtifactDescriptor) {
                                    ctx.reportArtifactWarning(((ArtifactDescriptor) info).getArtifact().getId(), message);
                                } else {
                                    ctx.reportWarning(message);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (errorReported && ctx.getFeature().isComplete()) {
            ctx.reportError(ctx.getFeature().getId().toMvnId() + " is marked as 'complete' but has unsatisfied requirements.");
        }
    }