in src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java [62:134]
public void execute(final AnalyserTaskContext ctx) throws IOException {
// basic checks
final Map<BundleDescriptor, Report> reports = new HashMap<>();
final SortedMap<Integer, List<BundleDescriptor>> bundlesMap = new TreeMap<>();
for(final BundleDescriptor bi : ctx.getFeatureDescriptor().getBundleDescriptors()) {
bundlesMap.computeIfAbsent(bi.getArtifact().getStartOrder(), key -> new ArrayList<>()).add(bi);
}
// add all system packages
final List<BundleDescriptor> exportingBundles = new ArrayList<>();
if ( ctx.getFrameworkDescriptor() != null ) {
exportingBundles.add(ctx.getFrameworkDescriptor());
}
for(final Map.Entry<Integer, List<BundleDescriptor>> entry : bundlesMap.entrySet()) {
// first add all exporting bundles
for(final BundleDescriptor info : entry.getValue()) {
if ( !info.getExportedPackages().isEmpty() ) {
exportingBundles.add(info);
}
}
// check importing bundles
for(final BundleDescriptor info : entry.getValue()) {
for(final PackageInfo pck : info.getImportedPackages() ) {
final List<BundleDescriptor> candidates = getCandidates(exportingBundles, pck);
if ( candidates.isEmpty() ) {
if ( pck.isOptional() ) {
getReport(reports, info).missingExportsForOptional.add(pck);
} else {
getReport(reports, info).missingExports.add(pck);
}
} else {
final List<BundleDescriptor> matchingCandidates = new ArrayList<>();
for (final BundleDescriptor i : candidates) {
if (i.isExportingPackage(pck)) {
matchingCandidates.add(i);
}
}
if ( matchingCandidates.isEmpty() ) {
if ( pck.isOptional() ) {
getReport(reports, info).missingExportsForOptional.add(pck);
} else {
getReport(reports, info).missingExportsWithVersion.add(pck);
}
} else if ( matchingCandidates.size() > 1 ) {
getReport(reports, info).exportMatchingSeveral.add(pck);
}
}
}
}
}
boolean errorReported = false;
for(final Map.Entry<BundleDescriptor, Report> entry : reports.entrySet()) {
if ( !entry.getValue().missingExports.isEmpty() ) {
ctx.reportArtifactError(entry.getKey().getArtifact().getId(), "Bundle is importing " + getPackageInfo(entry.getValue().missingExports, false) + " with start order " +
String.valueOf(entry.getKey().getArtifact().getStartOrder())
+ " but no bundle is exporting these for that start order.");
errorReported = true;
}
if ( !entry.getValue().missingExportsWithVersion.isEmpty() ) {
ctx.reportArtifactError(entry.getKey().getArtifact().getId(), "Bundle is importing "
+ getPackageInfo(entry.getValue().missingExportsWithVersion, true) + " with start order "
+ String.valueOf(entry.getKey().getArtifact().getStartOrder())
+ " but no bundle is exporting these for that start order in the required version range.");
errorReported = true;
}
}
if (errorReported && ctx.getFeature().isComplete()) {
ctx.reportError(ctx.getFeature().getId().toMvnId() + " is marked as 'complete' but has missing imports.");
}
}