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 d889619  SLING-10176 : Support creating api jar based on enabled 
toggles
d889619 is described below

commit d889619668c684b1d0d6dda3aa70a91208e592a0
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Mon Mar 1 16:04:41 2021 +0100

    SLING-10176 : Support creating api jar based on enabled toggles
---
 .../sling/feature/maven/mojos/ApisJarMojo.java     | 199 ++---------------
 .../feature/maven/mojos/apis/RegionSupport.java    | 235 +++++++++++++++++++++
 .../maven/mojos/FeatureLauncherMojoTest.java       |   6 +-
 .../maven/mojos/apis/RegionSupportTest.java        | 225 ++++++++++++++++++++
 4 files changed, 485 insertions(+), 180 deletions(-)

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 17bcbe2..53956f1 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
@@ -43,7 +43,6 @@ import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
 import org.apache.maven.archiver.MavenArchiveConfiguration;
 import org.apache.maven.archiver.MavenArchiver;
 import org.apache.maven.execution.MavenSession;
@@ -91,6 +90,7 @@ import 
org.apache.sling.feature.maven.mojos.apis.DirectorySource;
 import org.apache.sling.feature.maven.mojos.apis.FileSource;
 import org.apache.sling.feature.maven.mojos.apis.JavadocExecutor;
 import org.apache.sling.feature.maven.mojos.apis.JavadocLinks;
+import org.apache.sling.feature.maven.mojos.apis.RegionSupport;
 import org.apache.sling.feature.maven.mojos.apis.spi.Processor;
 import org.apache.sling.feature.maven.mojos.apis.spi.ProcessorContext;
 import org.apache.sling.feature.maven.mojos.apis.spi.Source;
