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-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new a7af344  SLING-7779 API Region support for the Sling Feature Model
a7af344 is described below

commit a7af344de677f0a764ea8d43dac7fd1af3161d1d
Author: David Bosschaert <[email protected]>
AuthorDate: Wed Oct 31 12:34:45 2018 +0000

    SLING-7779 API Region support for the Sling Feature Model
    
    Initial commit for the apiregions extension, which transforms region in
    formation in feature models into runtime-accessed resources.
---
 featuremodel/feature-extension-apiregions/pom.xml  |  61 ++++++++++
 .../whitelisting/extensions/APIRegionHandler.java  |  75 +++++++++++++
 .../whitelisting/extensions/AbstractHandler.java   |  58 ++++++++++
 .../extensions/BundleArtifactFeatureHandler.java   | 123 +++++++++++++++++++++
 .../extensions/BundleMappingHandler.java           |  63 +++++++++++
 .../org.apache.sling.feature.builder.MergeHandler  |   1 +
 ...apache.sling.feature.builder.PostProcessHandler |   2 +
 7 files changed, 383 insertions(+)

diff --git a/featuremodel/feature-extension-apiregions/pom.xml 
b/featuremodel/feature-extension-apiregions/pom.xml
new file mode 100644
index 0000000..0fb4d4b
--- /dev/null
+++ b/featuremodel/feature-extension-apiregions/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?><!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>34</version>
+        <relativePath />
+    </parent>
+
+    <artifactId>org.apache.sling.feature.extension.apiregions</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>Sling Featuremodel - API Regions Exension</name>
+
+    <properties>
+        <jdk.version>8</jdk.version>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        
<exclude>src/main/resources/META-INF/services/**</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-json_1.0_spec</artifactId>
+            <version>1.0-alpha-1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature</artifactId>
+            <version>0.1.3-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git 
a/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/APIRegionHandler.java
 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/APIRegionHandler.java
new file mode 100644
index 0000000..1756412
--- /dev/null
+++ 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/APIRegionHandler.java
@@ -0,0 +1,75 @@
+/*
+ * 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.whitelisting.extensions;
+
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.builder.HandlerContext;
+import org.apache.sling.feature.builder.MergeHandler;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonValue;
+import javax.json.stream.JsonGenerator;
+
+public class APIRegionHandler implements MergeHandler {
+
+    @Override
+    public boolean canMerge(Extension extension) {
+        return "api-regions".equals(extension.getName());
+    }
+
+    @Override
+    public void merge(HandlerContext context, Feature target, Feature source, 
Extension targetEx, Extension sourceEx) {
+        if (!targetEx.getName().equals("api-regions") || 
!sourceEx.getName().equals("api-regions"))
+            return;
+
+        JsonReader srcJR = Json.createReader(new 
StringReader(sourceEx.getJSON()));
+        JsonArray srcJA = srcJR.readArray();
+
+        JsonReader tgtJR = Json.createReader(new 
StringReader(targetEx.getJSON()));
+        JsonArray tgtJA = tgtJR.readArray();
+
+        StringWriter sw = new StringWriter();
+        JsonGenerator gen = Json.createGenerator(sw);
+        gen.writeStartArray();
+        for (JsonValue jv : tgtJA) {
+            gen.write(jv);
+        }
+
+        for (int i=0; i < srcJA.size(); i++) {
+            gen.writeStartObject();
+            JsonObject jo = srcJA.getJsonObject(i);
+            for (Map.Entry<String, JsonValue> entry : jo.entrySet()) {
+                gen.write(entry.getKey(), entry.getValue());
+            }
+            gen.write("org-feature", source.getId().toMvnId());
+            gen.writeEnd();
+        }
+
+        gen.writeEnd();
+        gen.close();
+
+        targetEx.setJSON(sw.toString());
+    }
+}
diff --git 
a/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/AbstractHandler.java
 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/AbstractHandler.java
new file mode 100644
index 0000000..ddc2d5e
--- /dev/null
+++ 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/AbstractHandler.java
@@ -0,0 +1,58 @@
+/*
+ * 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.whitelisting.extensions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Date;
+import java.util.Properties;
+
+class AbstractHandler {
+    private static final String FILE_PREFIX = "whitelisting.";
+
+    protected File getDataFile(String name) throws IOException {
+        Path p = Files.createTempFile(FILE_PREFIX, name);
+        File f = p.toFile();
+        f.deleteOnExit();
+
+        System.setProperty(FILE_PREFIX + name, f.getCanonicalPath());
+        return f;
+    }
+
+    protected Properties loadProperties(File file) throws IOException, 
FileNotFoundException {
+        Properties map = new Properties();
+        if (file.exists()) {
+            try (InputStream is = new FileInputStream(file)) {
+                map.load(is);
+            }
+        }
+        return map;
+    }
+
+    protected void storeProperties(Properties properties, File file) throws 
IOException, FileNotFoundException {
+        try (OutputStream os = new FileOutputStream(file)) {
+            properties.store(os, "Generated at " + new Date());
+        }
+    }
+}
diff --git 
a/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/BundleArtifactFeatureHandler.java
 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/BundleArtifactFeatureHandler.java
new file mode 100644
index 0000000..79558c4
--- /dev/null
+++ 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/BundleArtifactFeatureHandler.java
@@ -0,0 +1,123 @@
+/*
+ * 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.whitelisting.extensions;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.builder.HandlerContext;
+import org.apache.sling.feature.builder.PostProcessHandler;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonValue;
+
+public class BundleArtifactFeatureHandler extends AbstractHandler implements 
PostProcessHandler {
+    @Override
+    public void postProcess(HandlerContext context, Feature feature, Extension 
extension) {
+        if (!"api-regions".equals(extension.getName()))
+            return;
+
+        try {
+            writeBundleToFeatureMap(feature);
+            writeFeatureToRegionAndPackageMap(feature, extension);
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    private void writeBundleToFeatureMap(Feature feature) throws IOException {
+        File bundlesFile = getDataFile("bundles.properties");
+        Properties map = loadProperties(bundlesFile);
+
+        for (Artifact b : feature.getBundles()) {
+            String id = b.getId().toMvnId().trim();
+
+            String fid = b.getMetadata().get("org-feature");
+            if (fid == null)
+                fid = feature.getId().toMvnId().trim();
+
+            String m = map.getProperty(id);
+            if (m != null) {
+                List<String> l = Arrays.asList(m.split(","));
+                if (!l.contains(fid))
+                    m = m.trim() + "," + fid;
+            } else {
+                m = fid;
+            }
+            map.put(id, m);
+        }
+
+        storeProperties(map, bundlesFile);
+    }
+
+    private void writeFeatureToRegionAndPackageMap(Feature feature, Extension 
extension) throws IOException {
+        JsonReader jr = Json.createReader(new 
StringReader(extension.getJSON()));
+        JsonArray ja = jr.readArray();
+
+        File featuresFile = getDataFile("features.properties");
+        File regionsFile = getDataFile("regions.properties");
+        Properties frMap = loadProperties(featuresFile);
+        Properties rpMap = loadProperties(regionsFile);
+
+        for (JsonValue jv : ja) {
+            if (jv instanceof JsonObject) {
+                JsonObject jo = (JsonObject) jv;
+                String fid = jo.getString("org-feature");
+                if (fid == null)
+                    fid = feature.getId().toMvnId();
+
+                Set<String> regionSet = new HashSet<>();
+                String regions = frMap.getProperty(fid);
+                if (regions != null) {
+                    regionSet.addAll(Arrays.asList(regions.split(",")));
+                }
+                String region = jo.getString("name");
+                regionSet.add(region);
+
+                frMap.put(fid, 
regionSet.stream().collect(Collectors.joining(",")));
+
+                Set<String> packageSet = new HashSet<>();
+                String packages = rpMap.getProperty(region);
+                if (packages != null) {
+                    packageSet.addAll(Arrays.asList(packages.split(",")));
+                }
+                JsonArray eja = jo.getJsonArray("exports");
+                for (int i=0; i < eja.size(); i++) {
+                    packageSet.add(eja.getString(i));
+                }
+                rpMap.put(region, 
packageSet.stream().collect(Collectors.joining(",")));
+            }
+        }
+
+        storeProperties(frMap, featuresFile);
+        storeProperties(rpMap, regionsFile);
+    }
+}
diff --git 
a/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/BundleMappingHandler.java
 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/BundleMappingHandler.java
new file mode 100644
index 0000000..1338e88
--- /dev/null
+++ 
b/featuremodel/feature-extension-apiregions/src/main/java/org/apache/sling/feature/whitelisting/extensions/BundleMappingHandler.java
@@ -0,0 +1,63 @@
+/*
+ * 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.whitelisting.extensions;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.builder.HandlerContext;
+import org.apache.sling.feature.builder.PostProcessHandler;
+import org.osgi.framework.Constants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.jar.JarFile;
+
+public class BundleMappingHandler extends AbstractHandler implements 
PostProcessHandler {
+    @Override
+    public void postProcess(HandlerContext context, Feature feature, Extension 
extension) {
+        if (!"api-regions".equals(extension.getName()))
+            return;
+
+
+        try {
+            File idBSNFile = getDataFile("idbsnver.properties");
+            Properties map = loadProperties(idBSNFile);
+
+            for (Artifact b : feature.getBundles()) {
+                File f = context.getArtifactProvider().provide(b.getId());
+
+                try (JarFile jf = new JarFile(f)) {
+                    String bsn = 
jf.getManifest().getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+                    if (bsn == null)
+                        continue;
+
+                    String ver = 
jf.getManifest().getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+                    if (ver == null)
+                        ver = "0.0.0";
+
+                    map.put(b.getId().toMvnId(), bsn.trim() + "~" + 
ver.trim());
+                }
+            }
+
+            storeProperties(map, idBSNFile);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git 
a/featuremodel/feature-extension-apiregions/src/main/resources/META-INF/services/org.apache.sling.feature.builder.MergeHandler
 
b/featuremodel/feature-extension-apiregions/src/main/resources/META-INF/services/org.apache.sling.feature.builder.MergeHandler
new file mode 100644
index 0000000..359d2fa
--- /dev/null
+++ 
b/featuremodel/feature-extension-apiregions/src/main/resources/META-INF/services/org.apache.sling.feature.builder.MergeHandler
@@ -0,0 +1 @@
+org.apache.sling.feature.whitelisting.extensions.APIRegionHandler
diff --git 
a/featuremodel/feature-extension-apiregions/src/main/resources/META-INF/services/org.apache.sling.feature.builder.PostProcessHandler
 
b/featuremodel/feature-extension-apiregions/src/main/resources/META-INF/services/org.apache.sling.feature.builder.PostProcessHandler
new file mode 100644
index 0000000..22b67f7
--- /dev/null
+++ 
b/featuremodel/feature-extension-apiregions/src/main/resources/META-INF/services/org.apache.sling.feature.builder.PostProcessHandler
@@ -0,0 +1,2 @@
+org.apache.sling.feature.whitelisting.extensions.BundleMappingHandler
+org.apache.sling.feature.whitelisting.extensions.BundleArtifactFeatureHandler

Reply via email to