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 2019/10/29 07:12:54 UTC
[sling-slingfeature-maven-plugin] branch master updated: SLING-8813
: Provide a configuration to create incremental apis
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 af16ec7 SLING-8813 : Provide a configuration to create incremental apis
af16ec7 is described below
commit af16ec74a042748977405571fff253692681665e
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Oct 29 08:12:41 2019 +0100
SLING-8813 : Provide a configuration to create incremental apis
---
src/it/apis-jar/pom.xml | 1 +
.../sling/feature/maven/mojos/ApisJarMojo.java | 269 ++++++++++-----------
2 files changed, 128 insertions(+), 142 deletions(-)
diff --git a/src/it/apis-jar/pom.xml b/src/it/apis-jar/pom.xml
index 546d807..0f803ea 100644
--- a/src/it/apis-jar/pom.xml
+++ b/src/it/apis-jar/pom.xml
@@ -50,6 +50,7 @@
<javadocLink>https://osgi.org/javadoc/r6/annotation/</javadocLink>
<javadocLink>https://osgi.org/javadoc/r6/cmpn/</javadocLink>
</javadocLinks>
+ <incrementalApis>false</incrementalApis>
</configuration>
</plugin>
</plugins>
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 7cceb7b..9aad635 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
@@ -27,15 +27,12 @@ import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
-import java.util.Formatter;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
-import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
@@ -87,6 +84,7 @@ import org.apache.sling.feature.Extensions;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.builder.ArtifactProvider;
import org.apache.sling.feature.extension.apiregions.api.ApiExport;
+import org.apache.sling.feature.extension.apiregions.api.ApiRegion;
import org.apache.sling.feature.extension.apiregions.api.ApiRegions;
import org.apache.sling.feature.io.IOUtils;
import org.apache.sling.feature.maven.ProjectHelper;
@@ -131,6 +129,12 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
private static final String SPACE = " ";
+ private static final String PROPERTY_FILTER = ApisJarMojo.class.getName() + ".filter";
+
+ private static final String PROPERTY_CLAUSE = ApisJarMojo.class.getName() + ".clause";
+
+ private static final String PROPERTY_BUNDLE = ApisJarMojo.class.getName() + ".bundle";
+
/**
* Select the features for api generation.
*/
@@ -162,6 +166,14 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
private boolean ignoreJavadocErrors;
/**
+ * If set to true and api jars are created for more than one region, then the
+ * higher region only gets the difference to the lower region. If set to false
+ * each api jar gets the full region information (duplicating information)
+ */
+ @Parameter(defaultValue = "true")
+ private boolean incrementalApis;
+
+ /**
* Additional resources for the api jar
*/
@Parameter
@@ -231,6 +243,12 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
};
}
+ /**
+ * Check if the region is included
+ *
+ * @param name The region name
+ * @return {@code true} if the region is included
+ */
private boolean isRegionIncluded(final String name) {
boolean included = false;
for (final String i : this.includeRegions) {
@@ -260,8 +278,8 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
* or all regions are excluded
* @throws MojoExecutionException If an error occurs
*/
- private ExtendedApiRegions getApiRegions(final Feature feature) throws MojoExecutionException {
- ExtendedApiRegions regions = null;
+ private ApiRegions getApiRegions(final Feature feature) throws MojoExecutionException {
+ ApiRegions regions = null;
Extensions extensions = feature.getExtensions();
Extension apiRegionsExtension = extensions.getByName(ApiRegions.EXTENSION_NAME);
@@ -271,46 +289,59 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
"Feature file " + feature.getId().toMvnId() + " declares an empty '" + ApiRegions.EXTENSION_NAME
+ "' extension, no API JAR will be created");
} else {
- regions = new ExtendedApiRegions();
try {
- // calculate all api-regions first, taking the inheritance in account
- final ApiRegions parsedRegions = ApiRegions
+ regions = ApiRegions
.parse((JsonArray) apiRegionsExtension.getJSONStructure());
- ApiRegion previous = null;
- for (final org.apache.sling.feature.extension.apiregions.api.ApiRegion r : parsedRegions
- .listRegions()) {
- ApiRegion region = new ApiRegion();
- region.setName(r.getName());
- for (final ApiExport pck : r.listExports()) {
- region.addApi(pck.getName());
- }
+ } catch (final IOException ioe) {
+ throw new MojoExecutionException(ioe.getMessage(), ioe);
+ }
- if (previous != null) {
- region.doInherit(previous);
+ // calculate all api-regions first, taking the inheritance in account
+ final List<ApiRegion> toBeRemoved = new ArrayList<>();
+ for (final ApiRegion r : regions.listRegions()) {
+ if (r.getParent() != null && !this.incrementalApis) {
+ for (final ApiExport exp : r.getParent().listExports()) {
+ r.add(exp);
}
- if (isRegionIncluded(region.getName())) {
- regions.regions.add(region);
- } else {
- getLog().debug("API Region " + region.getName()
+ }
+ if (!isRegionIncluded(r.getName())) {
+ getLog().debug("API Region " + r.getName()
+ " will not processed due to the configured include/exclude list");
- }
- previous = region;
+ toBeRemoved.add(r);
}
- } catch (final IOException ioe) {
- throw new MojoExecutionException(ioe.getMessage(), ioe);
}
- if (regions.regions.isEmpty()) {
+ for (final ApiRegion r : toBeRemoved) {
+ regions.remove(r);
+ }
+
+ // prepare filter
+ for (final ApiRegion r : regions.listRegions()) {
+ for (final ApiExport e : r.listExports()) {
+ e.getProperties().put(PROPERTY_FILTER, packageToScannerFiler(e.getName()));
+ }
+ }
+
+ if (regions.isEmpty()) {
getLog().info("Feature file " + feature.getId().toMvnId()
+ " has no included api regions, no API JAR will be created");
regions = null;
}
}
} else {
- regions = new ExtendedApiRegions();
-
- final ApiRegion global = new GlobalApiRegion();
- global.setName("global");
- regions.regions.add(global);
+ regions = new ApiRegions();
+ // create exports on the fly
+ regions.add(new ApiRegion(ApiRegion.GLOBAL) {
+
+ @Override
+ public ApiExport getExportByName(final String name) {
+ ApiExport exp = super.getExportByName(name);
+ if (exp == null) {
+ exp = new ApiExport(name);
+ this.add(exp);
+ }
+ return exp;
+ }
+ });
}
return regions;
@@ -324,12 +355,11 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
getLog().info(MessageUtils.buffer().a("Creating API JARs for Feature ").strong(feature.getId().toMvnId())
.a(" ...").toString());
- final ExtendedApiRegions regions = getApiRegions(feature);
+ final ApiRegions regions = getApiRegions(feature);
if (regions == null) {
// wrongly configured api regions - skip execution
return;
}
- final List<ApiRegion> apiRegions = regions.regions;
if (!mainOutputDir.exists()) {
mainOutputDir.mkdirs();
@@ -347,12 +377,12 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
// for each bundle included in the feature file:
for (Artifact artifact : feature.getBundles()) {
- onArtifact(artifactProvider, artifact, null, apiRegions, javadocClasspath, deflatedBinDir,
+ onArtifact(artifactProvider, artifact, null, regions, javadocClasspath, deflatedBinDir,
deflatedSourcesDir, checkedOutSourcesDir);
}
// recollect and package stuff
- for (ApiRegion apiRegion : apiRegions) {
+ for (ApiRegion apiRegion : regions.listRegions()) {
File regionDir = new File(featureDir, apiRegion.getName());
File apisDir = new File(regionDir, APIS);
@@ -383,9 +413,9 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
private void report(final File jarFile, final String apiType, final ApiRegion apiRegion, final String extension) throws MojoExecutionException {
final List<String> packages = getPackages(jarFile, extension);
- final List<String> missing = new ArrayList<>();
- for (final String exp : apiRegion.getApis()) {
- if (!packages.remove(exp)) {
+ final List<ApiExport> missing = new ArrayList<>();
+ for (final ApiExport exp : apiRegion.listExports()) {
+ if (!packages.remove(exp.getName())) {
missing.add(exp);
}
}
@@ -394,8 +424,8 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
} else {
Collections.sort(missing);
getLog().info(apiType + " jar for region " + apiRegion.getName() + " has errors:");
- for (final String m : missing) {
- getLog().info("- Missing package " + m);
+ for (final ApiExport m : missing) {
+ getLog().info("- Missing package " + m + " from bundle(s) " + m.getProperties().get(PROPERTY_BUNDLE));
}
for (final String m : packages) {
getLog().info("- Wrong package " + m);
@@ -437,7 +467,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
}
private void onArtifact(final ArtifactProvider artifactProvider, Artifact artifact, Manifest wrappingBundleManifest,
- List<ApiRegion> apiRegions, Set<String> javadocClasspath, File deflatedBinDir, File deflatedSourcesDir,
+ ApiRegions apiRegions, Set<String> javadocClasspath, File deflatedBinDir, File deflatedSourcesDir,
File checkedOutSourcesDir) throws MojoExecutionException {
final ArtifactId artifactId = artifact.getId();
final File bundleFile = getArtifactFile(artifactProvider, artifactId);
@@ -452,14 +482,15 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
// check if the bundle is exporting packages?
final Clause[] exportedPackages = this.getExportedPackages(manifest);
if (exportedPackages.length > 0) {
- // get includes for deflating
- final String[] exportPackagesIncludes = computeExportPackageIncludes(exportedPackages);
// calculate the exported versioned packages in the manifest file for each
// region
// and calculate the exported versioned packages in the manifest file for each
// region
- if (computeExports(apiRegions, exportedPackages)) {
+ if (computeExports(apiRegions, exportedPackages, artifactId)) {
+ // get includes for deflating
+ final String[] exportPackagesIncludes = computeExportPackageIncludes(exportedPackages);
+
// deflate all bundles first, in order to copy APIs and resources later,
// depending to the region
final String[] exportedPackagesAndWrappedBundles = Stream
@@ -488,7 +519,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
private void computeWrappedBundles(Manifest manifest,
File deflatedBundleDirectory,
- List<ApiRegion> apiRegions,
+ ApiRegions apiRegions,
Set<String> javadocClasspath,
File deflatedBinDir,
File deflatedSourcesDir,
@@ -927,17 +958,27 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
*
* @return {@code true} if any region exports a package from this set
*/
- private boolean computeExports(List<ApiRegion> apiRegions, final Clause[] exportedPackages)
+ private boolean computeExports(final ApiRegions apiRegions, final Clause[] exportedPackages,
+ final ArtifactId bundle)
throws MojoExecutionException {
boolean hasExport = false;
// filter for each region
- for (Clause exportedPackage : exportedPackages) {
- final String api = exportedPackage.getName();
-
- for (ApiRegion apiRegion : apiRegions) {
- if (apiRegion.containsApi(api)) {
- apiRegion.addExportPackage(exportedPackage);
+ for (final Clause exportedPackage : exportedPackages) {
+ final String packageName = exportedPackage.getName();
+
+ for (ApiRegion apiRegion : apiRegions.listRegions()) {
+ final ApiExport exp = apiRegion.getExportByName(packageName);
+ if (exp != null) {
+ if (exp.getProperties().containsKey(PROPERTY_CLAUSE)) {
+ exp.getProperties().put(PROPERTY_CLAUSE, exp.getProperties().get(PROPERTY_CLAUSE).concat(",")
+ .concat(exportedPackage.toString()));
+ exp.getProperties().put(PROPERTY_BUNDLE,
+ exp.getProperties().get(PROPERTY_BUNDLE).concat(",").concat(bundle.toMvnId()));
+ } else {
+ exp.getProperties().put(PROPERTY_CLAUSE, exportedPackage.toString());
+ exp.getProperties().put(PROPERTY_BUNDLE, bundle.toMvnId());
+ }
hasExport = true;
}
}
@@ -946,6 +987,36 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
return hasExport;
}
+ private String[] getApiFilters(final ApiRegion region) {
+ final List<String> filters = new ArrayList<>();
+ for (final ApiExport exp : region.listExports()) {
+ final String f = exp.getProperties().get(PROPERTY_FILTER);
+ if (f != null) {
+ for (final String v : f.split(",")) {
+ filters.add(v);
+ }
+ }
+ }
+ return filters.toArray(new String[filters.size()]);
+ }
+
+ private String getApiExportClause(final ApiRegion region) {
+ final StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (final ApiExport exp : region.listExports()) {
+ final String v = exp.getProperties().get(PROPERTY_CLAUSE);
+ if (v != null) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(',');
+ }
+ sb.append(v);
+ }
+ }
+ return sb.toString();
+ }
+
private List<String> recollect(File featureDir, File deflatedDir, ApiRegion apiRegion, File destination) throws MojoExecutionException {
final List<String> nodeTypes = new LinkedList<>();
@@ -957,9 +1028,9 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
// for each region, include both APIs and resources
String[] includes;
if (APIS.equals(destination.getName())) {
- includes = concatenate(apiRegion.getFilteringApis(), includeResources);
+ includes = concatenate(getApiFilters(apiRegion), includeResources);
} else {
- includes = apiRegion.getFilteringApis();
+ includes = getApiFilters(apiRegion);
}
directoryScanner.setIncludes(includes);
directoryScanner.scan();
@@ -1040,7 +1111,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
MavenArchiveConfiguration archiveConfiguration = new MavenArchiveConfiguration();
if (APIS.equals(classifier)) {
// APIs need OSGi Manifest entry
- archiveConfiguration.addManifestEntry("Export-Package", StringUtils.join(apiRegion.getExportPackage(), ","));
+ archiveConfiguration.addManifestEntry("Export-Package", getApiExportClause(apiRegion));
archiveConfiguration.addManifestEntry("Bundle-Description", project.getDescription());
archiveConfiguration.addManifestEntry("Bundle-Version", featureId.getOSGiVersion().toString());
archiveConfiguration.addManifestEntry("Bundle-ManifestVersion", "2");
@@ -1139,88 +1210,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
type);
}
- private static class ApiRegion {
-
- private final Set<String> apis = new TreeSet<>();
-
- private final Set<String> filteringApis = new TreeSet<>();
-
- private final List<Clause> exportPackage = new ArrayList<>();
-
- private String name;
-
- private String inherits;
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String[] getFilteringApis() {
- return filteringApis.toArray(new String[filteringApis.size()]);
- }
-
- public void addApi(String api) {
- apis.add(api);
- filteringApis.add(packageToScannerFiler(api));
- }
-
- public Set<String> getApis() {
- return apis;
- }
-
- public boolean containsApi(String api) {
- return apis.contains(api);
- }
-
- public void addExportPackage(Clause exportPackage) {
- this.exportPackage.add(exportPackage);
- }
-
- public Iterator<Clause> getExportPackage() {
- return exportPackage.iterator();
- }
-
- public void doInherit(ApiRegion parent) {
- inherits = parent.getName();
- apis.addAll(parent.apis);
- filteringApis.addAll(parent.filteringApis);
- }
-
- @Override
- public String toString() {
- Formatter formatter = new Formatter();
- formatter.format("Region '%s'", name);
-
- if (inherits != null && !inherits.isEmpty()) {
- formatter.format(" inherits from '%s'", inherits);
- }
-
- formatter.format(":%n");
-
- for (String api : apis) {
- formatter.format(" * %s%n", api);
- }
-
- String toString = formatter.toString();
- formatter.close();
-
- return toString;
- }
-
- }
-
- private static class GlobalApiRegion extends ApiRegion {
-
- @Override
- public boolean containsApi(String api) {
- this.addApi(api);
- return true;
- }
- }
private static String packageToScannerFiler(String api) {
return "**/" + api.replace('.', '/') + "/*";
@@ -1260,11 +1250,6 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
return true;
}
- private static class ExtendedApiRegions extends ApiRegions {
-
- public final List<ApiRegion> regions = new ArrayList<>();
- }
-
private List<String> getPackages(final File file, final String extension) throws MojoExecutionException {
final String postfix = ".".concat(extension);
final Set<String> packages = new HashSet<>();