@@ -158,6 +158,15 @@ public class ApisJarMojo extends 
AbstractIncludingFeatureMojo {
     private boolean incrementalApis;
 
     /**
+     * If set to true the apis jar will only contain api which is behind
+     * the enabled toggles. All other public api is not included. If set to
+     * false (the default) all public api is included per region.
+     * @since 1.4.26
+     */
+    @Parameter(defaultValue = "false")
+    private boolean toggleApiOnly;
+
+    /**
      * Additional resources for the api jar
      */
     @Parameter
@@ -410,96 +419,14 @@ public class ApisJarMojo extends 
AbstractIncludingFeatureMojo {
     }
 
     /**
-     * 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) {
-            if ("*".equals(i) || i.equals(name)) {
-                included = true;
-                break;
-            }
-        }
-        if (included && this.excludeRegions != null) {
-            for (final String e : this.excludeRegions) {
-                if (name.equals(e)) {
-                    included = false;
-                    break;
-                }
-            }
-        }
-
-        return included;
-    }
-
-    /**
-     * Get the api regions for a feature If the feature does not have an api 
region
-     * an artificial global region is returned.
-     *
-     * @param feature The feature
-     * @return The api regions or {@code null} if the feature is wrongly 
configured
-     *         or all regions are excluded
-     * @throws MojoExecutionException If an error occurs
-     */
-    private ApiRegions getApiRegions(final Feature feature) throws 
MojoExecutionException {
-        ApiRegions regions = new ApiRegions();
-
-        final ApiRegions sourceRegions;
-        try {
-            sourceRegions = ApiRegions.getApiRegions(feature);
-        } catch (final IllegalArgumentException iae) {
-            throw new MojoExecutionException(iae.getMessage(), iae);
-        }
-        if (sourceRegions != null) {
-            // calculate all api-regions first, taking the inheritance in 
account
-            for (final ApiRegion r : sourceRegions.listRegions()) {
-                if (r.getParent() != null && !this.incrementalApis) {
-                    for (final ApiExport exp : r.getParent().listExports()) {
-                        r.add(exp);
-                    }
-                }
-                if (isRegionIncluded(r.getName())) {
-                    getLog().debug("API Region " + r.getName()
-                            + " will not processed due to the configured 
include/exclude list");
-                    regions.add(r);
-                }
-            }
-
-            if (regions.isEmpty()) {
-                getLog().info("Feature file " + feature.getId().toMvnId()
-                        + " has no included api regions, no API JAR will be 
created");
-                regions = null;
-            }
-        } else {
-            // 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;
-    }
-
-    /**
      * Create api jars for a feature
      */
     private void onFeature(final Feature feature) throws 
MojoExecutionException {
         getLog().info(MessageUtils.buffer().a("Creating API JARs for Feature 
").strong(feature.getId().toMvnId())
                 .a(" ...").toString());
 
-        final ApiRegions regions = getApiRegions(feature);
+        final RegionSupport regionSupport = new RegionSupport(this.getLog(), 
this.incrementalApis, this.toggleApiOnly, this.includeRegions, 
this.excludeRegions);
+        final ApiRegions regions = regionSupport.getApiRegions(feature);
         if (regions == null) {
             // wrongly configured api regions - skip execution, info is logged 
already so we
             // can just return
@@ -531,7 +458,7 @@ public class ApisJarMojo extends 
AbstractIncludingFeatureMojo {
 
         // for each bundle included in the feature file and record directories
         for (final Artifact artifact : feature.getBundles()) {
-            onArtifact(regions, ctx, artifact);
+            onArtifact(regions, ctx, regionSupport, artifact);
         }
 
         if (this.generateSourceJar || this.generateJavadocJar) {
@@ -715,22 +642,6 @@ public class ApisJarMojo extends 
AbstractIncludingFeatureMojo {
         return bundleFile;
     }
 
-    private Manifest getManifest(final ArtifactId artifactId, final File 
bundleFile) throws MojoExecutionException {
-        try (JarInputStream jis = new JarInputStream(new 
FileInputStream(bundleFile))) {
-            getLog().debug("Reading Manifest headers from bundle " + 
bundleFile);
-
-            final Manifest manifest = jis.getManifest();
-
-            if (manifest == null) {
-                throw new MojoExecutionException("Artifact + " + 
artifactId.toMvnId() + " does not  have a manifest.");
-            }
-            return manifest;
-        } catch (final IOException e) {
-            throw new MojoExecutionException("An error occurred while reading 
manifest from file " + bundleFile
-                    + " for artifact " + artifactId.toMvnId(), e);
-        }
-    }
-
     private boolean calculateOmitDependenciesFlag(final ApiRegion region, 
final Clause[] exportedPackageClauses,
             final Set<Clause> usedExportedPackagesPerRegion) {
         // check whether all packages are exported in this region
@@ -767,17 +678,20 @@ public class ApisJarMojo extends 
AbstractIncludingFeatureMojo {
      * @param artifact The artifact
      * @throws MojoExecutionException
      */
-    private void onArtifact(final ApiRegions apiRegions, final ApisJarContext 
ctx, Artifact artifact) throws MojoExecutionException {
+    private void onArtifact(final ApiRegions apiRegions, 
+            final ApisJarContext ctx,
+            final RegionSupport regionSupport, 
+            Artifact artifact) throws MojoExecutionException {
         final File bundleFile = getArtifactFile(artifact.getId());
 
-        final Manifest manifest = getManifest(artifact.getId(), bundleFile);
+        final Manifest manifest = regionSupport.getManifest(artifact.getId(), 
bundleFile);
 
         // check if the bundle is exporting packages?
-        final Clause[] exportedPackageClauses = 
this.getExportedPackages(manifest);
+        final Clause[] exportedPackageClauses = 
regionSupport.getExportedPackages(manifest);
         if (exportedPackageClauses.length > 0) {
 
             // calculate the exported packages in the manifest file for all 
regions
-            final Set<String> usedExportedPackages = 
computeUsedExportPackages(apiRegions, ctx, exportedPackageClauses, artifact);
+            final Set<String> usedExportedPackages = 
regionSupport.computeAllUsedExportPackages(apiRegions, 
ctx.getConfig().getEnabledToggles(), exportedPackageClauses, artifact);
 
             if (!usedExportedPackages.isEmpty()) {
                 // check for previous version of artifact due to toggles
@@ -814,8 +728,8 @@ public class ApisJarMojo extends 
AbstractIncludingFeatureMojo {
 
                 // calculate per region packages
                 for (final ApiRegion region : apiRegions.listRegions()) {
-                    final Set<Clause> usedExportedPackagesPerRegion = 
computeUsedExportPackages(region,
-                            exportedPackageClauses, artifact);
+                    final Set<Clause> usedExportedPackagesPerRegion = 
regionSupport.computeUsedExportPackagesPerRegion(region,
+                            exportedPackageClauses, usedExportedPackages);
 
                     // check whether packages are included in api jars - or 
added as a dependency
                     boolean useAsDependency = this.useApiDependencies
@@ -1429,75 +1343,6 @@ public class ApisJarMojo extends 
AbstractIncludingFeatureMojo {
         }
     }
 
-    private Clause[] getExportedPackages(final Manifest manifest) {
-        final String exportPackageHeader = 
manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE);
-        final Clause[] exportPackages = 
Parser.parseHeader(exportPackageHeader);
-
-        return exportPackages;
-    }
-
-    /**
-     * Compute exports based on a single region
-     *
-     * @return List of packages exported by this bundle and used in the region
-     */
-    private Set<Clause> computeUsedExportPackages(final ApiRegion apiRegion, 
final Clause[] exportedPackages,
-            final Artifact bundle) throws MojoExecutionException {
-
-        final Set<Clause> result = new HashSet<>();
-
-        final Set<String> ignoredPackages = 
ApisUtil.getIgnoredPackages(bundle);
-
-        // filter for each region
-        for (final Clause exportedPackage : exportedPackages) {
-            final String packageName = exportedPackage.getName();
-
-            if (!ignoredPackages.contains(packageName)) {
-                final ApiExport exp = apiRegion.getExportByName(packageName);
-                if (exp != null) {
-                    result.add(exportedPackage);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Compute exports based on all regions
-     *
-     * @return Set of packages exported by this bundle and used in any region
-     */
-    private Set<String> computeUsedExportPackages(final ApiRegions apiRegions, 
final ApisJarContext ctx, final Clause[] exportedPackages,
-            final Artifact bundle) throws MojoExecutionException {
-        final Set<String> result = new HashSet<>();
-
-        // filter for each region
-        for (final Clause exportedPackage : exportedPackages) {
-            final String packageName = exportedPackage.getName();
-
-            for (ApiRegion apiRegion : apiRegions.listRegions()) {
-                final ApiExport exp = apiRegion.getExportByName(packageName);
-                if (exp != null) {
-                    boolean include = true;
-                    // if the package is behind a toggle, don't include it
-                    if (exp.getToggle() != null && 
!ctx.getConfig().getEnabledToggles().contains(exp.getToggle())
-                            && exp.getPrevious() == null) {
-                        include = false;
-                    }
-                    if (include) {
-                        result.add(exportedPackage.getName());
-                    }
-                }
-            }
-        }
-
-        // check ignored packages configuration
-        result.removeAll(ApisUtil.getIgnoredPackages(bundle));
-
-        return result;
-    }
-
     private String getApiExportClause(final ApiRegion region, final 
Collection<ArtifactInfo> infos) {
         final StringBuilder sb = new StringBuilder();
         boolean first = true;
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
new file mode 100644
index 0000000..f67c94a
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/apis/RegionSupport.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+package org.apache.sling.feature.maven.mojos.apis;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+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.osgi.framework.Constants;
+
+public class RegionSupport {
+    
+    private final Log log;
+
+    private final boolean incrementalApis;
+
+    private final Set<String> includeRegions;
+
+    private final Set<String> excludeRegions;
+
+    private final boolean toggleApiOnly;
+
+    public RegionSupport(final Log logger,
+             final boolean incrementalApis,
+             final boolean toggleApiOnly,
+             final Set<String> includeRegions,
+             final Set<String> excludeRegions) {
+        this.log = logger;
+        this.incrementalApis = incrementalApis;
+        this.includeRegions = includeRegions;
+        this.excludeRegions = excludeRegions;
+        this.toggleApiOnly = toggleApiOnly;
+    }
+
+    /**
+     * Get the api regions for a feature If the feature does not have an api 
region
+     * an artificial global region is returned.
+     *
+     * @param feature The feature
+     * @return The api regions or {@code null} if the feature is wrongly 
configured
+     *         or all regions are excluded
+     * @throws MojoExecutionException If an error occurs
+     */
+    public ApiRegions getApiRegions(final Feature feature) throws 
MojoExecutionException {
+        ApiRegions regions = new ApiRegions();
+
+        final ApiRegions sourceRegions;
+        try {
+            sourceRegions = ApiRegions.getApiRegions(feature);
+        } catch (final IllegalArgumentException iae) {
+            throw new MojoExecutionException(iae.getMessage(), iae);
+        }
+        if (sourceRegions != null) {
+            // calculate all api-regions first, taking the inheritance in 
account
+            for (final ApiRegion r : sourceRegions.listRegions()) {
+                if (r.getParent() != null && !this.incrementalApis) {
+                    for (final ApiExport exp : r.getParent().listExports()) {
+                        r.add(exp);
+                    }
+                }
+                if (isRegionIncluded(r.getName())) {
+                    log.debug("API Region " + r.getName()
+                            + " will not processed due to the configured 
include/exclude list");
+                    regions.add(r);
+                }
+            }
+
+            if (regions.isEmpty()) {
+                log.info("Feature file " + feature.getId().toMvnId()
+                        + " has no included api regions, no API JAR will be 
created");
+                regions = null;
+            }
+        } else {
+            // 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;
+    }
+
+    /**
+     * 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) {
+            if ("*".equals(i) || i.equals(name)) {
+                included = true;
+                break;
+            }
+        }
+        if (included && this.excludeRegions != null) {
+            for (final String e : this.excludeRegions) {
+                if (name.equals(e)) {
+                    included = false;
+                    break;
+                }
+            }
+        }
+
+        return included;
+    }
+
+    /**
+     * Compute exports based on all regions
+     *
+     * @return Set of packages exported by this bundle and used in any region
+     */
+    public Set<String> computeAllUsedExportPackages(final ApiRegions 
apiRegions, 
+            final Set<String> enabledToggles,
+            final Clause[] exportedPackages,
+            final Artifact bundle) throws MojoExecutionException {
+        final Set<String> result = new HashSet<>();
+
+        // filter for each region
+        for (final Clause exportedPackage : exportedPackages) {
+            final String packageName = exportedPackage.getName();
+
+            for (ApiRegion apiRegion : apiRegions.listRegions()) {
+                final ApiExport exp = apiRegion.getExportByName(packageName);
+                if (exp != null) {
+                    boolean include = !toggleApiOnly;
+                    if ( toggleApiOnly ) {
+                        include = exp.getToggle() != null && 
enabledToggles.contains(exp.getToggle());
+                    } else {
+                        // if the package is behind a toggle,  only include if 
toggle is enabled or if previous artifact is set
+                        if (exp.getToggle() != null && 
!enabledToggles.contains(exp.getToggle()) && exp.getPrevious() == null) {
+                            include = false;
+                        }
+                    }
+                    if (include) {
+                        result.add(exportedPackage.getName());
+                    }
+                }
+            }
+        }
+
+        // check ignored packages configuration
+        result.removeAll(ApisUtil.getIgnoredPackages(bundle));
+
+        return result;
+    }
+
+   /**
+     * Compute exports based on a single region
+     *
+     * @return List of packages exported by this bundle and used in the region
+     */
+    public Set<Clause> computeUsedExportPackagesPerRegion(final ApiRegion 
apiRegion, 
+            final Clause[] exportedPackages,
+            final Set<String> allPackages) throws MojoExecutionException {
+
+        final Set<Clause> result = new HashSet<>();
+
+        // filter for each region
+        for (final Clause exportedPackage : exportedPackages) {
+            final String packageName = exportedPackage.getName();
+
+            if (allPackages.contains(packageName)) {
+                final ApiExport exp = apiRegion.getExportByName(packageName);
+                if (exp != null) {
+                    result.add(exportedPackage);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public Clause[] getExportedPackages(final Manifest manifest) {
+        final String exportPackageHeader = 
manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE);
+        final Clause[] exportPackages = 
Parser.parseHeader(exportPackageHeader);
+
+        return exportPackages;
+    }
+
+    public Manifest getManifest(final ArtifactId artifactId, final File 
bundleFile) throws MojoExecutionException {
+        try (JarInputStream jis = new JarInputStream(new 
FileInputStream(bundleFile))) {
+            log.debug("Reading Manifest headers from bundle " + bundleFile);
+
+            final Manifest manifest = jis.getManifest();
+
+            if (manifest == null) {
+                throw new MojoExecutionException("Artifact + " + 
artifactId.toMvnId() + " does not  have a manifest.");
+            }
+            return manifest;
+        } catch (final IOException e) {
+            throw new MojoExecutionException("An error occurred while reading 
manifest from file " + bundleFile
+                    + " for artifact " + artifactId.toMvnId(), e);
+        }
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/feature/maven/mojos/FeatureLauncherMojoTest.java
 
b/src/test/java/org/apache/sling/feature/maven/mojos/FeatureLauncherMojoTest.java
index ea54910..4b46cc2 100644
--- 
a/src/test/java/org/apache/sling/feature/maven/mojos/FeatureLauncherMojoTest.java
+++ 
b/src/test/java/org/apache/sling/feature/maven/mojos/FeatureLauncherMojoTest.java
@@ -34,6 +34,7 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
@@ -55,7 +56,6 @@ import org.mockito.internal.util.reflection.Whitebox;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
-import edu.emory.mathcs.backport.java.util.Arrays;
 
 public class FeatureLauncherMojoTest {
 
@@ -108,7 +108,7 @@ public class FeatureLauncherMojoTest {
         doNothing().when(mojo).checkPreconditions();
         final List<String> arguments = new ArrayList<>();
         doAnswer(
-            new Answer() {
+            new Answer<Object>() {
                 @Override
                 public Object answer(InvocationOnMock invocation) throws 
Throwable {
                     String[] args = (String[]) invocation.getArguments()[0];
@@ -167,7 +167,7 @@ public class FeatureLauncherMojoTest {
         doNothing().when(mojo).checkPreconditions();
         final List<String> arguments = new ArrayList<>();
         doAnswer(
-            new Answer() {
+            new Answer<Object>() {
                 @Override
                 public Object answer(InvocationOnMock invocation) throws 
Throwable {
                     String[] args = (String[]) invocation.getArguments()[0];
diff --git 
a/src/test/java/org/apache/sling/feature/maven/mojos/apis/RegionSupportTest.java
 
b/src/test/java/org/apache/sling/feature/maven/mojos/apis/RegionSupportTest.java
new file mode 100644
index 0000000..f945791
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/feature/maven/mojos/apis/RegionSupportTest.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.feature.maven.mojos.apis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+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.junit.Test;
+import org.mockito.Mockito;
+
+public class RegionSupportTest {
+
+    @Test public void testNoRegionInfo() throws MojoExecutionException {
+        final RegionSupport support = new 
RegionSupport(Mockito.mock(Log.class), true, false, Collections.singleton("*"), 
Collections.emptySet());
+
+        final Feature f = new Feature(ArtifactId.parse("g:a:1"));
+
+        final ApiRegions regions = support.getApiRegions(f);
+        assertNotNull(regions);
+        assertEquals(1, regions.listRegions().size());
+        assertEquals("global", regions.listRegions().get(0).getName());
+    }
+
+    @Test public void testApiExportAllPackages() throws MojoExecutionException 
{
+        final ApiRegions regions = new ApiRegions();
+        final ApiRegion region = new ApiRegion("global");
+        regions.add(region);
+        final ApiExport e1 = new ApiExport("p1");
+        region.add(e1);
+        final ApiExport e2 = new ApiExport("p2");
+        region.add(e2);
+        final ApiExport e3 = new ApiExport("p3");
+        region.add(e3);
+        final Artifact bundle = new Artifact(ArtifactId.parse("g:b:1"));
+        final RegionSupport support = new 
RegionSupport(Mockito.mock(Log.class), true, false, Collections.singleton("*"), 
Collections.emptySet());
+
+        // three packages are exported
+        final Clause[] exportedPackages = new Clause[3];
+        exportedPackages[0] = new Clause("p1", null, null);
+        exportedPackages[1] = new Clause("p2", null, null);
+        exportedPackages[2] = new Clause("p3", null, null);
+
+        final Set<String> used = support.computeAllUsedExportPackages(regions, 
Collections.emptySet(), exportedPackages, bundle);
+        assertEquals(3, used.size());
+        assertTrue(used.contains("p1"));
+        assertTrue(used.contains("p2"));
+        assertTrue(used.contains("p3"));
+
+        final Set<Clause> usedPerRegion = 
support.computeUsedExportPackagesPerRegion(region, exportedPackages, used);
+        assertEquals(3, usedPerRegion.size());
+        assertTrue(usedPerRegion.contains(exportedPackages[0]));
+        assertTrue(usedPerRegion.contains(exportedPackages[1]));
+        assertTrue(usedPerRegion.contains(exportedPackages[2]));
+    }
+
+    @Test public void testApiExportSubsetOfPackages() throws 
MojoExecutionException {
+        final ApiRegions regions = new ApiRegions();
+        final ApiRegion region = new ApiRegion("global");
+        regions.add(region);
+        final ApiExport e1 = new ApiExport("p1");
+        region.add(e1);
+        final ApiExport e2 = new ApiExport("p2");
+        region.add(e2);
+        final ApiExport e3 = new ApiExport("p4");
+        region.add(e3);
+        final Artifact bundle = new Artifact(ArtifactId.parse("g:b:1"));
+        final RegionSupport support = new 
RegionSupport(Mockito.mock(Log.class), true, false, Collections.singleton("*"), 
Collections.emptySet());
+
+        // three packages are exported
+        final Clause[] exportedPackages = new Clause[3];
+        exportedPackages[0] = new Clause("p1", null, null);
+        exportedPackages[1] = new Clause("p2", null, null);
+        exportedPackages[2] = new Clause("p3", null, null);
+
+        final Set<String> used = support.computeAllUsedExportPackages(regions, 
Collections.emptySet(), exportedPackages, bundle);
+        assertEquals(2, used.size());
+        assertTrue(used.contains("p1"));
+        assertTrue(used.contains("p2"));
+
+        final Set<Clause> usedPerRegion = 
support.computeUsedExportPackagesPerRegion(region, exportedPackages, used);
+        assertEquals(2, usedPerRegion.size());
+        assertTrue(usedPerRegion.contains(exportedPackages[0]));
+        assertTrue(usedPerRegion.contains(exportedPackages[1]));
+    }
+
+    @Test public void testApiExportWithToggles() throws MojoExecutionException 
{
+        final ApiRegions regions = new ApiRegions();
+        final ApiRegion region = new ApiRegion("global");
+        regions.add(region);
+        final ApiExport e1 = new ApiExport("p1");
+        region.add(e1);
+        final ApiExport e2 = new ApiExport("p2");
+        e2.setToggle("p2-feature");
+        region.add(e2);
+        final ApiExport e3 = new ApiExport("p3");
+        region.add(e3);
+        final Artifact bundle = new Artifact(ArtifactId.parse("g:b:1"));
+        final RegionSupport support = new 
RegionSupport(Mockito.mock(Log.class), true, false, Collections.singleton("*"), 
Collections.emptySet());
+
+        // three packages are exported
+        final Clause[] exportedPackages = new Clause[3];
+        exportedPackages[0] = new Clause("p1", null, null);
+        exportedPackages[1] = new Clause("p2", null, null);
+        exportedPackages[2] = new Clause("p3", null, null);
+
+        // no toggle set, p2 is not included
+        Set<String> used = support.computeAllUsedExportPackages(regions, 
Collections.emptySet(), exportedPackages, bundle);
+        assertEquals(2, used.size());
+        assertTrue(used.contains("p1"));
+        assertTrue(used.contains("p3"));
+
+        Set<Clause> usedPerRegion = 
support.computeUsedExportPackagesPerRegion(region, exportedPackages, used);
+        assertEquals(2, usedPerRegion.size());
+        assertTrue(usedPerRegion.contains(exportedPackages[0]));
+        assertTrue(usedPerRegion.contains(exportedPackages[2]));
+
+        // set toggle - p2 is included
+        used = support.computeAllUsedExportPackages(regions, 
Collections.singleton("p2-feature"), exportedPackages, bundle);
+        assertEquals(3, used.size());
+        assertTrue(used.contains("p1"));
+        assertTrue(used.contains("p2"));
+        assertTrue(used.contains("p3"));
+
+        usedPerRegion = support.computeUsedExportPackagesPerRegion(region, 
exportedPackages, used);
+        assertEquals(3, usedPerRegion.size());
+        assertTrue(usedPerRegion.contains(exportedPackages[0]));
+        assertTrue(usedPerRegion.contains(exportedPackages[1]));
+        assertTrue(usedPerRegion.contains(exportedPackages[2]));
+
+        // no toggle set, but toggle uses previous version
+        e2.setPrevious(ArtifactId.parse("g:b:0.1"));
+        used = support.computeAllUsedExportPackages(regions, 
Collections.emptySet(), exportedPackages, bundle);
+        assertEquals(3, used.size());
+        assertTrue(used.contains("p1"));
+        assertTrue(used.contains("p2"));
+        assertTrue(used.contains("p3"));
+
+        usedPerRegion = support.computeUsedExportPackagesPerRegion(region, 
exportedPackages, used);
+        assertEquals(3, usedPerRegion.size());
+        assertTrue(usedPerRegion.contains(exportedPackages[0]));
+        assertTrue(usedPerRegion.contains(exportedPackages[1]));
+        assertTrue(usedPerRegion.contains(exportedPackages[2]));
+    }
+
+    @Test public void testApiExportWithTogglesOnly() throws 
MojoExecutionException {
+        final ApiRegions regions = new ApiRegions();
+        final ApiRegion region = new ApiRegion("global");
+        regions.add(region);
+        final ApiExport e1 = new ApiExport("p1");
+        region.add(e1);
+        final ApiExport e2 = new ApiExport("p2");
+        e2.setToggle("p2-feature");
+        region.add(e2);
+        final ApiExport e3 = new ApiExport("p3");
+        region.add(e3);
+        final Artifact bundle = new Artifact(ArtifactId.parse("g:b:1"));
+        final RegionSupport support = new 
RegionSupport(Mockito.mock(Log.class), true, true, Collections.singleton("*"), 
Collections.emptySet());
+
+        // three packages are exported
+        final Clause[] exportedPackages = new Clause[3];
+        exportedPackages[0] = new Clause("p1", null, null);
+        exportedPackages[1] = new Clause("p2", null, null);
+        exportedPackages[2] = new Clause("p3", null, null);
+
+        // no toggle set, toggle is required - empty result
+        Set<String> used = support.computeAllUsedExportPackages(regions, 
Collections.emptySet(), exportedPackages, bundle);
+        assertTrue(used.isEmpty());
+
+        Set<Clause> usedPerRegion = 
support.computeUsedExportPackagesPerRegion(region, exportedPackages, used);
+        assertTrue(usedPerRegion.isEmpty());
+
+        // set toggle - p2-feature is set -> p2 is included
+        used = support.computeAllUsedExportPackages(regions, 
Collections.singleton("p2-feature"), exportedPackages, bundle);
+        assertEquals(1, used.size());
+        assertTrue(used.contains("p2"));
+
+        usedPerRegion = support.computeUsedExportPackagesPerRegion(region, 
exportedPackages, used);
+        assertEquals(1, usedPerRegion.size());
+        assertTrue(usedPerRegion.contains(exportedPackages[1]));
+
+        // no toggle set, but toggle uses previous version -> empty result
+        e2.setPrevious(ArtifactId.parse("g:b:0.1"));
+        used = support.computeAllUsedExportPackages(regions, 
Collections.emptySet(), exportedPackages, bundle);
+        assertTrue(used.isEmpty());
+
+        usedPerRegion = support.computeUsedExportPackagesPerRegion(region, 
exportedPackages, used);
+        assertTrue(usedPerRegion.isEmpty());
+
+        // set toggle - p2-feature is set -> p2 is included
+        used = support.computeAllUsedExportPackages(regions, 
Collections.singleton("p2-feature"), exportedPackages, bundle);
+        assertEquals(1, used.size());
+        assertTrue(used.contains("p2"));
+
+        usedPerRegion = support.computeUsedExportPackagesPerRegion(region, 
exportedPackages, used);
+        assertEquals(1, usedPerRegion.size());
+        assertTrue(usedPerRegion.contains(exportedPackages[1]));
+    }
+}

Reply via email to