public void execute()

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


    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);

                            String cardinality = requirement
                                    .getDirectives()
                                    .getOrDefault(
                                            Namespace.REQUIREMENT_CARDINALITY_DIRECTIVE, Namespace.CARDINALITY_SINGLE);
                            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
                                    && Objects.equals(cardinality, Namespace.CARDINALITY_SINGLE)) {
                                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.");
        }
    }