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

davidb 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 caaf453  SLING-7860 Enhance slingfeature-maven-plugin to aggregate 
multiple features into a single feature
caaf453 is described below

commit caaf453722578fd08997a5fbaad9212b0d32e279
Author: David Bosschaert <[email protected]>
AuthorDate: Tue Aug 28 15:07:32 2018 +0100

    SLING-7860 Enhance slingfeature-maven-plugin to aggregate multiple features 
into a single feature
    
    Initial code for supporting this.
---
 .../feature/maven/mojos/AggregateFeatures.java     | 207 +++++++++++++++++++++
 .../feature/maven/mojos/GenerateResources.java     |  33 +---
 .../{GenerateResources.java => Substitution.java}  |  44 +----
 .../META-INF/m2e/lifecycle-mapping-metadata.xml    |   1 +
 .../feature/maven/mojos/GenerateResourceTest.java  |   4 +-
 5 files changed, 217 insertions(+), 72 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/feature/maven/mojos/AggregateFeatures.java 
b/src/main/java/org/apache/sling/feature/maven/mojos/AggregateFeatures.java
new file mode 100644
index 0000000..07ed674
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AggregateFeatures.java
@@ -0,0 +1,207 @@
+/*
+ * 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;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.Include;
+import org.apache.sling.feature.builder.BuilderContext;
+import org.apache.sling.feature.builder.FeatureBuilder;
+import org.apache.sling.feature.builder.FeatureProvider;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.io.json.FeatureJSONWriter;
+import org.apache.sling.feature.maven.FeatureConstants;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.file.Files;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Aggregate multiple features into a single one.
+ */
+@Mojo(name = "aggregate-features",
+    defaultPhase = LifecyclePhase.PACKAGE,
+    requiresDependencyResolution = ResolutionScope.TEST,
+    threadSafe = true
+)
+public class AggregateFeatures extends AbstractFeatureMojo {
+    @Parameter(required=false)
+    private String classifier;
+
+    @Parameter
+    private List<FeatureConfig> features;
+
+    @Parameter(property = "project.remoteArtifactRepositories", readonly = 
true, required = true)
+    protected List<ArtifactRepository> remoteRepositories;
+
+    @Parameter(property = "localRepository", readonly = true, required = true)
+    protected ArtifactRepository localRepository;
+
+    @Component
+    private RepositorySystem repoSystem;
+
+    @Component
+    private ArtifactResolver artifactResolver;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        Map<ArtifactId, Feature> featureMap = readFeatures(features);
+
+        ArtifactId newFeatureID = new ArtifactId(project.getGroupId(), 
project.getArtifactId(),
+                project.getVersion(), classifier, 
FeatureConstants.PACKAGING_FEATURE);
+        Feature newFeature = new Feature(newFeatureID);
+        newFeature.getIncludes().addAll(
+                featureMap.keySet().stream()
+                .map(Include::new)
+                .collect(Collectors.toList()));
+
+        Feature result = FeatureBuilder.assemble(newFeature, new 
BuilderContext(new FeatureProvider() {
+            @Override
+            public Feature provide(ArtifactId id) {
+                return featureMap.get(id);
+            }
+        }));
+
+        File aggregatedFeaturesDir = new 
File(project.getBuild().getDirectory(), 
FeatureConstants.FEATURE_PROCESSED_LOCATION);
+        aggregatedFeaturesDir.mkdirs();
+
+        try (FileWriter fileWriter = new FileWriter(new 
File(aggregatedFeaturesDir, classifier + ".json"))) {
+            FeatureJSONWriter.write(fileWriter, result);
+        } catch (IOException e) {
+            throw new MojoExecutionException("Problem writing assembled 
feature", e);
+        }
+    }
+
+    private Map<ArtifactId, Feature> readFeatures(Collection<FeatureConfig> 
featureConfigs) throws MojoExecutionException {
+        Map<ArtifactId, Feature> featureMap = new HashMap<>();
+
+        try {
+            for (FeatureConfig fc : featureConfigs) {
+                if (fc.location != null) {
+                    readFeaturesFromDirectory(fc, featureMap);
+                } else if (fc.artifactId != null) {
+                    readFeaturesFromArtifact(fc, featureMap);
+                }
+            }
+        } catch (IOException e) {
+            throw new MojoExecutionException("Problem reading feature", e);
+        }
+
+        return featureMap;
+    }
+
+    private void readFeaturesFromArtifact(FeatureConfig fc, Map<ArtifactId, 
Feature> featureMap) throws IOException {
+        Artifact art = repoSystem.createArtifactWithClassifier(
+                fc.groupId, fc.artifactId, fc.version, fc.type, fc.classifier);
+
+        ArtifactResolutionRequest resReq = new ArtifactResolutionRequest()
+                .setArtifact(art)
+                .setLocalRepository(localRepository)
+                .setRemoteRepositories(remoteRepositories);
+        artifactResolver.resolve(resReq);
+
+        File artFile = art.getFile();
+        readFeatureFromFile(artFile, featureMap);
+    }
+
+    private void readFeaturesFromDirectory(FeatureConfig fc, Map<ArtifactId, 
Feature> featureMap) throws IOException {
+        for (File f : new File(fc.location).listFiles()) {
+            readFeatureFromFile(f, featureMap);
+        }
+    }
+
+    private void readFeatureFromFile(File f, Map<ArtifactId, Feature> 
featureMap) throws IOException {
+        String content = new String(Files.readAllBytes(f.toPath()));
+        content = Substitution.replaceMavenVars(project, content);
+        Feature feat = FeatureJSONReader.read(new StringReader(content), null, 
FeatureJSONReader.SubstituteVariables.NONE);
+        featureMap.put(feat.getId(), feat);
+    }
+
+    public static class FeatureConfig {
+        // If the configuration is a directory
+        String location;
+        Set<String> includes = new HashSet<>();
+        Set<String> excludes = new HashSet<>();
+
+        // If the configuration is an artifact
+        String groupId;
+        String artifactId;
+        String version;
+        String type;
+        String classifier;
+
+        public void setLocation(String loc) {
+            location = loc;
+        }
+
+        public void setIncludes(String i) {
+            includes.add(i);
+        }
+
+        public void setExcludes(String e) {
+            excludes.add(e);
+        }
+
+        public void setGroupId(String gid) {
+            groupId = gid;
+        }
+
+        public void setArtifactId(String aid) {
+            artifactId = aid;
+        }
+
+        public void setVersion(String ver) {
+            version = ver;
+        }
+
+        public void setType(String t) {
+            type = t;
+        }
+
+        public void setClassifier(String clf) {
+            classifier = clf;
+        }
+
+        @Override
+        public String toString() {
+            return "FeatureConfig [location=" + location + ", includes=" + 
includes + ", excludes=" + excludes + ", groupId="
+                    + groupId + ", artifactId=" + artifactId + ", version=" + 
version + ", type=" + type + ", classifier="
+                    + classifier + "]";
+        }
+    }
+}
diff --git 
a/src/main/java/org/apache/sling/feature/maven/mojos/GenerateResources.java 
b/src/main/java/org/apache/sling/feature/maven/mojos/GenerateResources.java
index ca78cbd..0fe467b 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/GenerateResources.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/GenerateResources.java
@@ -22,12 +22,10 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.project.MavenProject;
+import org.apache.sling.feature.maven.FeatureConstants;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
-import java.nio.file.Files;
 
 @Mojo(
         name = "generate-resources",
@@ -44,7 +42,7 @@ public class GenerateResources extends AbstractFeatureMojo {
         if (files == null)
             return;
 
-        File processedFeaturesDir = new 
File(project.getBuild().getDirectory(), "features/processed");
+        File processedFeaturesDir = new 
File(project.getBuild().getDirectory(), 
FeatureConstants.FEATURE_PROCESSED_LOCATION);
         processedFeaturesDir.mkdirs();
 
         for (File f : files) {
@@ -53,35 +51,10 @@ public class GenerateResources extends AbstractFeatureMojo {
             }
 
             try {
-                substituteVars(project, f, processedFeaturesDir);
+                Substitution.substituteMavenVars(project, f, 
processedFeaturesDir);
             } catch (IOException e) {
                 throw new MojoExecutionException("Problem processing feature 
file " + f.getAbsolutePath(), e);
             }
         }
     }
-
-    private static File substituteVars(MavenProject project, File f, File 
processedFeaturesDir) throws IOException {
-        File file = new File(processedFeaturesDir, f.getName());
-
-        if (file.exists() && file.lastModified() > f.lastModified()) {
-            // The file already exists, so we don't need to write it again
-            return file;
-        }
-
-        try (FileWriter fw = new FileWriter(file)) {
-            for (String s : Files.readAllLines(f.toPath())) {
-                fw.write(replaceVars(project, s));
-                fw.write(System.getProperty("line.separator"));
-            }
-        }
-        return file;
-    }
-
-    static String replaceVars(MavenProject project, String s) {
-        // There must be a better way than enumerating all these?
-        s = s.replaceAll("\\Q${project.groupId}\\E", project.getGroupId());
-        s = s.replaceAll("\\Q${project.artifactId}\\E", 
project.getArtifactId());
-        s = s.replaceAll("\\Q${project.version}\\E", project.getVersion());
-        return s;
-    }
 }
diff --git 
a/src/main/java/org/apache/sling/feature/maven/mojos/GenerateResources.java 
b/src/main/java/org/apache/sling/feature/maven/mojos/Substitution.java
similarity index 52%
copy from 
src/main/java/org/apache/sling/feature/maven/mojos/GenerateResources.java
copy to src/main/java/org/apache/sling/feature/maven/mojos/Substitution.java
index ca78cbd..6d5d8f2 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/GenerateResources.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/Substitution.java
@@ -16,12 +16,6 @@
  */
 package org.apache.sling.feature.maven.mojos;
 
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.maven.project.MavenProject;
 
 import java.io.File;
@@ -29,38 +23,8 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.nio.file.Files;
 
-@Mojo(
-        name = "generate-resources",
-        defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
-        requiresDependencyResolution = ResolutionScope.TEST,
-        threadSafe = true)
-public class GenerateResources extends AbstractFeatureMojo {
-    @Parameter(defaultValue="${basedir}/src/main/features")
-    private File featuresDirectory;
-
-    @Override
-    public void execute() throws MojoExecutionException, MojoFailureException {
-        File[] files = featuresDirectory.listFiles();
-        if (files == null)
-            return;
-
-        File processedFeaturesDir = new 
File(project.getBuild().getDirectory(), "features/processed");
-        processedFeaturesDir.mkdirs();
-
-        for (File f : files) {
-            if (!f.getName().endsWith(".json")) {
-                continue;
-            }
-
-            try {
-                substituteVars(project, f, processedFeaturesDir);
-            } catch (IOException e) {
-                throw new MojoExecutionException("Problem processing feature 
file " + f.getAbsolutePath(), e);
-            }
-        }
-    }
-
-    private static File substituteVars(MavenProject project, File f, File 
processedFeaturesDir) throws IOException {
+class Substitution {
+    static File substituteMavenVars(MavenProject project, File f, File 
processedFeaturesDir) throws IOException {
         File file = new File(processedFeaturesDir, f.getName());
 
         if (file.exists() && file.lastModified() > f.lastModified()) {
@@ -70,14 +34,14 @@ public class GenerateResources extends AbstractFeatureMojo {
 
         try (FileWriter fw = new FileWriter(file)) {
             for (String s : Files.readAllLines(f.toPath())) {
-                fw.write(replaceVars(project, s));
+                fw.write(replaceMavenVars(project, s));
                 fw.write(System.getProperty("line.separator"));
             }
         }
         return file;
     }
 
-    static String replaceVars(MavenProject project, String s) {
+    static String replaceMavenVars(MavenProject project, String s) {
         // There must be a better way than enumerating all these?
         s = s.replaceAll("\\Q${project.groupId}\\E", project.getGroupId());
         s = s.replaceAll("\\Q${project.artifactId}\\E", 
project.getArtifactId());
diff --git a/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml 
b/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
index f316c03..d293092 100644
--- a/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
+++ b/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
@@ -23,6 +23,7 @@
                 <goals>
                     <goal>process-resources</goal>
                     <goal>attach-feature</goal>
+                    <goal>aggregate-features</goal>
                 </goals>
             </pluginExecutionFilter>
             <action>
diff --git 
a/src/test/java/org/apache/sling/feature/maven/mojos/GenerateResourceTest.java 
b/src/test/java/org/apache/sling/feature/maven/mojos/GenerateResourceTest.java
index 0bc7503..56d44ee 100644
--- 
a/src/test/java/org/apache/sling/feature/maven/mojos/GenerateResourceTest.java
+++ 
b/src/test/java/org/apache/sling/feature/maven/mojos/GenerateResourceTest.java
@@ -83,9 +83,9 @@ public class GenerateResourceTest {
         Mockito.when(mp.getArtifactId()).thenReturn("a.b.c");
         Mockito.when(mp.getVersion()).thenReturn("1.2.3-SNAPSHOT");
 
-        assertEquals("xxxabcyyy", GenerateResources.replaceVars(mp,
+        assertEquals("xxxabcyyy", Substitution.replaceMavenVars(mp,
                 "xxx${project.groupId}yyy"));
-        assertEquals("xxxabcyyya.b.c1.2.3-SNAPSHOT", 
GenerateResources.replaceVars(mp,
+        assertEquals("xxxabcyyya.b.c1.2.3-SNAPSHOT", 
Substitution.replaceMavenVars(mp,
                 
"xxx${project.groupId}yyy${project.artifactId}${project.version}"));
     }
 

Reply via email to