You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2021/04/19 08:01:42 UTC

[sling-slingfeature-maven-plugin] branch master updated: SLING-10316 : Provide an option to use dependencies for javadoc artifact

This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-slingfeature-maven-plugin.git


The following commit(s) were added to refs/heads/master by this push:
     new 327e53e  SLING-10316 : Provide an option to use dependencies for javadoc artifact
327e53e is described below

commit 327e53eeed826246d487fa52f7be049229f50686
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Apr 19 10:01:32 2021 +0200

    SLING-10316 : Provide an option to use dependencies for javadoc artifact
---
 .../feature/maven/mojos/AbstractFeatureMojo.java   |  10 ++
 .../sling/feature/maven/mojos/ApisJarMojo.java     | 195 ++++++++++++---------
 .../maven/mojos/apis/ApisConfiguration.java        |  78 +++++++++
 .../feature/maven/mojos/apis/ApisJarContext.java   |  50 +++---
 .../feature/maven/mojos/apis/ArtifactType.java     |   1 +
 .../feature/maven/mojos/apis/RegionSupport.java    |  36 ++++
 6 files changed, 267 insertions(+), 103 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java
index e135b0e..dab9549 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java
@@ -333,6 +333,11 @@ public abstract class AbstractFeatureMojo extends AbstractMojo {
     }
 
     protected class BaseFeatureProvider implements FeatureProvider {
+
+        public BaseFeatureProvider() {
+            // public constructor
+        }
+
         @Override
         public Feature provide(ArtifactId id) {
             // Check for the feature in the local context
@@ -353,6 +358,11 @@ public abstract class AbstractFeatureMojo extends AbstractMojo {
     }
 
     protected class BaseArtifactProvider implements ArtifactProvider {
+
+        public BaseArtifactProvider() {
+            // public constructor
+        }
+
         @Override
         public URL provide(final ArtifactId id) {
             try {
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
index 6abba4b..aaa6cf9 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
@@ -291,7 +291,8 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
     /**
      * Comma separated list of Maven repository lists. If set, and
      * {@link #useApiDependencies} is enabled, then one of the listed repositories
-     * must provide the artifact.
+     * must provide the artifact. If it is not set, all artifacts are 
+     * used as dependencies if {@link #useApiDependencies} is enabled.
      *
      * @since 1.3.0
      */
@@ -299,6 +300,25 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
     private String apiRepositoryUrls;
 
     /**
+     * If this is set to {@code false} the javadoc generated will always contain
+     * all APIs even the api from dependencies (if {@link #useApiDependencies}) is
+     * enabled. If this is set to {@code true} the javadoc will not contain the API
+     * from dependencies and exactly match the binary and source jars.
+     * @since 1.5.2
+     */
+    @Parameter(defaultValue = "false")
+    private boolean useApiDependenciesForJavadoc;
+    
+    /**
+     * If {@link #useApiDependencies} is set to {@code true} and {@link #useApiDependenciesForJavadoc}
+     * is set to {@code true} this can be set to {@code false} to generate an additional
+     * javadoc API jar with all javadoc including the API from dependencies.
+     * @since 1.5.2 
+     */
+    @Parameter(defaultValue = "false")
+    private boolean generateJavadocForAllApi;
+
+    /**
      * Fail the build if errors are detected. For example, errors could be missing
      * packages in the api jars, or too many packages in those jars.
      *
@@ -464,11 +484,15 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
         ctx.getConfig().setClassifierMappings(apiClassifierMappings);
         ctx.getConfig().setRegionMappings(apiRegionNameMappings);
         ctx.getConfig().setManifestEntries(manifestProperties);
-        ctx.getConfig().logConfiguration(getLog());
         ctx.getConfig().setEnabledToggles(this.enabledToggles);
         ctx.getConfig().setAdditionalJavadocExtensions(this.javadocAdditionalExtensions);
 
-        ctx.setDependencyRepositories(this.apiRepositoryUrls);
+        ctx.getConfig().setUseApiDependencies(this.useApiDependencies);
+        ctx.getConfig().setUseApiDependenciesForJavadoc(this.useApiDependenciesForJavadoc);
+        ctx.getConfig().setGenerateJavadocForAllApi(this.generateJavadocForAllApi);
+        ctx.getConfig().setDependencyRepositories(this.apiRepositoryUrls);
+
+        ctx.getConfig().logConfiguration(getLog());
 
         // check additional extension configuration first to fail fast
         if ( this.generateJavadocJar ) {
@@ -513,23 +537,25 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
             final File regionDir = new File(featureDir, regionName);
 
             if (generateApiJar) {
-                final Collection<ArtifactInfo> infos = ctx.getArtifactInfos(regionName, this.useApiDependencies);
+                final Collection<ArtifactInfo> infos = ctx.getArtifactInfos(regionName, ctx.getConfig().isUseApiDependencies());
                 this.runProcessor(ctx, apiRegion, ArtifactType.APIS, this.apiResources, infos);
                 final File apiJar = createArchive(ctx, apiRegion, ArtifactType.APIS, this.apiResources, infos, report);
-                report(ctx, apiJar, ArtifactType.APIS, apiRegion, this.useApiDependencies, report, null);
+                report(ctx, apiJar, ArtifactType.APIS, apiRegion, ctx.getConfig().isUseApiDependencies(), report, null);
             }
 
-            if (generateSourceJar) {
-                final Collection<ArtifactInfo> infos = ctx.getArtifactInfos(regionName, this.useApiDependencies);
-                this.runProcessor(ctx, apiRegion, ArtifactType.SOURCES, this.apiResources, infos);
-                final File sourceJar = createArchive(ctx, apiRegion, ArtifactType.SOURCES, this.apiSourceResources, infos, report);
-                report(ctx, sourceJar, ArtifactType.SOURCES, apiRegion, this.useApiDependencies, report, null);
-            } else if ( generateJavadocJar ) {
+            // run processor on sources
+            if ( generateSourceJar || generateJavadocJar ) {
                 final Collection<ArtifactInfo> infos = ctx.getArtifactInfos(regionName, false);
                 this.runProcessor(ctx, apiRegion, ArtifactType.SOURCES, this.apiResources, infos);
             }
 
-            if (this.useApiDependencies && (this.generateApiJar || this.generateSourceJar)) {
+            if (generateSourceJar) {
+                final Collection<ArtifactInfo> infos = ctx.getArtifactInfos(regionName, ctx.getConfig().isUseApiDependencies());
+                final File sourceJar = createArchive(ctx, apiRegion, ArtifactType.SOURCES, this.apiSourceResources, infos, report);
+                report(ctx, sourceJar, ArtifactType.SOURCES, apiRegion, ctx.getConfig().isUseApiDependencies(), report, null);
+            }
+
+            if (ctx.getConfig().isUseApiDependencies() && (this.generateApiJar || this.generateSourceJar)) {
                 this.createDependenciesFile(ctx, apiRegion);
             }
 
@@ -541,16 +567,31 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
                 links.calculateLinks(ctx.getConfig().getJavadocLinks(), ctx.getArtifactInfos(regionName, false),
                         ext != null ? ext.getFramework() : null);
 
-                final Collection<ArtifactInfo> infos = generateJavadoc(ctx, regionName, links, javadocsDir, regionSupport);
+                final Collection<ArtifactInfo> infos = generateJavadoc(ctx, regionName, links, javadocsDir, regionSupport, ctx.getConfig().isUseApiDependenciesForJavadoc());
                 if (infos != null) {
                     ctx.setJavadocDir(javadocsDir);
                     final File javadocJar = createArchive(ctx, apiRegion, ArtifactType.JAVADOC,
                             this.apiJavadocResources, infos, report);
-                    report(ctx, javadocJar, ArtifactType.JAVADOC, apiRegion, false, report, links);
+                    report(ctx, javadocJar, ArtifactType.JAVADOC, apiRegion, ctx.getConfig().isUseApiDependenciesForJavadoc(), report, links);
                 } else {
                     getLog().warn("Javadoc JAR will NOT be generated - sources directory " + ctx.getDeflatedSourcesDir()
                             + " was empty or contained no Java files!");
                 }
+
+                if ( ctx.getConfig().isUseApiDependencies() && ctx.getConfig().isGenerateJavadocForAllApi() ) {
+                    final File javadocsAllDir = new File(regionDir, ArtifactType.JAVADOC_ALL.getId());
+                    final Collection<ArtifactInfo> infosForAll = generateJavadoc(ctx, regionName, links, javadocsAllDir, regionSupport, false);
+                    if (infosForAll != null) {
+                        ctx.setJavadocDir(javadocsAllDir);
+                        final File javadocJar = createArchive(ctx, apiRegion, ArtifactType.JAVADOC_ALL,
+                                this.apiJavadocResources, infosForAll, report);
+                        report(ctx, javadocJar, ArtifactType.JAVADOC, apiRegion, false, report, links);
+                    } else {
+                        getLog().warn("Javadoc JAR will NOT be generated - sources directory " + ctx.getDeflatedSourcesDir()
+                                + " was empty or contained no Java files!");
+                    }
+    
+                }
             }
 
             final ArtifactId reportId = this.buildArtifactId(ctx, apiRegion, ArtifactType.REPORT);
@@ -578,8 +619,12 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
                 .a(" succesfully created").toString());
     }
 
-    private void report(final ApisJarContext ctx, final File jarFile, final ArtifactType artifactType,
-            final ApiRegion apiRegion, final boolean omitDependencyArtifacts, final List<String> report,
+    private void report(final ApisJarContext ctx, 
+            final File jarFile, 
+            final ArtifactType artifactType,
+            final ApiRegion apiRegion, 
+            final boolean omitDependencyArtifacts, 
+            final List<String> report,
             final JavadocLinks links) throws MojoExecutionException {
         final Map.Entry<Set<String>, Set<String>> packageResult = ApisUtil.getPackages(ctx, jarFile,
                 artifactType.getContentExtension());
@@ -616,7 +661,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
         if (links != null) {
             apiPackages.removeAll(links.getLinkedPackages());
         }
-        if (artifactType == ArtifactType.JAVADOC) {
+        if (artifactType == ArtifactType.JAVADOC && !omitDependencyArtifacts) {
             otherPackages.removeAll(ctx.getPackagesWithoutSources());
             // handle additional artifacts
             for(final Artifact artifact : ApisUtil.getAdditionalJavadocArtifacts(ctx, apiRegion.getName()) ) {
@@ -682,35 +727,6 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
         return bundleFile;
     }
 
-    private boolean calculateOmitDependenciesFlag(final ApiRegion region, final Clause[] exportedPackageClauses,
-            final Set<Clause> usedExportedPackagesPerRegion) {
-        // check whether all packages are exported in this region
-        boolean fullUsage = true;
-        for (final Clause c : exportedPackageClauses) {
-            boolean found = false;
-            for (final Clause current : usedExportedPackagesPerRegion) {
-                if (current.getName().equals(c.getName())) {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (!found) {
-                fullUsage = false;
-                break;
-            }
-            // check deprecation - if deprecation is set, artifact can't be used as a
-            // dependency
-            final ApiExport exp = region.getAllExportByName(c.getName());
-            if (exp != null && (exp.getDeprecation().getPackageInfo() != null || !exp.getDeprecation().getMemberInfos().isEmpty())) {
-                fullUsage = false;
-                break;
-            }
-        }
-
-        return fullUsage;
-    }
-
     /**
      * Process a single artifact. This is a "global" processing and not per region
      *
@@ -772,8 +788,8 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
                             exportedPackageClauses, usedExportedPackages);
 
                     // check whether packages are included in api jars - or added as a dependency
-                    boolean useAsDependency = this.useApiDependencies
-                            ? calculateOmitDependenciesFlag(region, exportedPackageClauses,
+                    boolean useAsDependency = ctx.getConfig().isUseApiDependencies()
+                            ? regionSupport.calculateOmitDependenciesFlag(region, exportedPackageClauses,
                                     usedExportedPackagesPerRegion)
                             : false;
                     if (useAsDependency) {
@@ -1539,7 +1555,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
             // api or source
             this.addFileSets(apiRegion, archiveType, infos, jarArchiver, null);
         } else {
-            // javadoc
+            // javadoc or javadoc_all
             final DefaultFileSet fileSet = new DefaultFileSet(ctx.getJavadocDir());
             jarArchiver.addFileSet(fileSet);
         }
@@ -1682,6 +1698,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
      * @param links The links used for javadoc generation
      * @param javadocDir The output directory
      * @param regionSupport The region support
+     * @param useDependencies Whether dependencies should be used
      * @return A collection of artifacts used for the generation or {@code null} if no packages found
      * @throws MojoExecutionException on error
      */
@@ -1689,13 +1706,14 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
             final String regionName,
             final JavadocLinks links,
             final File javadocDir,
-            final RegionSupport regionSupport)
+            final RegionSupport regionSupport,
+            final boolean useDependencies)
     throws MojoExecutionException {
         final Collection<ArtifactInfo> usedInfos = new ArrayList<>();
 
         final List<String> sourceDirectories = new ArrayList<>();
         final Set<String> javadocPackages = new HashSet<>();
-        for(final ArtifactInfo info : ctx.getArtifactInfos(regionName, false)) {
+        for(final ArtifactInfo info : ctx.getArtifactInfos(regionName, useDependencies)) {
             boolean addDirectory = false;
             for(final Clause clause : info.getUsedExportedPackages(regionName)) {
                 if ( !ctx.getPackagesWithoutSources().contains(clause.getName()) && !links.getLinkedPackages().contains(clause.getName())) {
@@ -1714,38 +1732,55 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo {
         }
 
         // handle additional packages
-        for(final Artifact artifact : ApisUtil.getAdditionalJavadocArtifacts(ctx, regionName) ) {
-            final boolean infoExists = ctx.getArtifactInfo(artifact.getId()) != null;
-            final ArtifactInfo info = infoExists ?  ctx.getArtifactInfo(artifact.getId()) : ctx.addArtifactInfo(artifact);
-
-            final Set<Clause> exportedPackages = regionSupport.getAllPublicPackages(ctx, artifact, getArtifactFile(artifact.getId()));
-            final Iterator<Clause> iter = exportedPackages.iterator();
-            final Set<String> exportedPackageNames = new LinkedHashSet<>();
-            while ( iter.hasNext() ) {
-                final Clause c = iter.next();
-                if ( javadocPackages.contains(c.getName()) ) {
-                    iter.remove();
-                } else {
-                    javadocPackages.add(c.getName());
-                    exportedPackageNames.add(c.getName());
-                }
-            }
-
-            if ( !exportedPackages.isEmpty() ) {
-                info.setUsedExportedPackages(regionName, exportedPackages, false);
-                if ( !infoExists ) {
-                    info.setUsedExportedPackages(exportedPackageNames);
-                    info.setSourceDirectory(new File(ctx.getDeflatedSourcesDir(), info.getId().toMvnName()));
-                    final boolean skipSourceDeflate = info.getSourceDirectory().exists();
-                    if (skipSourceDeflate) {
-                        getLog().debug("Source for artifact " + info.getId().toMvnName() + " already deflated");
+        if ( !useDependencies) {
+            for(final Artifact artifact : ApisUtil.getAdditionalJavadocArtifacts(ctx, regionName) ) {
+                final boolean infoExists = ctx.getArtifactInfo(artifact.getId()) != null;
+                final ArtifactInfo info = infoExists ?  ctx.getArtifactInfo(artifact.getId()) : ctx.addArtifactInfo(artifact);
+    
+                final Set<Clause> exportedPackages = regionSupport.getAllPublicPackages(ctx, artifact, getArtifactFile(artifact.getId()));
+                final Iterator<Clause> iter = exportedPackages.iterator();
+                final Set<String> exportedPackageNames = new LinkedHashSet<>();
+                while ( iter.hasNext() ) {
+                    final Clause c = iter.next();
+                    if ( javadocPackages.contains(c.getName()) ) {
+                        iter.remove();
                     } else {
-                        this.downloadSources(ctx, info, artifact);
+                        javadocPackages.add(c.getName());
+                        exportedPackageNames.add(c.getName());
                     }
                 }
-
-                usedInfos.add(info);
-                sourceDirectories.add(info.getSourceDirectory().getAbsolutePath());
+    
+                if ( !exportedPackages.isEmpty() ) {
+                    info.setUsedExportedPackages(regionName, exportedPackages, false);
+                    if ( !infoExists ) {
+                        info.setUsedExportedPackages(exportedPackageNames);
+                        info.setSourceDirectory(new File(ctx.getDeflatedSourcesDir(), info.getId().toMvnName()));
+                        final boolean skipSourceDeflate = info.getSourceDirectory().exists();
+                        if (skipSourceDeflate) {
+                            getLog().debug("Source for artifact " + info.getId().toMvnName() + " already deflated");
+                        } else {
+                            this.downloadSources(ctx, info, artifact);
+                        }
+                    }
+    
+                    usedInfos.add(info);
+                    sourceDirectories.add(info.getSourceDirectory().getAbsolutePath());
+                }
+            }    
+        } else {
+            final Collection<ArtifactInfo> infos = ctx.getArtifactInfos(regionName, true);
+            for(final ArtifactInfo i : ctx.getArtifactInfos(regionName, false)) {
+                if ( !infos.contains(i) ) {
+                    boolean addDirectory = false;
+                    for(final Clause clause : i.getUsedExportedPackages(regionName)) {
+                        if ( !ctx.getPackagesWithoutSources().contains(clause.getName()) && !links.getLinkedPackages().contains(clause.getName())) {
+                            addDirectory = true;
+                        }
+                    }
+                    if ( addDirectory && i.getSourceDirectory() != null ) {
+                        sourceDirectories.add(i.getSourceDirectory().getAbsolutePath());
+                    }        
+                }
             }
         }
         javadocDir.mkdirs();
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisConfiguration.java b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisConfiguration.java
index 41c5cdb..8d6fbfd 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisConfiguration.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisConfiguration.java
@@ -142,6 +142,15 @@ public class ApisConfiguration {
 
     private final Set<String> enabledToggles = new HashSet<>();
 
+    private boolean useApiDependencies;
+
+    /** The set of dependency repositories (URLs) */
+    private final Set<String> dependencyRepositories = new HashSet<>();
+
+    private boolean useApiDependenciesForJavadoc;
+
+    private boolean generateJavadocForAllApi;
+
     /**
      * A map for additional extensions used for javadoc generation.
      * The key is the region name, "*" is used to indicate that these
@@ -187,6 +196,12 @@ public class ApisConfiguration {
     public void logConfiguration(final Log log) {
         if ( log.isInfoEnabled() ) {
             log.info("Using configuration:");
+            log.info("- useApiDependencies : " + this.useApiDependencies);
+            if ( this.useApiDependencies ) {
+                log.info("- dependencyRepositories : " + (this.dependencyRepositories.isEmpty() ? "NONE" : this.dependencyRepositories.toString()));
+                log.info("- useApiDependenciesForJavadoc : " + this.useApiDependenciesForJavadoc);
+                log.info("- generateJavadocForAllApi : " + this.generateJavadocForAllApi);
+            }
             log.info("- " + PROP_JAVADOC_SOURCE_LEVEL + " : " + this.javadocSourceLevel);
             log.info("- " + PROP_JAVADOC_LINKS + " : " + this.javadocLinks);
             log.info("- " + PROP_API_VERSION + " : " + this.apiVersion);
@@ -464,4 +479,67 @@ public class ApisConfiguration {
         result.addAll(this.additionJavadocExtensionNames.getOrDefault(regionName, Collections.emptySet()));
         return result;
     }
+
+    /**
+     * @return the useApiDependencies
+     */
+    public boolean isUseApiDependencies() {
+        return useApiDependencies;
+    }
+
+    /**
+     * @param useApiDependencies the useApiDependencies to set
+     */
+    public void setUseApiDependencies(final boolean flag) {
+        this.useApiDependencies = flag;
+    }
+
+    /**
+     * @return the useApiDependenciesForJavadoc
+     */
+    public boolean isUseApiDependenciesForJavadoc() {
+        return useApiDependenciesForJavadoc;
+    }
+
+    /**
+     * @param useApiDependenciesForJavadoc the useApiDependenciesForJavadoc to set
+     */
+    public void setUseApiDependenciesForJavadoc(final boolean flag) {
+        this.useApiDependenciesForJavadoc = flag;
+    }
+
+    /**
+     * @return the generateJavadocForAllApi
+     */
+    public boolean isGenerateJavadocForAllApi() {
+        return generateJavadocForAllApi;
+    }
+
+    /**
+     * @param generateJavadocForAllApi the generateJavadocForAllApi to set
+     */
+    public void setGenerateJavadocForAllApi(boolean generateJavadocForAllApi) {
+        this.generateJavadocForAllApi = generateJavadocForAllApi;
+    }
+
+    public Set<String> getDependencyRepositories() {
+        return this.dependencyRepositories;
+    }
+
+   /**
+     * Set the dependency repositories
+     * @param list Comma separated list or {@code null}
+     */
+    public void setDependencyRepositories(final String list) {
+        this.dependencyRepositories.clear();
+        if ( list != null ) {
+            for(String val : list.split(",") ) {
+                val = val.trim();
+                if ( !val.endsWith("/") ) {
+                    val = val.concat("/");
+                }
+                this.dependencyRepositories.add(val);
+            }
+        }
+    }    
 }
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java
index 28dbbc9..fc1d3ed 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java
@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.TreeMap;
 
@@ -205,6 +206,29 @@ public class ApisJarContext {
         public Set<String> getSources() {
             return this.sources;
         }
+
+        /* (non-Javadoc)
+         * @see java.lang.Object#hashCode()
+         */
+        
+        @Override
+        public int hashCode() {
+            return Objects.hash(artifact);
+        }
+
+        /* (non-Javadoc)
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (!(obj instanceof ArtifactInfo))
+                return false;
+            ArtifactInfo other = (ArtifactInfo) obj;
+            return Objects.equals(artifact, other.artifact);
+        }
     }
 
     private final ApisConfiguration config;
@@ -229,9 +253,6 @@ public class ApisJarContext {
 
     private final Map<ArtifactId, Model> modelCache = new HashMap<>();
 
-    /** The set of dependency repositories (URLs) */
-    private Set<String> dependencyRepositories = new HashSet<>();
-
     public ApisJarContext(final File mainDir, final Feature feature) throws MojoExecutionException {
         this.config = new ApisConfiguration(feature);
         this.feature = feature;
@@ -327,23 +348,6 @@ public class ApisJarContext {
     }
 
     /**
-     * Set the dependency repositories
-     * @param list Comma separated list or {@code null}
-     */
-    public void setDependencyRepositories(final String list) {
-        this.dependencyRepositories.clear();
-        if ( list != null ) {
-            for(String val : list.split(",") ) {
-                val = val.trim();
-                if ( !val.endsWith("/") ) {
-                    val = val.concat("/");
-                }
-                this.dependencyRepositories.add(val);
-            }
-        }
-    }
-
-    /**
      * Find a an artifact
      * If dependency repositories are configured, one of them must provide the artifact
      * @param log Logger
@@ -353,10 +357,10 @@ public class ApisJarContext {
      */
     private boolean findDependencyArtifact(final Log log, final ArtifactId id) throws MojoExecutionException {
         boolean result = true;
-        if ( !this.dependencyRepositories.isEmpty() ) {
+        if ( !this.getConfig().getDependencyRepositories().isEmpty() ) {
             result = false;
-            log.debug("Trying to resolve ".concat(id.toMvnId()).concat(" from ").concat(this.dependencyRepositories.toString()));
-            for(final String server : this.dependencyRepositories) {
+            log.debug("Trying to resolve ".concat(id.toMvnId()).concat(" from ").concat(this.getConfig().getDependencyRepositories().toString()));
+            for(final String server : this.getConfig().getDependencyRepositories()) {
                 try {
                     final URL url = new URL(server.concat(id.toMvnPath()));
                     try {
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ArtifactType.java b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ArtifactType.java
index ee04840..54f088b 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ArtifactType.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ArtifactType.java
@@ -20,6 +20,7 @@ public enum ArtifactType {
     APIS("apis", "class", "jar"),
     SOURCES("sources", "java", "jar"),
     JAVADOC("javadoc", "html", "jar"),
+    JAVADOC_ALL("javadoc-all", "html", "jar"),
     DEPENDENCIES("apideps", "txt", "ref"),
     CND("cnd", "cnd", "jar"),
     REPORT("report", "txt", "txt");
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/apis/RegionSupport.java b/src/main/java/org/apache/sling/feature/maven/mojos/apis/RegionSupport.java
index 9952eb1..7f15216 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/apis/RegionSupport.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/apis/RegionSupport.java
@@ -259,4 +259,40 @@ public class RegionSupport {
 
         return packages;
     }
+
+    /**
+     * Calculate whether the artifact can be omitted and a dependency can be used instead
+     * @param region The api region
+     * @param exportedPackageClauses All exported packages
+     * @param usedExportedPackagesPerRegion Used exported packages
+     * @return {@code true} if the artifact can be used as a dependency
+     */
+    public boolean calculateOmitDependenciesFlag(final ApiRegion region, final Clause[] exportedPackageClauses,
+            final Set<Clause> usedExportedPackagesPerRegion) {
+        // check whether all packages are exported in this region
+        boolean fullUsage = true;
+        for (final Clause c : exportedPackageClauses) {
+            boolean found = false;
+            for (final Clause current : usedExportedPackagesPerRegion) {
+                if (current.getName().equals(c.getName())) {
+                    found = true;
+                    break;
+                }
+            }
+
+            if (!found) {
+                fullUsage = false;
+                break;
+            }
+            // check deprecation - if deprecation is set, artifact can't be used as a
+            // dependency
+            final ApiExport exp = region.getAllExportByName(c.getName());
+            if (exp != null && (exp.getDeprecation().getPackageInfo() != null || !exp.getDeprecation().getMemberInfos().isEmpty())) {
+                fullUsage = false;
+                break;
+            }
+        }
+
+        return fullUsage;
+    }
 }