You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2020/09/01 16:32:51 UTC

[sling-org-apache-sling-installer-factory-feature] branch master updated (22f5b28 -> 436c272)

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

davidb pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git.


    from 22f5b28  Adding sonarqube badges as per SLING-9682
     new 34e639d  SLING-9658 Support binary archives in .far files
     new d37d3fb  Remove unnecessary dependency
     new 5d5f715  Explicitly use dynamic, greedy reference
     new 436c272  Merge pull request #1 from bosschaert/SLING-9658-sq

The 32 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 pom.xml                                            |  27 +++-
 .../spi/context/ExtensionHandler.java}             |  30 ++--
 .../spi/context/ExtensionHandlerContext.java       |  61 +++++++
 .../sling/feature/spi/context/package-info.java    |   6 +-
 .../model/impl/APIRegionsExtensionHandler.java     |  74 +++++++++
 .../model/impl/FeatureModelInstallerPlugin.java    |  12 +-
 .../model/impl/InstallFeatureModelTask.java        | 164 ++++++++++++-------
 .../model/impl/RepoinitExtensionHandler.java       |  51 ++++++
 .../model/impl/APIRegionsExtensionHandlerTest.java |  71 +++++++++
 .../model/impl/InstallFeatureModelTaskTest.java    | 177 +++++++++++++++++++++
 .../model/impl/RepoinitExtensionHandlerTest.java   |  68 ++++++++
 src/test/resources/test2/test2.far                 | Bin 0 -> 103630 bytes
 src/test/resources/test2/test2.slingosgifeature    |  10 ++
 13 files changed, 671 insertions(+), 80 deletions(-)
 copy src/main/java/org/apache/sling/{installer/factory/model/impl/InstallContext.java => feature/spi/context/ExtensionHandler.java} (51%)
 create mode 100644 src/main/java/org/apache/sling/feature/spi/context/ExtensionHandlerContext.java
 copy Jenkinsfile => src/main/java/org/apache/sling/feature/spi/context/package-info.java (84%)
 create mode 100644 src/main/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandler.java
 create mode 100644 src/main/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandler.java
 create mode 100644 src/test/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandlerTest.java
 create mode 100644 src/test/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTaskTest.java
 create mode 100644 src/test/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandlerTest.java
 create mode 100644 src/test/resources/test2/test2.far
 create mode 100644 src/test/resources/test2/test2.slingosgifeature


[sling-org-apache-sling-installer-factory-feature] 12/32: [maven-release-plugin] prepare for next development iteration

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 1d7cf922e3b38dae7bec60d8b75f33124994828c
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 13:40:40 2020 +0200

    [maven-release-plugin] prepare for next development iteration
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index b3d39c8..091b889 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.1.0</version>
+    <version>0.1.1-SNAPSHOT</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 


[sling-org-apache-sling-installer-factory-feature] 08/32: Use feature 1.2.0 release

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit c9c474c91205ded2a0fcaa266f46cceebe4ce03b
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Apr 28 13:33:49 2020 +0200

    Use feature 1.2.0 release
---
 README.md | 4 ++--
 pom.xml   | 8 +-------
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index 5a63122..504ac47 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
 
  [![Build Status](https://builds.apache.org/buildStatus/icon?job=Sling/sling-org-apache-sling-installer-factory-model/master)](https://builds.apache.org/job/Sling/job/sling-org-apache-sling-installer-factory-model/job/master) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![installer](https://sling.apache.org/badges/group-installer.svg)](https://github.com/apache/sling-aggregator/blob/master/docs/groups/installer.md)
 
-# Apache Sling Installer Provisioning Model Support
+# Apache Sling Installer Feature Model Support
 
 This module is part of the [Apache Sling](https://sling.apache.org) project.
 
-Provides support for the provisioning model to the Apache Sling OSGi installer
+Provides support for the feature model to the Apache Sling OSGi installer
diff --git a/pom.xml b/pom.xml
index 76a1193..814b2ae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -101,13 +101,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature</artifactId>
-            <version>1.1.8</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.io</artifactId>
-            <version>1.3.0</version>
+            <version>1.2.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>


[sling-org-apache-sling-installer-factory-feature] 10/32: Add error reason to finish state

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 1497e9f811db5d1110dc4c540f8a7c5e75e6b242
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 13:39:04 2020 +0200

    Add error reason to finish state
---
 pom.xml                                                             | 2 +-
 .../sling/installer/factory/model/impl/InstallFeatureModelTask.java | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 814b2ae..4d201eb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,7 +47,7 @@
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
                     <excludePackageNames>
-                        org.apache.sling.installer.factory.model.impl
+                        org.apache.sling.installer.factory.feature.model.impl
                     </excludePackageNames>
                 </configuration>
             </plugin>
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index f60c0cb..7dbb111 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -80,13 +80,13 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             final String featureJson = (String) resource.getAttribute(FeatureModelInstallerPlugin.ATTR_MODEL);
             if (featureJson == null) {
                 ctx.log("Unable to install feature model resource {} : no model found", resource);
-                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                this.getResourceGroup().setFinishState(ResourceState.IGNORED, null, "No model found");
             } else {
                 boolean success = false;
                 final List<InstallableResource> result = this.transform(featureJson, resource);
                 if (result == null) {
                     ctx.log("Unable to install feature model resource {} : unable to create resources", resource);
-                    this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                    this.getResourceGroup().setFinishState(ResourceState.IGNORED, null, "Unable to create resources");
                 } else {
                     if (!result.isEmpty()) {
                         final OsgiInstaller installer = this.getService(OsgiInstaller.class);
@@ -97,7 +97,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                         } else {
                             ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
                                     resource);
-                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                            this.getResourceGroup().setFinishState(ResourceState.IGNORED, null,  "Unable to get OSGi installer");
                             return;
                         }
                     }


[sling-org-apache-sling-installer-factory-feature] 22/32: [maven-release-plugin] prepare for next development iteration

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 76e4f2863207647bbafd3b03292b5acd09e1a738
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun May 3 10:14:48 2020 +0200

    [maven-release-plugin] prepare for next development iteration
---
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index f616e93..ee5bb37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.3.0</version>
+    <version>0.3.1-SNAPSHOT</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 
@@ -38,7 +38,7 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
-      <tag>org.apache.sling.installer.factory.feature-0.3.0</tag>
+      <tag>HEAD</tag>
   </scm>
 
     <build>


[sling-org-apache-sling-installer-factory-feature] 11/32: [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.1.0

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 258c456011118bd5efb1c67f8e2e436ccbeffc69
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 13:40:26 2020 +0200

    [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.1.0
---
 pom.xml | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 4d201eb..b3d39c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,11 +23,11 @@
         <groupId>org.apache.sling</groupId>
         <artifactId>sling-bundle-parent</artifactId>
         <version>38</version>
-        <relativePath/>
+        <relativePath />
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.1.0-SNAPSHOT</version>
+    <version>0.1.0</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 
@@ -38,7 +38,8 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
-    </scm>
+      <tag>org.apache.sling.installer.factory.feature-0.1.0</tag>
+  </scm>
 
     <build>
         <plugins>


[sling-org-apache-sling-installer-factory-feature] 09/32: Update README

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit e92a1c10c07e3332c2fc3442fe5a8280d9c300c3
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 12:51:32 2020 +0200

    Update README
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 504ac47..575bee8 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 [<img src="https://sling.apache.org/res/logos/sling.png"/>](https://sling.apache.org)
 
- [![Build Status](https://builds.apache.org/buildStatus/icon?job=Sling/sling-org-apache-sling-installer-factory-model/master)](https://builds.apache.org/job/Sling/job/sling-org-apache-sling-installer-factory-model/job/master) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![installer](https://sling.apache.org/badges/group-installer.svg)](https://github.com/apache/sling-aggregator/blob/master/docs/groups/installer.md)
+ [![Build Status](https://builds.apache.org/buildStatus/icon?job=Sling/sling-org-apache-sling-installer-factory-feature/master)](https://builds.apache.org/job/Sling/job/sling-org-apache-sling-installer-factory-feature/job/master) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![installer](https://sling.apache.org/badges/group-installer.svg)](https://github.com/apache/sling-aggregator/blob/master/docs/groups/installer.md)
 
 # Apache Sling Installer Feature Model Support
 


[sling-org-apache-sling-installer-factory-feature] 07/32: Add feature region support

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 35fee328c31d0243fe14c6e4dca44a34c525667d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Apr 23 17:11:07 2020 +0200

    Add feature region support
---
 bnd.bnd                                            |   2 +
 pom.xml                                            |  30 +++---
 .../model/impl/FeatureModelInstallerPlugin.java    |  12 +--
 .../factory/model/impl/InstallContext.java         |  14 +--
 .../model/impl/InstallFeatureModelTask.java        | 119 ++++++++++-----------
 5 files changed, 74 insertions(+), 103 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..d2c832f
--- /dev/null
+++ b/bnd.bnd
@@ -0,0 +1,2 @@
+-includeresource: @org.apache.sling.feature.extension.apiregions-[0-9.]*.jar!/org/apache/sling/feature/extension/apiregions/launcher/LauncherProperties.*
+Conditional-Package: org.apache.sling.feature.extension.apiregions.api
diff --git a/pom.xml b/pom.xml
index fe8398e..76a1193 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,12 @@
             <artifactId>osgi.core</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-json_1.1_spec</artifactId>
+            <version>1.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
@@ -94,24 +100,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.jcr.api</artifactId>
-            <version>2.4.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.jcr.repoinit</artifactId>
-            <version>1.1.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.repoinit.parser</artifactId>
-            <version>1.1.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature</artifactId>
             <version>1.1.8</version>
             <scope>provided</scope>
@@ -122,6 +110,12 @@
             <version>1.3.0</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.extension.apiregions</artifactId>
+            <version>1.1.4</version>
+            <scope>provided</scope>
+        </dependency>
    <!-- Testing -->
         <dependency>
             <groupId>junit</groupId>
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index fb34de2..3c1b870 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -94,15 +94,6 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
     /** Logger. */
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-//    @Reference
-//    private SlingRepository repository;
-
-//    @Reference
-//    private JcrRepoInitOpsProcessor repoInitProcessor;
-
-//    @Reference
-//    private RepoInitParser repoInitParser;
-
     private final BundleContext bundleContext;
 
     private final ArtifactManager artifactManager;
@@ -234,8 +225,7 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
         if (rsrc.getState() == ResourceState.UNINSTALL ) {
             return new UninstallFeatureModelTask(group, bundleContext);
         }
-        final InstallContext ctx = new InstallContext(//this.repository, this.repoInitProcessor, this.repoInitParser,
-                this.artifactManager, this.storageDirectory);
+        final InstallContext ctx = new InstallContext(this.artifactManager, this.storageDirectory);
         return new InstallFeatureModelTask(group,
                 ctx, this.bundleContext);
     }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
index 9f7f42f..8408f91 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
@@ -24,23 +24,11 @@ import org.apache.sling.feature.io.artifacts.ArtifactManager;
 
 public class InstallContext {
 
-//    public final SlingRepository repository;
-
-//    public final JcrRepoInitOpsProcessor repoInitProcessor;
-
-//    public final RepoInitParser repoInitParser;
-
     public final ArtifactManager artifactManager;
 
     public final File storageDirectory;
 
-    public InstallContext(//final SlingRepository repository,
-//            final JcrRepoInitOpsProcessor repoInitProcessor,
-//            final RepoInitParser repoInitParser,
-            final ArtifactManager artifactManager, final File storageDirectory) {
-//        this.repository = repository;
-//        this.repoInitProcessor = repoInitProcessor;
-//        this.repoInitParser = repoInitParser;
+    public InstallContext(final ArtifactManager artifactManager, final File storageDirectory) {
         this.artifactManager = artifactManager;
         this.storageDirectory = storageDirectory;
     }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index efce876..f60c0cb 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -38,6 +38,8 @@ import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.extension.apiregions.api.ApiRegions;
+import org.apache.sling.feature.extension.apiregions.launcher.LauncherProperties;
 import org.apache.sling.feature.io.archive.ArchiveReader;
 import org.apache.sling.feature.io.artifacts.ArtifactHandler;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
@@ -54,6 +56,14 @@ import org.osgi.framework.BundleContext;
  */
 public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
+    private static final String PROP_idbsnver = "mapping.bundleid.bsnver";
+    private static final String PROP_bundleFeatures = "mapping.bundleid.features";
+    private static final String PROP_featureRegions = "mapping.featureid.regions";
+    private static final String PROP_regionPackage = "mapping.region.packages";
+
+    private static final String REGION_FACTORY_PID = "org.apache.sling.feature.apiregions.factory~";
+    private static final String REPOINIT_FACTORY_PID = "org.apache.sling.jcr.repoinit.RepositoryInitializer~";
+
     private final InstallContext installContext;
 
     public InstallFeatureModelTask(final TaskResourceGroup group,
@@ -62,7 +72,6 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
         this.installContext = installContext;
     }
 
-    @SuppressWarnings("deprecation")
     @Override
     public void execute(final InstallationContext ctx) {
         try {
@@ -74,49 +83,17 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                 this.getResourceGroup().setFinishState(ResourceState.IGNORED);
             } else {
                 boolean success = false;
-                final Result result = this.transform(featureJson, resource);
+                final List<InstallableResource> result = this.transform(featureJson, resource);
                 if (result == null) {
                     ctx.log("Unable to install feature model resource {} : unable to create resources", resource);
                     this.getResourceGroup().setFinishState(ResourceState.IGNORED);
                 } else {
-                    // repo init first
-/*                    if (result.repoinit != null) {
-                        List<Operation> ops = null;
-                        try (final Reader r = new StringReader(result.repoinit)) {
-                            ops = this.installContext.repoInitParser.parse(r);
-                        } catch (final IOException | RepoInitParsingException e) {
-                            logger.error("Unable to parse repoinit text.", e);
-                            ctx.log("Unable to install feature model resource {} : unable parse repoinit text.",
-                                    resource);
-                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                            return;
-                        }
-
-                        // login admin is required for repo init
-                        Session session = null;
-                        try {
-                            session = this.installContext.repository.loginAdministrative(null);
-                            this.installContext.repoInitProcessor.apply(session, ops);
-                            session.save();
-                        } catch (final RepositoryException re) {
-                            logger.error("Unable to process repoinit text.", re);
-                            ctx.log("Unable to install feature model resource {} : unable to process repoinit text.",
-                                    resource);
-                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                            return;
-
-                        } finally {
-                            if (session != null) {
-                                session.logout();
-                            }
-                        }
-                    }*/
-                    if (!result.resources.isEmpty()) {
+                    if (!result.isEmpty()) {
                         final OsgiInstaller installer = this.getService(OsgiInstaller.class);
                         if (installer != null) {
                             installer.registerResources(
                                     getScheme(resource),
-                                    result.resources.toArray(new InstallableResource[result.resources.size()]));
+                                    result.toArray(new InstallableResource[result.size()]));
                         } else {
                             ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
                                     resource);
@@ -136,16 +113,11 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
         }
     }
 
-    public static final class Result {
-        public final List<InstallableResource> resources = new ArrayList<>();
-//        public String repoinit;
-    }
-
     private File getArtifactFile(final File baseDir, final ArtifactId id) {
         return new File(baseDir, id.toMvnId().replace('/', File.separatorChar));
     }
 
-    private Result transform(final String featureJson,
+    private List<InstallableResource> transform(final String featureJson,
             final TaskResource rsrc) {
         Feature feature = null;
         try (final Reader reader = new StringReader(featureJson)) {
@@ -157,8 +129,26 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             return null;
         }
 
+        final List<InstallableResource> result = new ArrayList<>();
+        // configurations
+        for (final Configuration cfg : feature.getConfigurations()) {
+            result.add(new InstallableResource("/".concat(cfg.getPid()).concat(".config"), null,
+                    cfg.getConfigurationProperties(), null, InstallableResource.TYPE_CONFIG, null));
+        }
+
+        // repoinit
+        final Extension repoInit = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
+        if (repoInit != null && repoInit.getType() == ExtensionType.TEXT) {
+            final String configPid = REPOINIT_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
+            final Dictionary<String, Object> props = new Hashtable<>();
+            props.put("scripts", repoInit.getText());
+
+            result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
+                    props, null, InstallableResource.TYPE_CONFIG, null));
+        }
+
+        // extract artifacts
         if (this.installContext.storageDirectory != null) {
-            // extract artifacts
             final byte[] buffer = new byte[1024*1024*256];
 
             try ( final InputStream is = rsrc.getInputStream() ) {
@@ -184,13 +174,35 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
         }
 
+        // api regions
+        final Extension regionExt = feature.getExtensions().getByName(ApiRegions.EXTENSION_NAME);
+        if ( regionExt != null ) {
+            try {
+                final ApiRegions regions = ApiRegions.parse(regionExt.getJSONStructure().asJsonArray());
+
+                final String configPid = REGION_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
+                final Dictionary<String, Object> props = new Hashtable<>();
+                props.put(PROP_idbsnver, LauncherProperties.getBundleIDtoBSNandVersionMap(feature, this.installContext.artifactManager));
+                props.put(PROP_bundleFeatures, LauncherProperties.getBundleIDtoFeaturesMap(feature));
+                props.put(PROP_featureRegions, LauncherProperties.getFeatureIDtoRegionsMap(regions));
+                props.put(PROP_regionPackage, LauncherProperties.getRegionNametoPackagesMap(regions));
 
-        final Result result = new Result();
+                result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
+                        props, null, InstallableResource.TYPE_CONFIG, null));
+            } catch (final IOException ioe) {
+                logger.warn("Unable to parse region information " + feature.getId().toMvnId(), ioe);
+                return null;
+            }
+        }
+
+        // bundles
         for (final Artifact bundle : feature.getBundles()) {
             if (!addArtifact(bundle, result)) {
                 return null;
             }
         }
+
+        // content packages
         final Extension ext = feature.getExtensions().getByName(Extension.EXTENSION_NAME_CONTENT_PACKAGES);
         if (ext != null && ext.getType() == ExtensionType.ARTIFACTS) {
             for (final Artifact artifact : ext.getArtifacts()) {
@@ -198,26 +210,11 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
         }
 
-        for (final Configuration cfg : feature.getConfigurations()) {
-            result.resources.add(new InstallableResource("/".concat(cfg.getPid()).concat(".config"), null,
-                    cfg.getConfigurationProperties(), null, InstallableResource.TYPE_CONFIG, null));
-        }
-
-        final Extension repoInit = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
-        if (repoInit != null && repoInit.getType() == ExtensionType.TEXT) {
-//            result.repoinit = repoInit.getText();
-            final String configPid = "org.apache.sling.jcr.repoinit.RepositoryInitializer~".concat(feature.getId().toMvnName().replace('-', '_'));
-            final Dictionary<String, Object> props = new Hashtable<>();
-            props.put("scripts", repoInit.getText());
-
-            result.resources.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
-                    props, null, InstallableResource.TYPE_CONFIG, null));
-        }
         return result;
     }
 
     private boolean addArtifact(final Artifact artifact,
-            final Result result) {
+            final List<InstallableResource> result) {
         File artifactFile = (this.installContext.storageDirectory == null ? null
                 : getArtifactFile(this.installContext.storageDirectory, artifact.getId()));
         ArtifactHandler handler;
@@ -250,7 +247,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
             dict.put(InstallableResource.RESOURCE_URI_HINT, handler.getLocalURL().toString());
 
-            result.resources.add(new InstallableResource("/".concat(artifact.getId().toMvnName()), is, dict, digest,
+            result.add(new InstallableResource("/".concat(artifact.getId().toMvnName()), is, dict, digest,
                     InstallableResource.TYPE_FILE, null));
         } catch (final IOException ioe) {
             logger.warn("Unable to read artifact " + handler.getLocalURL(), ioe);


[sling-org-apache-sling-installer-factory-feature] 28/32: Adding sonarqube badges as per SLING-9682

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 22f5b287b1376d28be6436b534596342ed725279
Author: Dan Klco <dk...@apache.org>
AuthorDate: Mon Aug 24 17:18:21 2020 -0400

    Adding sonarqube badges as per SLING-9682
---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 68d698a..86be1cc 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-[<img src="https://sling.apache.org/res/logos/sling.png"/>](https://sling.apache.org)
+[![Apache Sling](https://sling.apache.org/res/logos/sling.png)](https://sling.apache.org)
 
- [![Build Status](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/badge/icon)](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/) [![Test Status](https://img.shields.io/jenkins/tests.svg?jobUrl=https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/)](https://ci-builds.apache.org/job/Sling/job/modu [...]
+&#32;[![Build Status](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/badge/icon)](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/)&#32;[![Test Status](https://img.shields.io/jenkins/tests.svg?jobUrl=https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/)](https://ci-builds.apache.org/job/Sling/ [...]
 
 # Apache Sling Installer Feature Model Support
 


[sling-org-apache-sling-installer-factory-feature] 26/32: SLING-9480 : Provide all artifacts to OSGi installer

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit c328d1f57736b0e2908a65ee5a13e84711883ca0
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu May 28 14:32:14 2020 +0200

    SLING-9480 : Provide all artifacts to OSGi installer
---
 .../installer/factory/model/impl/InstallFeatureModelTask.java | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index 9d62540..a63ff6b 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -206,11 +206,12 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
         }
 
-        // content packages
-        final Extension ext = feature.getExtensions().getByName(Extension.EXTENSION_NAME_CONTENT_PACKAGES);
-        if (ext != null && ext.getType() == ExtensionType.ARTIFACTS) {
-            for (final Artifact artifact : ext.getArtifacts()) {
-                addArtifact(artifact, result);
+        // artifact extensions
+        for(final Extension ext : feature.getExtensions()) {
+            if ( ext.getType() == ExtensionType.ARTIFACTS ) {
+                for (final Artifact artifact : ext.getArtifacts()) {
+                    addArtifact(artifact, result);
+                }
             }
         }
 


[sling-org-apache-sling-installer-factory-feature] 21/32: [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.3.0

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 02fac6ddb50ff2d655be0f0ff269ab34496e8083
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun May 3 10:14:37 2020 +0200

    [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.3.0
---
 pom.xml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index dd9873a..f616e93 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.2.1-SNAPSHOT</version>
+    <version>0.3.0</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 
@@ -38,7 +38,8 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
-    </scm>
+      <tag>org.apache.sling.installer.factory.feature-0.3.0</tag>
+  </scm>
 
     <build>
         <plugins>


[sling-org-apache-sling-installer-factory-feature] 13/32: Remove skip configuration for baseline plugin

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 82089451290c34b1d071f9a2935917c0ea5aadce
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 13:43:25 2020 +0200

    Remove skip configuration for baseline plugin
---
 pom.xml | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/pom.xml b/pom.xml
index 091b889..d2f1bbb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,6 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
-      <tag>org.apache.sling.installer.factory.feature-0.1.0</tag>
   </scm>
 
     <build>
@@ -48,17 +47,10 @@
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
                     <excludePackageNames>
-                        org.apache.sling.installer.factory.feature.model.impl
+                        org.apache.sling.installer.factory.impl
                     </excludePackageNames>
                 </configuration>
             </plugin>
-            <plugin>
-                <groupId>biz.aQute.bnd</groupId>
-                <artifactId>bnd-baseline-maven-plugin</artifactId>
-                <configuration>
-                    <skip>true</skip>
-                </configuration>
-            </plugin>
         </plugins>
     </build>
 


[sling-org-apache-sling-installer-factory-feature] 02/32: Update to support multiple feature files per archive

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 677a88f0a982d04ad9da817e9b4d785d4976191d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sat Feb 22 11:16:10 2020 +0100

    Update to support multiple feature files per archive
---
 .../model/impl/FeatureModelInstallerPlugin.java    | 230 +++++++++++++++++++++
 .../model/impl/FeatureModelTaskFactory.java        | 109 ----------
 .../model/impl/FeatureModelTransformer.java        | 126 -----------
 .../model/impl/InstallFeatureModelTask.java        |   8 +-
 .../model/impl/UninstallFeatureModelTask.java      |   7 +-
 5 files changed, 238 insertions(+), 242 deletions(-)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
new file mode 100644
index 0000000..69df21f
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -0,0 +1,230 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.io.archive.ArchiveReader;
+import org.apache.sling.feature.io.artifacts.ArtifactManager;
+import org.apache.sling.feature.io.artifacts.ArtifactManagerConfig;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.io.json.FeatureJSONWriter;
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.InstallTaskFactory;
+import org.apache.sling.installer.api.tasks.RegisteredResource;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.ResourceTransformer;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.apache.sling.installer.api.tasks.TransformationResult;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
+import org.apache.sling.repoinit.parser.RepoInitParser;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This task factory processes model resources detected by
+ * the {@link FeatureModelTransformer}.
+ */
+@Component(service = { InstallTaskFactory.class, ResourceTransformer.class })
+@Designate(ocd = FeatureModelInstallerPlugin.Config.class)
+public class FeatureModelInstallerPlugin implements InstallTaskFactory, ResourceTransformer {
+
+    @ObjectClassDefinition(name = "Apache Sling Feature Model Installer",
+            description = "This component provides support for feature models to the OSGi installer")
+    public @interface Config {
+
+        @AttributeDefinition(name = "Use Apache Maven",
+                description = "If enabled, missing artifacts from a feature are tried by invoking the mvn command")
+        boolean useMvn() default true;
+
+        @AttributeDefinition(name = "Repository URLs", description = "Additional repository URLs to fetch artifacts")
+        String[] repositories();
+
+        @AttributeDefinition(name = "Classifier Patterns", description = "Patterns for selecting the features to handle based on the classifier. Without a configuration all features are handled.")
+        String[] classifierPatterns();
+    }
+
+    public static final String FILE_EXTENSION = ".json";
+
+    public static final String TYPE_FEATURE_MODEL = "featuremodel";
+
+    public static final String ATTR_MODEL = "feature";
+
+    public static final String ATTR_BASE_PATH = "path";
+
+    public static final String ATTR_ID = "featureId";
+
+    /** Logger. */
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Reference
+    private SlingRepository repository;
+
+    @Reference
+    private JcrRepoInitOpsProcessor repoInitProcessor;
+
+    @Reference
+    private RepoInitParser repoInitParser;
+
+    private final BundleContext bundleContext;
+
+    private final ArtifactManager artifactManager;
+
+    private final List<String> classifierPatterns = new ArrayList<>();
+
+    @Activate
+    public FeatureModelInstallerPlugin(final BundleContext ctx, final Config config) throws IOException {
+        this.bundleContext = ctx;
+        final ArtifactManagerConfig amCfg = new ArtifactManagerConfig();
+        amCfg.setUseMvn(config.useMvn());
+        if (config.repositories() != null && config.repositories().length > 0) {
+            final List<String> repos = new ArrayList<>(Arrays.asList(amCfg.getRepositoryUrls()));
+            for (final String r : config.repositories()) {
+                if (!r.trim().isEmpty()) {
+                    repos.add(r);
+                }
+            }
+            amCfg.setRepositoryUrls(repos.toArray(new String[repos.size()]));
+        }
+        this.artifactManager = ArtifactManager.getArtifactManager(amCfg);
+        if (config.classifierPatterns() != null) {
+            for (final String text : config.classifierPatterns()) {
+                if (text != null && !text.trim().isEmpty()) {
+                    classifierPatterns.add(text.trim());
+                }
+            }
+        }
+    }
+
+    @Override
+    public TransformationResult[] transform(final RegisteredResource resource) {
+        final List<Feature> features = new ArrayList<>();
+        File baseDir = null;
+        if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(FILE_EXTENSION)) {
+            try (final Reader reader = new InputStreamReader(resource.getInputStream(), "UTF-8")) {
+                features.add(FeatureJSONReader.read(reader, resource.getURL()));
+            } catch (final IOException ioe) {
+                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
+            }
+        }
+        if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(".zip")) {
+            baseDir = this.bundleContext.getDataFile("");
+            try (final InputStream is = resource.getInputStream()) {
+                features.addAll(ArchiveReader.read(is, null));
+            } catch (final IOException ioe) {
+                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
+            }
+        }
+        if (!features.isEmpty()) {
+            boolean error = false;
+            final List<TransformationResult> result = new ArrayList<>();
+            for (final Feature feature : features) {
+                boolean select = this.classifierPatterns.isEmpty();
+                if (!select) {
+                    for (final String pattern : this.classifierPatterns) {
+                        if (":".equals(pattern)) {
+                            select = feature.getId().getClassifier() == null;
+                        } else if (feature.getId().getClassifier() != null) {
+                            select = Pattern.compile(pattern).matcher(feature.getId().getClassifier()).matches();
+                        }
+
+                        if (select) {
+                            break;
+                        }
+                    }
+                }
+
+                if (!select) {
+                    continue;
+                }
+
+                String featureJson = null;
+                try (final StringWriter sw = new StringWriter()) {
+                    FeatureJSONWriter.write(sw, feature);
+                    featureJson = sw.toString();
+                } catch (final IOException ioe) {
+                    logger.info("Unable to read feature model from " + resource.getURL(), ioe);
+                }
+
+                if (featureJson != null) {
+                    final TransformationResult tr = new TransformationResult();
+                    tr.setResourceType(TYPE_FEATURE_MODEL);
+                    tr.setId(feature.getId().toMvnId());
+                    tr.setVersion(feature.getId().getOSGiVersion());
+
+                    final Map<String, Object> attributes = new HashMap<>();
+                    attributes.put(ATTR_MODEL, featureJson);
+                    attributes.put(ATTR_ID, feature.getId().toMvnId());
+                    if (baseDir != null) {
+                        final File dir = new File(baseDir, feature.getId().toMvnName());
+                        attributes.put(ATTR_BASE_PATH, dir.getAbsolutePath());
+                    }
+                    tr.setAttributes(attributes);
+
+                    result.add(tr);
+                } else {
+                    error = true;
+                    break;
+                }
+            }
+            if (!error) {
+                return result.toArray(new TransformationResult[result.size()]);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public InstallTask createTask(final TaskResourceGroup group) {
+        final TaskResource rsrc = group.getActiveResource();
+        if (!TYPE_FEATURE_MODEL.equals(rsrc.getType())) {
+            return null;
+        }
+        if (rsrc.getState() == ResourceState.UNINSTALL ) {
+            return new UninstallFeatureModelTask(group, bundleContext);
+        }
+        return new InstallFeatureModelTask(group,
+                this.repository,
+                this.repoInitProcessor,
+                this.repoInitParser,
+                this.bundleContext, this.artifactManager);
+    }
+}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTaskFactory.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTaskFactory.java
deleted file mode 100644
index 60c1e76..0000000
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTaskFactory.java
+++ /dev/null
@@ -1,109 +0,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.
- */
-package org.apache.sling.installer.factory.model.impl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.sling.feature.io.artifacts.ArtifactManager;
-import org.apache.sling.feature.io.artifacts.ArtifactManagerConfig;
-import org.apache.sling.installer.api.tasks.InstallTask;
-import org.apache.sling.installer.api.tasks.InstallTaskFactory;
-import org.apache.sling.installer.api.tasks.ResourceState;
-import org.apache.sling.installer.api.tasks.TaskResource;
-import org.apache.sling.installer.api.tasks.TaskResourceGroup;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
-import org.apache.sling.repoinit.parser.RepoInitParser;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.Designate;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-/**
- * This task factory processes model resources detected by
- * the {@link FeatureModelTransformer}.
- */
-@Component(service = InstallTaskFactory.class)
-@Designate(ocd = FeatureModelTaskFactory.Config.class)
-public class FeatureModelTaskFactory implements InstallTaskFactory {
-
-    @ObjectClassDefinition(name = "Apache Sling Feature Model Installer",
-            description = "This component provides support for feature models to the OSGi installer")
-    public @interface Config {
-
-        @AttributeDefinition(name = "Use Apache Maven",
-                description = "If enabled, missing artifacts from a feature are tried by invoking the mvn command")
-        boolean useMvn() default true;
-
-        @AttributeDefinition(name = "Repository URLs", description = "Additional repository URLs to fetch artifacts")
-        String[] repositories();
-    }
-
-    @Reference
-    private SlingRepository repository;
-
-    @Reference
-    private JcrRepoInitOpsProcessor repoInitProcessor;
-
-    @Reference
-    private RepoInitParser repoInitParser;
-
-    private final BundleContext bundleContext;
-
-    private final ArtifactManager artifactManager;
-
-    @Activate
-    public FeatureModelTaskFactory(final BundleContext ctx, final Config config) throws IOException {
-        this.bundleContext = ctx;
-        final ArtifactManagerConfig amCfg = new ArtifactManagerConfig();
-        amCfg.setUseMvn(config.useMvn());
-        if (config.repositories() != null && config.repositories().length > 0) {
-            final List<String> repos = new ArrayList<>(Arrays.asList(amCfg.getRepositoryUrls()));
-            for (final String r : config.repositories()) {
-                if (!r.trim().isEmpty()) {
-                    repos.add(r);
-                }
-            }
-            amCfg.setRepositoryUrls(repos.toArray(new String[repos.size()]));
-        }
-        this.artifactManager = ArtifactManager.getArtifactManager(amCfg);
-    }
-
-    @Override
-    public InstallTask createTask(final TaskResourceGroup group) {
-        final TaskResource rsrc = group.getActiveResource();
-        if (!FeatureModelTransformer.TYPE_FEATURE_MODEL.equals(rsrc.getType())) {
-            return null;
-        }
-        if (rsrc.getState() == ResourceState.UNINSTALL ) {
-            return new UninstallFeatureModelTask(group, bundleContext);
-        }
-        return new InstallFeatureModelTask(group,
-                this.repository,
-                this.repoInitProcessor,
-                this.repoInitParser,
-                this.bundleContext, this.artifactManager);
-    }
-}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTransformer.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTransformer.java
deleted file mode 100644
index 57b6b99..0000000
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTransformer.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package org.apache.sling.installer.factory.model.impl;/*
- * 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.
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.archive.ArchiveReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONWriter;
-import org.apache.sling.installer.api.InstallableResource;
-import org.apache.sling.installer.api.tasks.RegisteredResource;
-import org.apache.sling.installer.api.tasks.ResourceTransformer;
-import org.apache.sling.installer.api.tasks.TransformationResult;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This transformer detects a file with the ending ".feature" containing a
- * feature model or a feature model archive ending in ".far"
- */
-@Component(service = ResourceTransformer.class)
-public class FeatureModelTransformer implements ResourceTransformer {
-
-    public static final String FILE_EXTENSION = ".json";
-
-    public static final String TYPE_FEATURE_MODEL = "featuremodel";
-
-    public static final String ATTR_MODEL = "feature";
-
-    public static final String ATTR_BASE_PATH = "path";
-
-    public static final String ATTR_ID = "featureId";
-
-    /** Logger. */
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    private final BundleContext bundleContext;
-
-    @Activate
-    public FeatureModelTransformer(final BundleContext bc) {
-        this.bundleContext = bc;
-    }
-
-    @Override
-    public TransformationResult[] transform(final RegisteredResource resource) {
-        Feature feature = null;
-        File baseDir = null;
-        if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(FILE_EXTENSION)) {
-            try ( final Reader reader = new InputStreamReader(resource.getInputStream(), "UTF-8") ) {
-                feature = FeatureJSONReader.read(reader, resource.getURL());
-            } catch ( final IOException ioe) {
-                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
-            }
-        }
-        if (resource.getType().equals(InstallableResource.TYPE_FILE)
-                && resource.getURL().endsWith(".zip")) {
-            baseDir = this.bundleContext.getDataFile("");
-            try ( final InputStream is = resource.getInputStream() ) {
-
-                feature = ArchiveReader.read(is, new ArchiveReader.ArtifactConsumer() {
-                    @Override
-                    public void consume(final ArtifactId artifact, final InputStream is) throws IOException {
-                        // nothing to do, install task does extraction
-                    }
-                });
-            } catch ( final IOException ioe) {
-                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
-            }
-        }
-        if (feature != null) {
-            String featureJson = null;
-            try (final StringWriter sw = new StringWriter()) {
-                FeatureJSONWriter.write(sw, feature);
-                featureJson = sw.toString();
-            } catch (final IOException ioe) {
-                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
-            }
-
-            if (featureJson != null) {
-                final TransformationResult tr = new TransformationResult();
-                tr.setResourceType(TYPE_FEATURE_MODEL);
-                tr.setId(feature.getId().toMvnId());
-                tr.setVersion(feature.getId().getOSGiVersion());
-
-                final Map<String, Object> attributes = new HashMap<>();
-                attributes.put(ATTR_MODEL, featureJson);
-                attributes.put(ATTR_ID, feature.getId().toMvnId());
-                if (baseDir != null) {
-                    final File dir = new File(baseDir, feature.getId().toMvnName());
-                    attributes.put(ATTR_BASE_PATH, dir.getAbsolutePath());
-                }
-                tr.setAttributes(attributes);
-
-                return new TransformationResult[] { tr };
-            }
-        }
-        return null;
-    }
-}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index 55f3f5c..3dde406 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -89,12 +89,12 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
         try {
             final TaskResource resource = this.getResource();
             ctx.log("Installing {}", resource.getEntityId());
-            final String featureJson = (String) resource.getAttribute(FeatureModelTransformer.ATTR_MODEL);
+            final String featureJson = (String) resource.getAttribute(FeatureModelInstallerPlugin.ATTR_MODEL);
             if (featureJson == null) {
                 ctx.log("Unable to install feature model resource {} : no model found", resource);
                 this.getResourceGroup().setFinishState(ResourceState.IGNORED);
             } else {
-                final String path = (String) resource.getAttribute(FeatureModelTransformer.ATTR_BASE_PATH);
+                final String path = (String) resource.getAttribute(FeatureModelInstallerPlugin.ATTR_BASE_PATH);
                 final File baseDir = (path == null ? null : new File(path));
 
                 boolean success = false;
@@ -140,7 +140,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                             final OsgiInstaller installer = this.getService(OsgiInstaller.class);
                             if ( installer != null ) {
                                 installer.registerResources(
-                                        "model-" + resource.getAttribute(FeatureModelTransformer.ATTR_ID),
+                                        "model-" + resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID),
                                         result.resources.toArray(new InstallableResource[result.resources.size()]));
                             } else {
                                 ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
@@ -285,6 +285,6 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
     @Override
     public String getSortKey() {
-        return "30-" + getResource().getAttribute(FeatureModelTransformer.ATTR_ID);
+        return "30-" + getResource().getAttribute(FeatureModelInstallerPlugin.ATTR_ID);
     }
 }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
index ed437de..b584e6d 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
@@ -46,8 +46,9 @@ public class UninstallFeatureModelTask extends AbstractFeatureModelTask {
             } else {
                 final TaskResource resource = this.getResource();
                 ctx.log("Uninstalling {}", resource.getEntityId());
-                installer.registerResources("model-" + resource.getAttribute(FeatureModelTransformer.ATTR_ID), null);
-                final String path = (String)resource.getAttribute(FeatureModelTransformer.ATTR_BASE_PATH);
+                installer.registerResources("model-" + resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID),
+                        null);
+                final String path = (String) resource.getAttribute(FeatureModelInstallerPlugin.ATTR_BASE_PATH);
                 if ( path != null ) {
                     final File dir = new File(path);
                     deleteDirectory(dir);
@@ -62,6 +63,6 @@ public class UninstallFeatureModelTask extends AbstractFeatureModelTask {
 
     @Override
     public String getSortKey() {
-        return "31-" + getResource().getAttribute(FeatureModelTransformer.ATTR_ID);
+        return "31-" + getResource().getAttribute(FeatureModelInstallerPlugin.ATTR_ID);
     }
 }


[sling-org-apache-sling-installer-factory-feature] 20/32: Skip javadoc generation

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit b65c15f439dbaabcf459e791164c486566f18e3a
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sat May 2 10:03:15 2020 +0200

    Skip javadoc generation
---
 pom.xml | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index b8b9c2c..dd9873a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,8 +38,7 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
-    <tag>org.apache.sling.installer.factory.feature-0.2.0</tag>
-  </scm>
+    </scm>
 
     <build>
         <plugins>
@@ -47,9 +46,7 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
-                    <excludePackageNames>
-                        org.apache.sling.installer.factory.impl
-                    </excludePackageNames>
+                    <skip>true</skip>
                 </configuration>
             </plugin>
         </plugins>


[sling-org-apache-sling-installer-factory-feature] 06/32: Use OSGi configuration for repoinit to avoid dependencies to all the JCR services

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 07037cacbd5efa4c5bdb5e0037360a782b888f88
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Apr 20 15:41:51 2020 +0200

    Use OSGi configuration for repoinit to avoid dependencies to all the JCR services
---
 .../model/impl/FeatureModelInstallerPlugin.java     | 20 ++++++++------------
 .../factory/model/impl/InstallContext.java          | 21 +++++++++------------
 .../factory/model/impl/InstallFeatureModelTask.java | 19 ++++++++++---------
 3 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index 3023feb..fb34de2 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -50,13 +50,9 @@ import org.apache.sling.installer.api.tasks.ResourceTransformer;
 import org.apache.sling.installer.api.tasks.TaskResource;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
 import org.apache.sling.installer.api.tasks.TransformationResult;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
-import org.apache.sling.repoinit.parser.RepoInitParser;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -98,14 +94,14 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
     /** Logger. */
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    @Reference
-    private SlingRepository repository;
+//    @Reference
+//    private SlingRepository repository;
 
-    @Reference
-    private JcrRepoInitOpsProcessor repoInitProcessor;
+//    @Reference
+//    private JcrRepoInitOpsProcessor repoInitProcessor;
 
-    @Reference
-    private RepoInitParser repoInitParser;
+//    @Reference
+//    private RepoInitParser repoInitParser;
 
     private final BundleContext bundleContext;
 
@@ -158,7 +154,7 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
                 logger.info("Unable to read feature model from " + resource.getURL(), ioe);
             }
         }
-        if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(".zip")) {
+        if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(".far")) {
             try (final InputStream is = resource.getInputStream()) {
                 features.addAll(ArchiveReader.read(is, null));
             } catch (final IOException ioe) {
@@ -238,7 +234,7 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
         if (rsrc.getState() == ResourceState.UNINSTALL ) {
             return new UninstallFeatureModelTask(group, bundleContext);
         }
-        final InstallContext ctx = new InstallContext(this.repository, this.repoInitProcessor, this.repoInitParser,
+        final InstallContext ctx = new InstallContext(//this.repository, this.repoInitProcessor, this.repoInitParser,
                 this.artifactManager, this.storageDirectory);
         return new InstallFeatureModelTask(group,
                 ctx, this.bundleContext);
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
index 0af42fa..9f7f42f 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
@@ -21,29 +21,26 @@ package org.apache.sling.installer.factory.model.impl;
 import java.io.File;
 
 import org.apache.sling.feature.io.artifacts.ArtifactManager;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
-import org.apache.sling.repoinit.parser.RepoInitParser;
 
 public class InstallContext {
 
-    public final SlingRepository repository;
+//    public final SlingRepository repository;
 
-    public final JcrRepoInitOpsProcessor repoInitProcessor;
+//    public final JcrRepoInitOpsProcessor repoInitProcessor;
 
-    public final RepoInitParser repoInitParser;
+//    public final RepoInitParser repoInitParser;
 
     public final ArtifactManager artifactManager;
 
     public final File storageDirectory;
 
-    public InstallContext(final SlingRepository repository,
-            final JcrRepoInitOpsProcessor repoInitProcessor,
-            final RepoInitParser repoInitParser,
+    public InstallContext(//final SlingRepository repository,
+//            final JcrRepoInitOpsProcessor repoInitProcessor,
+//            final RepoInitParser repoInitParser,
             final ArtifactManager artifactManager, final File storageDirectory) {
-        this.repository = repository;
-        this.repoInitProcessor = repoInitProcessor;
-        this.repoInitParser = repoInitParser;
+//        this.repository = repository;
+//        this.repoInitProcessor = repoInitProcessor;
+//        this.repoInitParser = repoInitParser;
         this.artifactManager = artifactManager;
         this.storageDirectory = storageDirectory;
     }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index 5e97d54..efce876 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -32,9 +32,6 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Configuration;
@@ -50,8 +47,6 @@ import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.apache.sling.installer.api.tasks.ResourceState;
 import org.apache.sling.installer.api.tasks.TaskResource;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
-import org.apache.sling.repoinit.parser.RepoInitParsingException;
-import org.apache.sling.repoinit.parser.operations.Operation;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -85,7 +80,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                     this.getResourceGroup().setFinishState(ResourceState.IGNORED);
                 } else {
                     // repo init first
-                    if (result.repoinit != null) {
+/*                    if (result.repoinit != null) {
                         List<Operation> ops = null;
                         try (final Reader r = new StringReader(result.repoinit)) {
                             ops = this.installContext.repoInitParser.parse(r);
@@ -115,7 +110,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                                 session.logout();
                             }
                         }
-                    }
+                    }*/
                     if (!result.resources.isEmpty()) {
                         final OsgiInstaller installer = this.getService(OsgiInstaller.class);
                         if (installer != null) {
@@ -143,7 +138,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
     public static final class Result {
         public final List<InstallableResource> resources = new ArrayList<>();
-        public String repoinit;
+//        public String repoinit;
     }
 
     private File getArtifactFile(final File baseDir, final ArtifactId id) {
@@ -210,7 +205,13 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
         final Extension repoInit = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
         if (repoInit != null && repoInit.getType() == ExtensionType.TEXT) {
-            result.repoinit = repoInit.getText();
+//            result.repoinit = repoInit.getText();
+            final String configPid = "org.apache.sling.jcr.repoinit.RepositoryInitializer~".concat(feature.getId().toMvnName().replace('-', '_'));
+            final Dictionary<String, Object> props = new Hashtable<>();
+            props.put("scripts", repoInit.getText());
+
+            result.resources.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
+                    props, null, InstallableResource.TYPE_CONFIG, null));
         }
         return result;
     }


[sling-org-apache-sling-installer-factory-feature] 01/32: Initial OSGi installer support for features

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 2d6c2e714b6e2c50a6d8730d23836b88d8624ad3
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Feb 21 09:16:47 2020 +0100

    Initial OSGi installer support for features
---
 .gitignore                                         |  17 ++
 CODE_OF_CONDUCT.md                                 |  22 ++
 CONTRIBUTING.md                                    |  24 ++
 Jenkinsfile                                        |  20 ++
 LICENSE                                            | 202 ++++++++++++++
 README.md                                          |   9 +
 pom.xml                                            | 120 +++++++++
 .../model/impl/AbstractFeatureModelTask.java       |  89 +++++++
 .../model/impl/FeatureModelTaskFactory.java        | 109 ++++++++
 .../model/impl/FeatureModelTransformer.java        | 126 +++++++++
 .../model/impl/InstallFeatureModelTask.java        | 290 +++++++++++++++++++++
 .../model/impl/UninstallFeatureModelTask.java      |  67 +++++
 12 files changed, 1095 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5b783ed
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+/target
+.idea
+.classpath
+.metadata
+.project
+.settings
+.externalToolBuilders
+maven-eclipse.xml
+*.swp
+*.iml
+*.ipr
+*.iws
+*.bak
+.vlt
+.DS_Store
+jcr.log
+atlassian-ide-plugin.xml
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..0fa18e5
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,22 @@
+<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
+Apache Software Foundation Code of Conduct
+====
+
+Being an Apache project, Apache Sling adheres to the Apache Software Foundation's [Code of Conduct](https://www.apache.org/foundation/policies/conduct.html).
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..ac82a1a
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,24 @@
+<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
+Contributing
+====
+
+Thanks for choosing to contribute!
+
+You will find all the necessary details about how you can do this at https://sling.apache.org/contributing.html.
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..f582519
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,20 @@
+/**
+ * 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.
+ */
+
+slingOsgiBundleBuild()
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5a63122
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+[<img src="https://sling.apache.org/res/logos/sling.png"/>](https://sling.apache.org)
+
+ [![Build Status](https://builds.apache.org/buildStatus/icon?job=Sling/sling-org-apache-sling-installer-factory-model/master)](https://builds.apache.org/job/Sling/job/sling-org-apache-sling-installer-factory-model/job/master) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![installer](https://sling.apache.org/badges/group-installer.svg)](https://github.com/apache/sling-aggregator/blob/master/docs/groups/installer.md)
+
+# Apache Sling Installer Provisioning Model Support
+
+This module is part of the [Apache Sling](https://sling.apache.org) project.
+
+Provides support for the provisioning model to the Apache Sling OSGi installer
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..815d242
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,120 @@
+<?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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling-bundle-parent</artifactId>
+        <version>38</version>
+        <relativePath/>
+    </parent>
+
+    <artifactId>org.apache.sling.installer.factory.feature</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+
+    <name>Apache Sling Installer Feature Model Support</name>
+    <description> 
+        Provides support for the feature model to the Apache Sling OSGi installer
+    </description>
+
+    <scm>
+        <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
+        <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
+        <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <excludePackageNames>
+                        org.apache.sling.installer.factory.model.impl
+                    </excludePackageNames>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation.versioning</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.metatype.annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.installer.core</artifactId>
+            <version>3.8.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.api</artifactId>
+            <version>2.4.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.repoinit</artifactId>
+            <version>1.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.repoinit.parser</artifactId>
+            <version>1.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature</artifactId>
+            <version>1.1.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.io</artifactId>
+            <version>1.3.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractFeatureModelTask.java
new file mode 100644
index 0000000..2f6f459
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractFeatureModelTask.java
@@ -0,0 +1,89 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class for the tasks.
+ */
+public abstract class AbstractFeatureModelTask extends InstallTask {
+
+    /** Logger. */
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private final BundleContext bundleContext;
+
+    private final Map<ServiceReference<?>, Object> services = new HashMap<>();
+
+    public AbstractFeatureModelTask(final TaskResourceGroup group,
+            final BundleContext bundleContext) {
+        super(group);
+        this.bundleContext = bundleContext;
+    }
+
+    protected void cleanup() {
+        for(final ServiceReference<?> r : this.services.keySet()) {
+            this.bundleContext.ungetService(r);
+        }
+        this.services.clear();
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <T> T getService(final Class<T> type) {
+        T service = null;
+        final ServiceReference<T> reference = this.bundleContext.getServiceReference(type);
+        if ( reference != null ) {
+            service = (T)this.services.get(reference);
+            if ( service == null ) {
+                service = this.bundleContext.getService(reference);
+                if ( service != null ) {
+                    this.services.put(reference, service);
+                } else {
+                }
+            }
+        }
+        if ( service == null ) {
+            logger.error("Unable to get OSGi service " + type.getName());
+        }
+        return service;
+    }
+
+    protected void deleteDirectory(final File dir) {
+        if ( dir.exists() ) {
+            for(final File f : dir.listFiles()) {
+                if ( f.isDirectory() ) {
+                    deleteDirectory(f);
+                } else {
+                    f.delete();
+                }
+            }
+            dir.delete();
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTaskFactory.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTaskFactory.java
new file mode 100644
index 0000000..60c1e76
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTaskFactory.java
@@ -0,0 +1,109 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sling.feature.io.artifacts.ArtifactManager;
+import org.apache.sling.feature.io.artifacts.ArtifactManagerConfig;
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.InstallTaskFactory;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
+import org.apache.sling.repoinit.parser.RepoInitParser;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+/**
+ * This task factory processes model resources detected by
+ * the {@link FeatureModelTransformer}.
+ */
+@Component(service = InstallTaskFactory.class)
+@Designate(ocd = FeatureModelTaskFactory.Config.class)
+public class FeatureModelTaskFactory implements InstallTaskFactory {
+
+    @ObjectClassDefinition(name = "Apache Sling Feature Model Installer",
+            description = "This component provides support for feature models to the OSGi installer")
+    public @interface Config {
+
+        @AttributeDefinition(name = "Use Apache Maven",
+                description = "If enabled, missing artifacts from a feature are tried by invoking the mvn command")
+        boolean useMvn() default true;
+
+        @AttributeDefinition(name = "Repository URLs", description = "Additional repository URLs to fetch artifacts")
+        String[] repositories();
+    }
+
+    @Reference
+    private SlingRepository repository;
+
+    @Reference
+    private JcrRepoInitOpsProcessor repoInitProcessor;
+
+    @Reference
+    private RepoInitParser repoInitParser;
+
+    private final BundleContext bundleContext;
+
+    private final ArtifactManager artifactManager;
+
+    @Activate
+    public FeatureModelTaskFactory(final BundleContext ctx, final Config config) throws IOException {
+        this.bundleContext = ctx;
+        final ArtifactManagerConfig amCfg = new ArtifactManagerConfig();
+        amCfg.setUseMvn(config.useMvn());
+        if (config.repositories() != null && config.repositories().length > 0) {
+            final List<String> repos = new ArrayList<>(Arrays.asList(amCfg.getRepositoryUrls()));
+            for (final String r : config.repositories()) {
+                if (!r.trim().isEmpty()) {
+                    repos.add(r);
+                }
+            }
+            amCfg.setRepositoryUrls(repos.toArray(new String[repos.size()]));
+        }
+        this.artifactManager = ArtifactManager.getArtifactManager(amCfg);
+    }
+
+    @Override
+    public InstallTask createTask(final TaskResourceGroup group) {
+        final TaskResource rsrc = group.getActiveResource();
+        if (!FeatureModelTransformer.TYPE_FEATURE_MODEL.equals(rsrc.getType())) {
+            return null;
+        }
+        if (rsrc.getState() == ResourceState.UNINSTALL ) {
+            return new UninstallFeatureModelTask(group, bundleContext);
+        }
+        return new InstallFeatureModelTask(group,
+                this.repository,
+                this.repoInitProcessor,
+                this.repoInitParser,
+                this.bundleContext, this.artifactManager);
+    }
+}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTransformer.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTransformer.java
new file mode 100644
index 0000000..57b6b99
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelTransformer.java
@@ -0,0 +1,126 @@
+package org.apache.sling.installer.factory.model.impl;/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.io.archive.ArchiveReader;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.io.json.FeatureJSONWriter;
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.tasks.RegisteredResource;
+import org.apache.sling.installer.api.tasks.ResourceTransformer;
+import org.apache.sling.installer.api.tasks.TransformationResult;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This transformer detects a file with the ending ".feature" containing a
+ * feature model or a feature model archive ending in ".far"
+ */
+@Component(service = ResourceTransformer.class)
+public class FeatureModelTransformer implements ResourceTransformer {
+
+    public static final String FILE_EXTENSION = ".json";
+
+    public static final String TYPE_FEATURE_MODEL = "featuremodel";
+
+    public static final String ATTR_MODEL = "feature";
+
+    public static final String ATTR_BASE_PATH = "path";
+
+    public static final String ATTR_ID = "featureId";
+
+    /** Logger. */
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private final BundleContext bundleContext;
+
+    @Activate
+    public FeatureModelTransformer(final BundleContext bc) {
+        this.bundleContext = bc;
+    }
+
+    @Override
+    public TransformationResult[] transform(final RegisteredResource resource) {
+        Feature feature = null;
+        File baseDir = null;
+        if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(FILE_EXTENSION)) {
+            try ( final Reader reader = new InputStreamReader(resource.getInputStream(), "UTF-8") ) {
+                feature = FeatureJSONReader.read(reader, resource.getURL());
+            } catch ( final IOException ioe) {
+                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
+            }
+        }
+        if (resource.getType().equals(InstallableResource.TYPE_FILE)
+                && resource.getURL().endsWith(".zip")) {
+            baseDir = this.bundleContext.getDataFile("");
+            try ( final InputStream is = resource.getInputStream() ) {
+
+                feature = ArchiveReader.read(is, new ArchiveReader.ArtifactConsumer() {
+                    @Override
+                    public void consume(final ArtifactId artifact, final InputStream is) throws IOException {
+                        // nothing to do, install task does extraction
+                    }
+                });
+            } catch ( final IOException ioe) {
+                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
+            }
+        }
+        if (feature != null) {
+            String featureJson = null;
+            try (final StringWriter sw = new StringWriter()) {
+                FeatureJSONWriter.write(sw, feature);
+                featureJson = sw.toString();
+            } catch (final IOException ioe) {
+                logger.info("Unable to read feature model from " + resource.getURL(), ioe);
+            }
+
+            if (featureJson != null) {
+                final TransformationResult tr = new TransformationResult();
+                tr.setResourceType(TYPE_FEATURE_MODEL);
+                tr.setId(feature.getId().toMvnId());
+                tr.setVersion(feature.getId().getOSGiVersion());
+
+                final Map<String, Object> attributes = new HashMap<>();
+                attributes.put(ATTR_MODEL, featureJson);
+                attributes.put(ATTR_ID, feature.getId().toMvnId());
+                if (baseDir != null) {
+                    final File dir = new File(baseDir, feature.getId().toMvnName());
+                    attributes.put(ATTR_BASE_PATH, dir.getAbsolutePath());
+                }
+                tr.setAttributes(attributes);
+
+                return new TransformationResult[] { tr };
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
new file mode 100644
index 0000000..55f3f5c
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -0,0 +1,290 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Configuration;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.io.archive.ArchiveReader;
+import org.apache.sling.feature.io.artifacts.ArtifactHandler;
+import org.apache.sling.feature.io.artifacts.ArtifactManager;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.OsgiInstaller;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
+import org.apache.sling.repoinit.parser.RepoInitParser;
+import org.apache.sling.repoinit.parser.RepoInitParsingException;
+import org.apache.sling.repoinit.parser.operations.Operation;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This task installs a feature model resources.
+ */
+public class InstallFeatureModelTask extends AbstractFeatureModelTask {
+
+    private final SlingRepository repository;
+
+    private final JcrRepoInitOpsProcessor repoInitProcessor;
+
+    private final RepoInitParser repoInitParser;
+
+    private final ArtifactManager artifactManager;
+
+    public InstallFeatureModelTask(final TaskResourceGroup group,
+            final SlingRepository repository,
+            final JcrRepoInitOpsProcessor repoInitProcessor,
+            final RepoInitParser repoInitParser,
+            final BundleContext bundleContext, final ArtifactManager artifactManager) {
+        super(group, bundleContext);
+        this.repository = repository;
+        this.repoInitProcessor = repoInitProcessor;
+        this.repoInitParser = repoInitParser;
+        this.artifactManager = artifactManager;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void execute(final InstallationContext ctx) {
+        try {
+            final TaskResource resource = this.getResource();
+            ctx.log("Installing {}", resource.getEntityId());
+            final String featureJson = (String) resource.getAttribute(FeatureModelTransformer.ATTR_MODEL);
+            if (featureJson == null) {
+                ctx.log("Unable to install feature model resource {} : no model found", resource);
+                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+            } else {
+                final String path = (String) resource.getAttribute(FeatureModelTransformer.ATTR_BASE_PATH);
+                final File baseDir = (path == null ? null : new File(path));
+
+                boolean success = false;
+                try {
+                    final Result result = this.transform(featureJson, resource, baseDir);
+                    if ( result == null ) {
+                        ctx.log("Unable to install feature model resource {} : unable to create resources", resource);
+                        this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                    } else {
+                        // repo init first
+                        if ( result.repoinit != null ) {
+                            List<Operation> ops = null;
+                            try ( final Reader r = new StringReader(result.repoinit) ) {
+                                ops = this.repoInitParser.parse(r);
+                            } catch (final IOException | RepoInitParsingException e) {
+                                logger.error("Unable to parse repoinit text.", e);
+                                ctx.log("Unable to install feature model resource {} : unable parse repoinit text.",
+                                        resource);
+                                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                                return;
+                            }
+
+                            // login admin is required for repo init
+                            Session session = null;
+                            try {
+                                session = this.repository.loginAdministrative(null);
+                                this.repoInitProcessor.apply(session, ops);
+                                session.save();
+                            } catch ( final RepositoryException re) {
+                                logger.error("Unable to process repoinit text.", re);
+                                ctx.log("Unable to install feature model resource {} : unable to process repoinit text.",
+                                        resource);
+                                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                                return;
+
+                            } finally {
+                                if ( session != null ) {
+                                    session.logout();
+                                }
+                            }
+                        }
+                        if ( !result.resources.isEmpty() ) {
+                            final OsgiInstaller installer = this.getService(OsgiInstaller.class);
+                            if ( installer != null ) {
+                                installer.registerResources(
+                                        "model-" + resource.getAttribute(FeatureModelTransformer.ATTR_ID),
+                                        result.resources.toArray(new InstallableResource[result.resources.size()]));
+                            } else {
+                                ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
+                                        resource);
+                                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                                return;
+                            }
+                        }
+                        this.getResourceGroup().setFinishState(ResourceState.INSTALLED);
+                        success = true;
+                    }
+                } finally {
+                    if ( !success && baseDir != null ) {
+                        this.deleteDirectory(baseDir);
+                    }
+                }
+                if ( success ) {
+                    ctx.log("Installed {}", resource.getEntityId());
+                }
+            }
+        } finally {
+            this.cleanup();
+        }
+    }
+
+    public static final class Result {
+        public final List<InstallableResource> resources = new ArrayList<>();
+        public String repoinit;
+    }
+
+    private File getArtifactFile(final File baseDir, final ArtifactId id) {
+        return new File(baseDir, id.toMvnId().replace('/', File.separatorChar));
+    }
+
+    private Result transform(final String featureJson,
+            final TaskResource rsrc,
+            final File baseDir) {
+        Feature feature = null;
+        try (final Reader reader = new StringReader(featureJson)) {
+            feature = FeatureJSONReader.read(reader, null);
+        } catch ( final IOException ioe) {
+            logger.warn("Unable to read feature model file", ioe);
+        }
+        if (feature == null) {
+            return null;
+        }
+
+        if ( baseDir != null ) {
+            // extract artifacts
+            final byte[] buffer = new byte[1024*1024*256];
+
+            try ( final InputStream is = rsrc.getInputStream() ) {
+                ArchiveReader.read(is, new ArchiveReader.ArtifactConsumer() {
+
+                    @Override
+                    public void consume(final ArtifactId id, final InputStream is) throws IOException {
+                        final File artifactFile = getArtifactFile(baseDir, id);
+                        if (!artifactFile.exists()) {
+                            artifactFile.getParentFile().mkdirs();
+                            try (final OutputStream os = new FileOutputStream(artifactFile)) {
+                                int l = 0;
+                                while ((l = is.read(buffer)) > 0) {
+                                    os.write(buffer, 0, l);
+                                }
+                            }
+                        }
+                    }
+                });
+            } catch ( final IOException ioe) {
+                logger.warn("Unable to extract artifacts from feature model " + feature.getId().toMvnId(), ioe);
+                return null;
+            }
+        }
+
+
+        final Result result = new Result();
+        for (final Artifact bundle : feature.getBundles()) {
+            if (!addArtifact(baseDir, bundle, result)) {
+                return null;
+            }
+        }
+        final Extension ext = feature.getExtensions().getByName(Extension.EXTENSION_NAME_CONTENT_PACKAGES);
+        if (ext != null && ext.getType() == ExtensionType.ARTIFACTS) {
+            for (final Artifact artifact : ext.getArtifacts()) {
+                addArtifact(baseDir, artifact, result);
+            }
+        }
+
+        for (final Configuration cfg : feature.getConfigurations()) {
+            result.resources.add(new InstallableResource("/".concat(cfg.getPid()).concat(".config"), null,
+                    cfg.getConfigurationProperties(), null, InstallableResource.TYPE_CONFIG, null));
+        }
+
+        final Extension repoInit = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
+        if (repoInit != null && repoInit.getType() == ExtensionType.TEXT) {
+            result.repoinit = repoInit.getText();
+        }
+        return result;
+    }
+
+    private boolean addArtifact(final File baseDir, final Artifact artifact,
+            final Result result) {
+        File artifactFile = (baseDir == null ? null : getArtifactFile(baseDir, artifact.getId()));
+        ArtifactHandler handler;
+        if (artifactFile == null || !artifactFile.exists()) {
+            try {
+                handler = this.artifactManager.getArtifactHandler(artifact.getId().toMvnUrl());
+            } catch (final IOException ignore) {
+                return false;
+            }
+        } else {
+            try {
+                handler = new ArtifactHandler(artifactFile);
+            } catch (final MalformedURLException e) {
+                return false;
+            }
+        }
+        if (handler == null) {
+            return false;
+        }
+        try {
+            final URLConnection connection = handler.getLocalURL().openConnection();
+            connection.connect();
+            final InputStream is = connection.getInputStream();
+            final long lastModified = connection.getLastModified();
+            final String digest = lastModified == 0 ? null : String.valueOf(lastModified);
+            // handle start order
+            final Dictionary<String, Object> dict = new Hashtable<String, Object>();
+            if (artifact.getStartOrder() > 0) {
+                dict.put(InstallableResource.BUNDLE_START_LEVEL, artifact.getStartOrder());
+            }
+            dict.put(InstallableResource.RESOURCE_URI_HINT, handler.getLocalURL().toString());
+
+            result.resources.add(new InstallableResource("/".concat(artifact.getId().toMvnName()), is, dict, digest,
+                    InstallableResource.TYPE_FILE, null));
+        } catch (final IOException ioe) {
+            logger.warn("Unable to read artifact " + handler.getLocalURL(), ioe);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String getSortKey() {
+        return "30-" + getResource().getAttribute(FeatureModelTransformer.ATTR_ID);
+    }
+}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
new file mode 100644
index 0000000..ed437de
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
@@ -0,0 +1,67 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import java.io.File;
+
+import org.apache.sling.installer.api.OsgiInstaller;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This task uninstalls feature model resources.
+ */
+public class UninstallFeatureModelTask extends AbstractFeatureModelTask {
+
+    public UninstallFeatureModelTask(final TaskResourceGroup group,
+            final BundleContext bundleContext) {
+        super(group, bundleContext);
+    }
+
+    @Override
+    public void execute(final InstallationContext ctx) {
+        try {
+            final OsgiInstaller installer = this.getService(OsgiInstaller.class);
+            if ( installer == null ) {
+                ctx.log("Unable to get OSGi Installer service!");
+            } else {
+                final TaskResource resource = this.getResource();
+                ctx.log("Uninstalling {}", resource.getEntityId());
+                installer.registerResources("model-" + resource.getAttribute(FeatureModelTransformer.ATTR_ID), null);
+                final String path = (String)resource.getAttribute(FeatureModelTransformer.ATTR_BASE_PATH);
+                if ( path != null ) {
+                    final File dir = new File(path);
+                    deleteDirectory(dir);
+                }
+                this.getResourceGroup().setFinishState(ResourceState.UNINSTALLED);
+                ctx.log("Uninstalled {}", resource.getEntityId());
+            }
+        } finally {
+            this.cleanup();
+        }
+    }
+
+    @Override
+    public String getSortKey() {
+        return "31-" + getResource().getAttribute(FeatureModelTransformer.ATTR_ID);
+    }
+}


[sling-org-apache-sling-installer-factory-feature] 15/32: Correctly configure caching directory

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 542240c4b230d78d27926119db053b288186f20e
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 17:41:32 2020 +0200

    Correctly configure caching directory
---
 .../installer/factory/model/impl/FeatureModelInstallerPlugin.java     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index 3c1b870..cc86f97 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -108,10 +108,10 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
         this.storageDirectory = this.bundleContext.getDataFile("repository");
         final ArtifactManagerConfig amCfg = new ArtifactManagerConfig();
         amCfg.setUseMvn(config.useMvn());
-        final List<String> repos = new ArrayList<>(Arrays.asList(amCfg.getRepositoryUrls()));
         if (this.storageDirectory != null) {
-            repos.add(this.storageDirectory.toURI().toURL().toExternalForm());
+            amCfg.setCacheDirectory(storageDirectory);
         }
+        final List<String> repos = new ArrayList<>(Arrays.asList(amCfg.getRepositoryUrls()));
         if (config.repositories() != null && config.repositories().length > 0) {
             for (final String r : config.repositories()) {
                 if (!r.trim().isEmpty()) {


[sling-org-apache-sling-installer-factory-feature] 32/32: Merge pull request #1 from bosschaert/SLING-9658-sq

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 436c272467ec77f1ffe486cd1dd3a0de7f8418ee
Merge: 22f5b28 5d5f715
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Tue Sep 1 17:32:44 2020 +0100

    Merge pull request #1 from bosschaert/SLING-9658-sq
    
    SLING-9658 Support binary archives in .far files

 pom.xml                                            |  27 +++-
 .../feature/spi/context/ExtensionHandler.java      |  37 +++++
 .../spi/context/ExtensionHandlerContext.java       |  61 +++++++
 .../sling/feature/spi/context/package-info.java    |  22 +++
 .../model/impl/APIRegionsExtensionHandler.java     |  74 +++++++++
 .../model/impl/FeatureModelInstallerPlugin.java    |  12 +-
 .../model/impl/InstallFeatureModelTask.java        | 164 ++++++++++++-------
 .../model/impl/RepoinitExtensionHandler.java       |  51 ++++++
 .../model/impl/APIRegionsExtensionHandlerTest.java |  71 +++++++++
 .../model/impl/InstallFeatureModelTaskTest.java    | 177 +++++++++++++++++++++
 .../model/impl/RepoinitExtensionHandlerTest.java   |  68 ++++++++
 src/test/resources/test2/test2.far                 | Bin 0 -> 103630 bytes
 src/test/resources/test2/test2.slingosgifeature    |  10 ++
 13 files changed, 710 insertions(+), 64 deletions(-)


[sling-org-apache-sling-installer-factory-feature] 24/32: [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.4.0

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit bc5f61800bbc4909428391704ed111f1bf0cecbb
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 25 12:14:19 2020 +0200

    [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.4.0
---
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index ee5bb37..f7f1b07 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.3.1-SNAPSHOT</version>
+    <version>0.4.0</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 
@@ -38,7 +38,7 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
-      <tag>HEAD</tag>
+      <tag>org.apache.sling.installer.factory.feature-0.4.0</tag>
   </scm>
 
     <build>


[sling-org-apache-sling-installer-factory-feature] 05/32: Fix url scheme

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 7549fb2734c692db07eccf783d06a2d87e164519
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 15 15:50:50 2020 +0200

    Fix url scheme
---
 pom.xml                                                             | 6 +++---
 .../installer/factory/model/impl/AbstractFeatureModelTask.java      | 5 +++++
 .../sling/installer/factory/model/impl/InstallFeatureModelTask.java | 2 +-
 .../installer/factory/model/impl/UninstallFeatureModelTask.java     | 3 +--
 .../factory/model/impl/FeatureModelInstallerPluginTest.java         | 2 +-
 5 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index 2bcd34a..fe8398e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -113,13 +113,13 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature</artifactId>
-            <version>1.1.2</version>
+            <version>1.1.8</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature.io</artifactId>
-            <version>1.3.0-SNAPSHOT</version>
+            <version>1.3.0</version>
             <scope>provided</scope>
         </dependency>
    <!-- Testing -->
@@ -130,7 +130,7 @@
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>2.15.0</version>
+            <version>3.3.0</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractFeatureModelTask.java
index 2f6f459..d58ec51 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractFeatureModelTask.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.TaskResource;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -54,6 +55,10 @@ public abstract class AbstractFeatureModelTask extends InstallTask {
         this.services.clear();
     }
 
+    protected String getScheme(final TaskResource resource) {
+        return "model-".concat(resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID).toString().replace(':', '_'));
+    }
+
     @SuppressWarnings("unchecked")
     protected <T> T getService(final Class<T> type) {
         T service = null;
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index 34572c4..5e97d54 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -120,7 +120,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                         final OsgiInstaller installer = this.getService(OsgiInstaller.class);
                         if (installer != null) {
                             installer.registerResources(
-                                    "model-" + resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID),
+                                    getScheme(resource),
                                     result.resources.toArray(new InstallableResource[result.resources.size()]));
                         } else {
                             ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
index d734e4a..4370438 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
@@ -44,8 +44,7 @@ public class UninstallFeatureModelTask extends AbstractFeatureModelTask {
             } else {
                 final TaskResource resource = this.getResource();
                 ctx.log("Uninstalling {}", resource.getEntityId());
-                installer.registerResources("model-" + resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID),
-                        null);
+                installer.registerResources(getScheme(resource), null);
                 this.getResourceGroup().setFinishState(ResourceState.UNINSTALLED);
                 ctx.log("Uninstalled {}", resource.getEntityId());
             }
diff --git a/src/test/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPluginTest.java b/src/test/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPluginTest.java
index 04c7eda..e640a5a 100644
--- a/src/test/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPluginTest.java
+++ b/src/test/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPluginTest.java
@@ -50,7 +50,7 @@ public class FeatureModelInstallerPluginTest {
     }
 
     @Test
-    public void tesClassifierPatterns() throws Exception {
+    public void testClassifierPatterns() throws Exception {
         final FeatureModelInstallerPlugin.Config config = Mockito.mock(FeatureModelInstallerPlugin.Config.class);
         Mockito.when(config.classifierPatterns()).thenReturn(new String[] { ":", "*devfar", "*prodfar", "*special*" });
 


[sling-org-apache-sling-installer-factory-feature] 19/32: SLING-9415 : Mvn id instead of path used to store artifacts

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit a3fed5f4e956eae1502a952889c98c56f341237c
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri May 1 14:36:29 2020 +0200

    SLING-9415 : Mvn id instead of path used to store artifacts
---
 .../sling/installer/factory/model/impl/InstallFeatureModelTask.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index c3519aa..9d62540 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -117,7 +117,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
     }
 
     private File getArtifactFile(final File baseDir, final ArtifactId id) {
-        return new File(baseDir, id.toMvnId().replace('/', File.separatorChar));
+        return new File(baseDir, id.toMvnPath().replace('/', File.separatorChar));
     }
 
     private List<InstallableResource> transform(final String featureJson,


[sling-org-apache-sling-installer-factory-feature] 25/32: [maven-release-plugin] prepare for next development iteration

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 8a9eff8391a1b163c5edba513d70d334ad143219
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 25 12:15:01 2020 +0200

    [maven-release-plugin] prepare for next development iteration
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index f7f1b07..507b9fa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.4.0</version>
+    <version>0.4.1-SNAPSHOT</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 


[sling-org-apache-sling-installer-factory-feature] 03/32: Support multiple features per archive and allow for selection through pattern

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit fed02f0bd831f2bb44b2b3641da21d47b4f985d6
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun Feb 23 17:34:30 2020 +0100

    Support multiple features per archive and allow for selection through pattern
---
 pom.xml                                            |  11 ++
 .../model/impl/FeatureModelInstallerPlugin.java    | 121 +++++++++++++-----
 .../factory/model/impl/InstallContext.java         |  50 ++++++++
 .../model/impl/InstallFeatureModelTask.java        | 141 +++++++++------------
 .../model/impl/UninstallFeatureModelTask.java      |   7 -
 .../impl/FeatureModelInstallerPluginTest.java      |  70 ++++++++++
 6 files changed, 278 insertions(+), 122 deletions(-)

diff --git a/pom.xml b/pom.xml
index 815d242..5991eae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -115,6 +115,17 @@
             <version>1.3.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
+   <!-- Testing -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>2.15.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index 69df21f..3023feb 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -19,11 +19,13 @@
 package org.apache.sling.installer.factory.model.impl;
 
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.StringWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -32,6 +34,8 @@ import java.util.Map;
 import java.util.regex.Pattern;
 
 import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.builder.BuilderContext;
+import org.apache.sling.feature.builder.FeatureBuilder;
 import org.apache.sling.feature.io.archive.ArchiveReader;
 import org.apache.sling.feature.io.artifacts.ArtifactManager;
 import org.apache.sling.feature.io.artifacts.ArtifactManagerConfig;
@@ -78,7 +82,8 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
         @AttributeDefinition(name = "Repository URLs", description = "Additional repository URLs to fetch artifacts")
         String[] repositories();
 
-        @AttributeDefinition(name = "Classifier Patterns", description = "Patterns for selecting the features to handle based on the classifier. Without a configuration all features are handled.")
+        @AttributeDefinition(name = "Classifier Patterns", description = "Patterns for selecting the features to handle based on the classifier. Without a configuration all features are handled."
+                + " The patterns can use an asteriks to match any characters in the classifier. The special token ':' can be used to match the empty classifier.")
         String[] classifierPatterns();
     }
 
@@ -88,8 +93,6 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
 
     public static final String ATTR_MODEL = "feature";
 
-    public static final String ATTR_BASE_PATH = "path";
-
     public static final String ATTR_ID = "featureId";
 
     /** Logger. */
@@ -108,27 +111,38 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
 
     private final ArtifactManager artifactManager;
 
-    private final List<String> classifierPatterns = new ArrayList<>();
+    private final List<Pattern> classifierPatterns = new ArrayList<>();
+
+    private final File storageDirectory;
 
     @Activate
     public FeatureModelInstallerPlugin(final BundleContext ctx, final Config config) throws IOException {
         this.bundleContext = ctx;
+        this.storageDirectory = this.bundleContext.getDataFile("repository");
         final ArtifactManagerConfig amCfg = new ArtifactManagerConfig();
         amCfg.setUseMvn(config.useMvn());
+        final List<String> repos = new ArrayList<>(Arrays.asList(amCfg.getRepositoryUrls()));
+        if (this.storageDirectory != null) {
+            repos.add(this.storageDirectory.toURI().toURL().toExternalForm());
+        }
         if (config.repositories() != null && config.repositories().length > 0) {
-            final List<String> repos = new ArrayList<>(Arrays.asList(amCfg.getRepositoryUrls()));
             for (final String r : config.repositories()) {
                 if (!r.trim().isEmpty()) {
                     repos.add(r);
                 }
             }
-            amCfg.setRepositoryUrls(repos.toArray(new String[repos.size()]));
         }
+        amCfg.setRepositoryUrls(repos.toArray(new String[repos.size()]));
+
         this.artifactManager = ArtifactManager.getArtifactManager(amCfg);
         if (config.classifierPatterns() != null) {
             for (final String text : config.classifierPatterns()) {
                 if (text != null && !text.trim().isEmpty()) {
-                    classifierPatterns.add(text.trim());
+                    if (":".equals(text.trim())) {
+                        classifierPatterns.add(Pattern.compile("^$"));
+                    } else {
+                        classifierPatterns.add(Pattern.compile(toRegexPattern(text.trim())));
+                    }
                 }
             }
         }
@@ -137,7 +151,6 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
     @Override
     public TransformationResult[] transform(final RegisteredResource resource) {
         final List<Feature> features = new ArrayList<>();
-        File baseDir = null;
         if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(FILE_EXTENSION)) {
             try (final Reader reader = new InputStreamReader(resource.getInputStream(), "UTF-8")) {
                 features.add(FeatureJSONReader.read(reader, resource.getURL()));
@@ -146,7 +159,6 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
             }
         }
         if (resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(".zip")) {
-            baseDir = this.bundleContext.getDataFile("");
             try (final InputStream is = resource.getInputStream()) {
                 features.addAll(ArchiveReader.read(is, null));
             } catch (final IOException ioe) {
@@ -154,28 +166,36 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
             }
         }
         if (!features.isEmpty()) {
-            boolean error = false;
-            final List<TransformationResult> result = new ArrayList<>();
-            for (final Feature feature : features) {
-                boolean select = this.classifierPatterns.isEmpty();
-                if (!select) {
-                    for (final String pattern : this.classifierPatterns) {
-                        if (":".equals(pattern)) {
-                            select = feature.getId().getClassifier() == null;
-                        } else if (feature.getId().getClassifier() != null) {
-                            select = Pattern.compile(pattern).matcher(feature.getId().getClassifier()).matches();
-                        }
-
-                        if (select) {
-                            break;
+            // persist all features to the file system
+            if (this.storageDirectory != null) {
+                for (Feature feature : features) {
+                    final File featureFile = new File(this.storageDirectory,
+                            feature.getId().toMvnPath().replace('/', File.separatorChar));
+                    if (!featureFile.exists()) {
+                        featureFile.getParentFile().mkdirs();
+                        try (final Writer writer = new FileWriter(featureFile)) {
+                            FeatureJSONWriter.write(writer, feature);
+                        } catch (final IOException ioe) {
+                            logger.error("Unable to write feature to " + featureFile + ":" + ioe.getMessage(), ioe);
                         }
                     }
                 }
+            }
 
-                if (!select) {
+            boolean error = false;
+            final List<TransformationResult> result = new ArrayList<>();
+            for (Feature feature : features) {
+                if (!classifierMatches(feature.getId().getClassifier())) {
                     continue;
                 }
 
+                // assemble feature now
+                if (!feature.isAssembled()) {
+                    final BuilderContext ctx = new BuilderContext(this.artifactManager.toFeatureProvider());
+                    ctx.setArtifactProvider(this.artifactManager);
+                    feature = FeatureBuilder.assemble(feature, ctx);
+                }
+
                 String featureJson = null;
                 try (final StringWriter sw = new StringWriter()) {
                     FeatureJSONWriter.write(sw, feature);
@@ -193,10 +213,7 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
                     final Map<String, Object> attributes = new HashMap<>();
                     attributes.put(ATTR_MODEL, featureJson);
                     attributes.put(ATTR_ID, feature.getId().toMvnId());
-                    if (baseDir != null) {
-                        final File dir = new File(baseDir, feature.getId().toMvnName());
-                        attributes.put(ATTR_BASE_PATH, dir.getAbsolutePath());
-                    }
+
                     tr.setAttributes(attributes);
 
                     result.add(tr);
@@ -221,10 +238,50 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
         if (rsrc.getState() == ResourceState.UNINSTALL ) {
             return new UninstallFeatureModelTask(group, bundleContext);
         }
+        final InstallContext ctx = new InstallContext(this.repository, this.repoInitProcessor, this.repoInitParser,
+                this.artifactManager, this.storageDirectory);
         return new InstallFeatureModelTask(group,
-                this.repository,
-                this.repoInitProcessor,
-                this.repoInitParser,
-                this.bundleContext, this.artifactManager);
+                ctx, this.bundleContext);
+    }
+
+    boolean classifierMatches(String classifier) {
+        boolean select = this.classifierPatterns.isEmpty();
+        if (!select) {
+            if (classifier == null) {
+                classifier = "";
+            }
+            for (final Pattern pattern : this.classifierPatterns) {
+                select = pattern.matcher(classifier).matches();
+
+                if (select) {
+                    break;
+                }
+            }
+        }
+        return select;
+    }
+
+    private static String toRegexPattern(String pattern) {
+        StringBuilder stringBuilder = new StringBuilder("^");
+        int index = 0;
+        while (index < pattern.length()) {
+            char currentChar = pattern.charAt(index++);
+            switch (currentChar) {
+            case '*':
+                stringBuilder.append("[^/]*");
+                break;
+            default:
+                if (isRegexMeta(currentChar)) {
+                    stringBuilder.append(Pattern.quote(Character.toString(currentChar)));
+                } else {
+                    stringBuilder.append(currentChar);
+                }
+            }
+        }
+        return stringBuilder.append('$').toString();
+    }
+
+    private static boolean isRegexMeta(char character) {
+        return "<([{\\^-=$!|]})?*+.>".indexOf(character) != -1;
     }
 }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
new file mode 100644
index 0000000..0af42fa
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallContext.java
@@ -0,0 +1,50 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import java.io.File;
+
+import org.apache.sling.feature.io.artifacts.ArtifactManager;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
+import org.apache.sling.repoinit.parser.RepoInitParser;
+
+public class InstallContext {
+
+    public final SlingRepository repository;
+
+    public final JcrRepoInitOpsProcessor repoInitProcessor;
+
+    public final RepoInitParser repoInitParser;
+
+    public final ArtifactManager artifactManager;
+
+    public final File storageDirectory;
+
+    public InstallContext(final SlingRepository repository,
+            final JcrRepoInitOpsProcessor repoInitProcessor,
+            final RepoInitParser repoInitParser,
+            final ArtifactManager artifactManager, final File storageDirectory) {
+        this.repository = repository;
+        this.repoInitProcessor = repoInitProcessor;
+        this.repoInitParser = repoInitParser;
+        this.artifactManager = artifactManager;
+        this.storageDirectory = storageDirectory;
+    }
+}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index 3dde406..34572c4 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -43,7 +43,6 @@ import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.io.archive.ArchiveReader;
 import org.apache.sling.feature.io.artifacts.ArtifactHandler;
-import org.apache.sling.feature.io.artifacts.ArtifactManager;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.OsgiInstaller;
@@ -51,9 +50,6 @@ import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.apache.sling.installer.api.tasks.ResourceState;
 import org.apache.sling.installer.api.tasks.TaskResource;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
-import org.apache.sling.repoinit.parser.RepoInitParser;
 import org.apache.sling.repoinit.parser.RepoInitParsingException;
 import org.apache.sling.repoinit.parser.operations.Operation;
 import org.osgi.framework.BundleContext;
@@ -63,24 +59,12 @@ import org.osgi.framework.BundleContext;
  */
 public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
-    private final SlingRepository repository;
-
-    private final JcrRepoInitOpsProcessor repoInitProcessor;
-
-    private final RepoInitParser repoInitParser;
-
-    private final ArtifactManager artifactManager;
+    private final InstallContext installContext;
 
     public InstallFeatureModelTask(final TaskResourceGroup group,
-            final SlingRepository repository,
-            final JcrRepoInitOpsProcessor repoInitProcessor,
-            final RepoInitParser repoInitParser,
-            final BundleContext bundleContext, final ArtifactManager artifactManager) {
+            final InstallContext installContext, final BundleContext bundleContext) {
         super(group, bundleContext);
-        this.repository = repository;
-        this.repoInitProcessor = repoInitProcessor;
-        this.repoInitParser = repoInitParser;
-        this.artifactManager = artifactManager;
+        this.installContext = installContext;
     }
 
     @SuppressWarnings("deprecation")
@@ -94,68 +78,59 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                 ctx.log("Unable to install feature model resource {} : no model found", resource);
                 this.getResourceGroup().setFinishState(ResourceState.IGNORED);
             } else {
-                final String path = (String) resource.getAttribute(FeatureModelInstallerPlugin.ATTR_BASE_PATH);
-                final File baseDir = (path == null ? null : new File(path));
-
                 boolean success = false;
-                try {
-                    final Result result = this.transform(featureJson, resource, baseDir);
-                    if ( result == null ) {
-                        ctx.log("Unable to install feature model resource {} : unable to create resources", resource);
-                        this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                    } else {
-                        // repo init first
-                        if ( result.repoinit != null ) {
-                            List<Operation> ops = null;
-                            try ( final Reader r = new StringReader(result.repoinit) ) {
-                                ops = this.repoInitParser.parse(r);
-                            } catch (final IOException | RepoInitParsingException e) {
-                                logger.error("Unable to parse repoinit text.", e);
-                                ctx.log("Unable to install feature model resource {} : unable parse repoinit text.",
-                                        resource);
-                                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                                return;
-                            }
+                final Result result = this.transform(featureJson, resource);
+                if (result == null) {
+                    ctx.log("Unable to install feature model resource {} : unable to create resources", resource);
+                    this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                } else {
+                    // repo init first
+                    if (result.repoinit != null) {
+                        List<Operation> ops = null;
+                        try (final Reader r = new StringReader(result.repoinit)) {
+                            ops = this.installContext.repoInitParser.parse(r);
+                        } catch (final IOException | RepoInitParsingException e) {
+                            logger.error("Unable to parse repoinit text.", e);
+                            ctx.log("Unable to install feature model resource {} : unable parse repoinit text.",
+                                    resource);
+                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                            return;
+                        }
 
-                            // login admin is required for repo init
-                            Session session = null;
-                            try {
-                                session = this.repository.loginAdministrative(null);
-                                this.repoInitProcessor.apply(session, ops);
-                                session.save();
-                            } catch ( final RepositoryException re) {
-                                logger.error("Unable to process repoinit text.", re);
-                                ctx.log("Unable to install feature model resource {} : unable to process repoinit text.",
-                                        resource);
-                                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                                return;
+                        // login admin is required for repo init
+                        Session session = null;
+                        try {
+                            session = this.installContext.repository.loginAdministrative(null);
+                            this.installContext.repoInitProcessor.apply(session, ops);
+                            session.save();
+                        } catch (final RepositoryException re) {
+                            logger.error("Unable to process repoinit text.", re);
+                            ctx.log("Unable to install feature model resource {} : unable to process repoinit text.",
+                                    resource);
+                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                            return;
 
-                            } finally {
-                                if ( session != null ) {
-                                    session.logout();
-                                }
+                        } finally {
+                            if (session != null) {
+                                session.logout();
                             }
                         }
-                        if ( !result.resources.isEmpty() ) {
-                            final OsgiInstaller installer = this.getService(OsgiInstaller.class);
-                            if ( installer != null ) {
-                                installer.registerResources(
-                                        "model-" + resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID),
-                                        result.resources.toArray(new InstallableResource[result.resources.size()]));
-                            } else {
-                                ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
-                                        resource);
-                                this.getResourceGroup().setFinishState(ResourceState.IGNORED);
-                                return;
-                            }
-                        }
-                        this.getResourceGroup().setFinishState(ResourceState.INSTALLED);
-                        success = true;
                     }
-                } finally {
-                    if ( !success && baseDir != null ) {
-                        this.deleteDirectory(baseDir);
+                    if (!result.resources.isEmpty()) {
+                        final OsgiInstaller installer = this.getService(OsgiInstaller.class);
+                        if (installer != null) {
+                            installer.registerResources(
+                                    "model-" + resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID),
+                                    result.resources.toArray(new InstallableResource[result.resources.size()]));
+                        } else {
+                            ctx.log("Unable to install feature model resource {} : unable to get OSGi installer",
+                                    resource);
+                            this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+                            return;
+                        }
                     }
+                    this.getResourceGroup().setFinishState(ResourceState.INSTALLED);
+                    success = true;
                 }
                 if ( success ) {
                     ctx.log("Installed {}", resource.getEntityId());
@@ -176,8 +151,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
     }
 
     private Result transform(final String featureJson,
-            final TaskResource rsrc,
-            final File baseDir) {
+            final TaskResource rsrc) {
         Feature feature = null;
         try (final Reader reader = new StringReader(featureJson)) {
             feature = FeatureJSONReader.read(reader, null);
@@ -188,7 +162,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             return null;
         }
 
-        if ( baseDir != null ) {
+        if (this.installContext.storageDirectory != null) {
             // extract artifacts
             final byte[] buffer = new byte[1024*1024*256];
 
@@ -197,7 +171,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
                     @Override
                     public void consume(final ArtifactId id, final InputStream is) throws IOException {
-                        final File artifactFile = getArtifactFile(baseDir, id);
+                        final File artifactFile = getArtifactFile(installContext.storageDirectory, id);
                         if (!artifactFile.exists()) {
                             artifactFile.getParentFile().mkdirs();
                             try (final OutputStream os = new FileOutputStream(artifactFile)) {
@@ -218,14 +192,14 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
         final Result result = new Result();
         for (final Artifact bundle : feature.getBundles()) {
-            if (!addArtifact(baseDir, bundle, result)) {
+            if (!addArtifact(bundle, result)) {
                 return null;
             }
         }
         final Extension ext = feature.getExtensions().getByName(Extension.EXTENSION_NAME_CONTENT_PACKAGES);
         if (ext != null && ext.getType() == ExtensionType.ARTIFACTS) {
             for (final Artifact artifact : ext.getArtifacts()) {
-                addArtifact(baseDir, artifact, result);
+                addArtifact(artifact, result);
             }
         }
 
@@ -241,13 +215,14 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
         return result;
     }
 
-    private boolean addArtifact(final File baseDir, final Artifact artifact,
+    private boolean addArtifact(final Artifact artifact,
             final Result result) {
-        File artifactFile = (baseDir == null ? null : getArtifactFile(baseDir, artifact.getId()));
+        File artifactFile = (this.installContext.storageDirectory == null ? null
+                : getArtifactFile(this.installContext.storageDirectory, artifact.getId()));
         ArtifactHandler handler;
         if (artifactFile == null || !artifactFile.exists()) {
             try {
-                handler = this.artifactManager.getArtifactHandler(artifact.getId().toMvnUrl());
+                handler = this.installContext.artifactManager.getArtifactHandler(artifact.getId().toMvnUrl());
             } catch (final IOException ignore) {
                 return false;
             }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
index b584e6d..d734e4a 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallFeatureModelTask.java
@@ -18,8 +18,6 @@
  */
 package org.apache.sling.installer.factory.model.impl;
 
-import java.io.File;
-
 import org.apache.sling.installer.api.OsgiInstaller;
 import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.apache.sling.installer.api.tasks.ResourceState;
@@ -48,11 +46,6 @@ public class UninstallFeatureModelTask extends AbstractFeatureModelTask {
                 ctx.log("Uninstalling {}", resource.getEntityId());
                 installer.registerResources("model-" + resource.getAttribute(FeatureModelInstallerPlugin.ATTR_ID),
                         null);
-                final String path = (String) resource.getAttribute(FeatureModelInstallerPlugin.ATTR_BASE_PATH);
-                if ( path != null ) {
-                    final File dir = new File(path);
-                    deleteDirectory(dir);
-                }
                 this.getResourceGroup().setFinishState(ResourceState.UNINSTALLED);
                 ctx.log("Uninstalled {}", resource.getEntityId());
             }
diff --git a/src/test/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPluginTest.java b/src/test/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPluginTest.java
new file mode 100644
index 0000000..04c7eda
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPluginTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+
+public class FeatureModelInstallerPluginTest {
+
+    @Test
+    public void testNoPatterns() throws Exception {
+        final FeatureModelInstallerPlugin.Config config = Mockito.mock(FeatureModelInstallerPlugin.Config.class);
+        Mockito.when(config.classifierPatterns()).thenReturn(null);
+
+        final FeatureModelInstallerPlugin plugin = new FeatureModelInstallerPlugin(Mockito.mock(BundleContext.class),
+                config);
+        assertTrue(plugin.classifierMatches("foo"));
+        assertTrue(plugin.classifierMatches(null));
+    }
+
+    @Test
+    public void testNoClassifierPattern() throws Exception {
+        final FeatureModelInstallerPlugin.Config config = Mockito.mock(FeatureModelInstallerPlugin.Config.class);
+        Mockito.when(config.classifierPatterns()).thenReturn(new String[] { ":" });
+
+        final FeatureModelInstallerPlugin plugin = new FeatureModelInstallerPlugin(Mockito.mock(BundleContext.class),
+                config);
+        assertFalse(plugin.classifierMatches("foo"));
+        assertTrue(plugin.classifierMatches(null));
+    }
+
+    @Test
+    public void tesClassifierPatterns() throws Exception {
+        final FeatureModelInstallerPlugin.Config config = Mockito.mock(FeatureModelInstallerPlugin.Config.class);
+        Mockito.when(config.classifierPatterns()).thenReturn(new String[] { ":", "*devfar", "*prodfar", "*special*" });
+
+        final FeatureModelInstallerPlugin plugin = new FeatureModelInstallerPlugin(Mockito.mock(BundleContext.class),
+                config);
+
+        assertTrue(plugin.classifierMatches(null));
+        assertTrue(plugin.classifierMatches("mydevfar"));
+        assertTrue(plugin.classifierMatches("myprodfar"));
+        assertTrue(plugin.classifierMatches("superspecialfar"));
+        assertTrue(plugin.classifierMatches("evenmorespecial"));
+
+        assertFalse(plugin.classifierMatches("foo"));
+        assertFalse(plugin.classifierMatches("devmyfar"));
+        assertFalse(plugin.classifierMatches("prodmfar"));
+    }
+}


[sling-org-apache-sling-installer-factory-feature] 31/32: Explicitly use dynamic, greedy reference

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 5d5f715b291f3d5de73ca7de2245d8fa4e0ff3b1
Author: David Bosschaert <da...@apache.org>
AuthorDate: Tue Sep 1 15:36:56 2020 +0100

    Explicitly use dynamic, greedy reference
---
 .../installer/factory/model/impl/FeatureModelInstallerPlugin.java     | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index a3f5039..2086bdb 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -55,6 +55,8 @@ import org.osgi.framework.BundleContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -104,7 +106,7 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
 
     private final File storageDirectory;
 
-    @Reference
+    @Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY)
     private volatile List<ExtensionHandler> extensionHandlers;
 
     @Activate


[sling-org-apache-sling-installer-factory-feature] 29/32: SLING-9658 Support binary archives in .far files

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 34e639d625746627ec81e34877e5cf8b36317841
Author: David Bosschaert <da...@apache.org>
AuthorDate: Tue Sep 1 14:52:41 2020 +0100

    SLING-9658 Support binary archives in .far files
    
    New extension handler service API added.
    InstallFeatureModelTask that uses these services to handle extensions.
    Additionalservices are provided by the unpack extension to provide binary support.
---
 bnd.bnd                                            |   2 +-
 pom.xml                                            |  31 +++-
 .../feature/spi/context/ExtensionHandler.java      |  37 +++++
 .../spi/context/ExtensionHandlerContext.java       |  61 +++++++
 .../sling/feature/spi/context/package-info.java    |  22 +++
 .../model/impl/APIRegionsExtensionHandler.java     |  74 +++++++++
 .../model/impl/FeatureModelInstallerPlugin.java    |  10 +-
 .../model/impl/InstallFeatureModelTask.java        | 164 ++++++++++++-------
 .../model/impl/RepoinitExtensionHandler.java       |  51 ++++++
 .../model/impl/APIRegionsExtensionHandlerTest.java |  71 +++++++++
 .../model/impl/InstallFeatureModelTaskTest.java    | 177 +++++++++++++++++++++
 .../model/impl/RepoinitExtensionHandlerTest.java   |  68 ++++++++
 src/test/resources/test2/test2.far                 | Bin 0 -> 103630 bytes
 src/test/resources/test2/test2.slingosgifeature    |  10 ++
 14 files changed, 714 insertions(+), 64 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
index d2c832f..3e6776b 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -1,2 +1,2 @@
 -includeresource: @org.apache.sling.feature.extension.apiregions-[0-9.]*.jar!/org/apache/sling/feature/extension/apiregions/launcher/LauncherProperties.*
-Conditional-Package: org.apache.sling.feature.extension.apiregions.api
+Conditional-Package: org.apache.sling.feature.extension.apiregions.api,org.apache.felix.utils.manifest
diff --git a/pom.xml b/pom.xml
index 507b9fa..ff8c46a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,16 @@
                     <skip>true</skip>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>src/test/resources/**/*.slingosgifeature</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            
         </plugins>
     </build>
 
@@ -93,7 +103,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature</artifactId>
-            <version>1.2.0</version>
+            <version>1.2.4</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -102,6 +112,13 @@
             <version>1.1.4</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.utils</artifactId>
+            <version>1.11.4</version>
+            <scope>provided</scope>
+        </dependency>
+        
    <!-- Testing -->
         <dependency>
             <groupId>junit</groupId>
@@ -113,6 +130,18 @@
             <version>3.3.0</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.johnzon</groupId>
+            <artifactId>johnzon-core</artifactId>
+            <version>1.2.8</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.cm.json</artifactId>
+            <version>1.0.2</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/src/main/java/org/apache/sling/feature/spi/context/ExtensionHandler.java b/src/main/java/org/apache/sling/feature/spi/context/ExtensionHandler.java
new file mode 100644
index 0000000..da4ad62
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/spi/context/ExtensionHandler.java
@@ -0,0 +1,37 @@
+/*
+ * 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.spi.context;
+
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.Feature;
+
+/**
+ * Service interface to handle feature model extensions in the feature installer
+ */
+public interface ExtensionHandler {
+    /**
+     * Called on registered services when an extension is encountered
+     * @param context The extension context
+     * @param extension The extension to be handled
+     * @param feature The feature that contains the extension
+     * @return Returns {@code true} if this extension handler can handle the presented extension.
+     * @throws Exception If something goes wrong.
+     */
+    public boolean handle(ExtensionHandlerContext context, Extension extension, Feature feature) throws Exception;
+}
diff --git a/src/main/java/org/apache/sling/feature/spi/context/ExtensionHandlerContext.java b/src/main/java/org/apache/sling/feature/spi/context/ExtensionHandlerContext.java
new file mode 100644
index 0000000..384279e
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/spi/context/ExtensionHandlerContext.java
@@ -0,0 +1,61 @@
+/*
+ * 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.spi.context;
+
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.builder.ArtifactProvider;
+
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Map;
+
+/**
+ * This context is provided with calls to {@link ExtensionHandler} services.
+ */
+public interface ExtensionHandlerContext {
+    /**
+     * Add a bundle to be installed by the launcher.
+     * @param id The bundle's artifact ID
+     * @param startLevel The start level for the bundle.
+     * @param file The file with the bundle.
+     */
+    public void addBundle(ArtifactId id, URL file, Integer startLevel);
+
+    /**
+     * Add an artifact to be installed by the launcher
+     * @param id The artifact's ID
+     * @param url The url to the Artifact resource
+     * @param props Additional installation metadata
+     */
+    public void addInstallableArtifact(ArtifactId id, final URL url, final Map<String,Object> props);
+
+    /**
+     * Add a configuration to be installed by the launcher
+     * @param pid The pid
+     * @param factoryPid The factory pid
+     * @param properties The propertis
+     */
+    public void addConfiguration(final String pid, final String factoryPid, final Dictionary<String, Object> properties);
+
+    /**
+     * Obtain the artifact provider.
+     * @return The artifact provider.
+     */
+    public ArtifactProvider getArtifactProvider();
+}
diff --git a/src/main/java/org/apache/sling/feature/spi/context/package-info.java b/src/main/java/org/apache/sling/feature/spi/context/package-info.java
new file mode 100644
index 0000000..8d0d1e1
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/spi/context/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+@org.osgi.annotation.versioning.ProviderType
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.sling.feature.spi.context;
+
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandler.java b/src/main/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandler.java
new file mode 100644
index 0000000..619540d
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandler.java
@@ -0,0 +1,74 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.extension.apiregions.api.ApiRegions;
+import org.apache.sling.feature.extension.apiregions.launcher.LauncherProperties;
+import org.apache.sling.feature.spi.context.ExtensionHandler;
+import org.apache.sling.feature.spi.context.ExtensionHandlerContext;
+import org.osgi.service.component.annotations.Component;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+@Component
+public class APIRegionsExtensionHandler implements ExtensionHandler {
+    private static final String REGION_FACTORY_PID = "org.apache.sling.feature.apiregions.factory~";
+
+    private static final String PROP_idbsnver = "mapping.bundleid.bsnver";
+    private static final String PROP_bundleFeatures = "mapping.bundleid.features";
+    private static final String PROP_featureRegions = "mapping.featureid.regions";
+    private static final String PROP_regionPackage = "mapping.region.packages";
+
+    @Override
+    public boolean handle(ExtensionHandlerContext context, Extension extension, Feature feature) throws Exception {
+        if (!extension.getName().equals(ApiRegions.EXTENSION_NAME) ||
+                extension.getType() != ExtensionType.JSON) {
+            return false;
+        }
+
+        final ApiRegions regions = ApiRegions.parse(extension.getJSONStructure().asJsonArray());
+
+        final String configPid = REGION_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
+        final Dictionary<String, Object> props = new Hashtable<>();
+        props.put(PROP_idbsnver, convert(LauncherProperties.getBundleIDtoBSNandVersionMap(feature, context.getArtifactProvider())));
+        props.put(PROP_bundleFeatures, convert(LauncherProperties.getBundleIDtoFeaturesMap(feature)));
+        props.put(PROP_featureRegions, convert(LauncherProperties.getFeatureIDtoRegionsMap(regions)));
+        props.put(PROP_regionPackage, convert(LauncherProperties.getRegionNametoPackagesMap(regions)));
+
+        context.addConfiguration(null, configPid, props);
+        return true;
+    }
+
+    private String[] convert(final Properties props) {
+        final List<String> result = new ArrayList<>();
+
+        for(final Map.Entry<Object, Object> entry : props.entrySet()) {
+            result.add(entry.getKey().toString().concat("=").concat(entry.getValue().toString()));
+        }
+        return result.toArray(new String[result.size()]);
+    }
+}
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index eaec3c5..a3f5039 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -41,6 +41,7 @@ import org.apache.sling.feature.io.artifacts.ArtifactManager;
 import org.apache.sling.feature.io.artifacts.ArtifactManagerConfig;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
 import org.apache.sling.feature.io.json.FeatureJSONWriter;
+import org.apache.sling.feature.spi.context.ExtensionHandler;
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.tasks.InstallTask;
 import org.apache.sling.installer.api.tasks.InstallTaskFactory;
@@ -53,6 +54,7 @@ import org.apache.sling.installer.api.tasks.TransformationResult;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -102,6 +104,9 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
 
     private final File storageDirectory;
 
+    @Reference
+    private volatile List<ExtensionHandler> extensionHandlers;
+
     @Activate
     public FeatureModelInstallerPlugin(final BundleContext ctx, final Config config) throws IOException {
         this.bundleContext = ctx;
@@ -180,6 +185,9 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
                 if (!feature.isAssembled()) {
                     final BuilderContext ctx = new BuilderContext(this.artifactManager.toFeatureProvider());
                     ctx.setArtifactProvider(this.artifactManager);
+
+                    // Set all merge extensions here from the service registry?
+
                     feature = FeatureBuilder.assemble(feature, ctx);
                 }
 
@@ -229,7 +237,7 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
         }
         final InstallContext ctx = new InstallContext(this.artifactManager, this.storageDirectory);
         return new InstallFeatureModelTask(group,
-                ctx, this.bundleContext);
+                ctx, this.bundleContext, this.extensionHandlers);
     }
 
     boolean classifierMatches(String classifier) {
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index a63ff6b..1d7c925 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -26,13 +26,13 @@ import java.io.OutputStream;
 import java.io.Reader;
 import java.io.StringReader;
 import java.net.MalformedURLException;
+import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
@@ -40,11 +40,12 @@ import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.extension.apiregions.api.ApiRegions;
-import org.apache.sling.feature.extension.apiregions.launcher.LauncherProperties;
+import org.apache.sling.feature.builder.ArtifactProvider;
 import org.apache.sling.feature.io.archive.ArchiveReader;
 import org.apache.sling.feature.io.artifacts.ArtifactHandler;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.spi.context.ExtensionHandler;
+import org.apache.sling.feature.spi.context.ExtensionHandlerContext;
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.OsgiInstaller;
 import org.apache.sling.installer.api.tasks.InstallationContext;
@@ -52,27 +53,20 @@ import org.apache.sling.installer.api.tasks.ResourceState;
 import org.apache.sling.installer.api.tasks.TaskResource;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 
 /**
  * This task installs a feature model resources.
  */
 public class InstallFeatureModelTask extends AbstractFeatureModelTask {
-
-    private static final String PROP_idbsnver = "mapping.bundleid.bsnver";
-    private static final String PROP_bundleFeatures = "mapping.bundleid.features";
-    private static final String PROP_featureRegions = "mapping.featureid.regions";
-    private static final String PROP_regionPackage = "mapping.region.packages";
-
-    private static final String REGION_FACTORY_PID = "org.apache.sling.feature.apiregions.factory~";
-    private static final String REPOINIT_FACTORY_PID = "org.apache.sling.jcr.repoinit.RepositoryInitializer~";
-
     private final InstallContext installContext;
+    private final List<ExtensionHandler> extensionHandlers;
 
     public InstallFeatureModelTask(final TaskResourceGroup group,
-            final InstallContext installContext, final BundleContext bundleContext) {
+            final InstallContext installContext, final BundleContext bundleContext,
+            final List<ExtensionHandler> extensionHandlers) {
         super(group, bundleContext);
         this.installContext = installContext;
+        this.extensionHandlers = extensionHandlers;
     }
 
     @Override
@@ -139,18 +133,6 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
                     cfg.getConfigurationProperties(), null, InstallableResource.TYPE_CONFIG, null));
         }
 
-        // repoinit
-        final Extension repoInit = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
-        if (repoInit != null && repoInit.getType() == ExtensionType.TEXT) {
-            final String configPid = REPOINIT_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
-            final Dictionary<String, Object> props = new Hashtable<>();
-            props.put("scripts", repoInit.getText());
-            props.put(Constants.SERVICE_RANKING, 200);
-
-            result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
-                    props, null, InstallableResource.TYPE_CONFIG, null));
-        }
-
         // extract artifacts
         if (this.installContext.storageDirectory != null) {
             final byte[] buffer = new byte[1024*1024*256];
@@ -178,24 +160,27 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
         }
 
-        // api regions
-        final Extension regionExt = feature.getExtensions().getByName(ApiRegions.EXTENSION_NAME);
-        if ( regionExt != null ) {
-            try {
-                final ApiRegions regions = ApiRegions.parse(regionExt.getJSONStructure().asJsonArray());
-
-                final String configPid = REGION_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
-                final Dictionary<String, Object> props = new Hashtable<>();
-                props.put(PROP_idbsnver, convert(LauncherProperties.getBundleIDtoBSNandVersionMap(feature, this.installContext.artifactManager)));
-                props.put(PROP_bundleFeatures, convert(LauncherProperties.getBundleIDtoFeaturesMap(feature)));
-                props.put(PROP_featureRegions, convert(LauncherProperties.getFeatureIDtoRegionsMap(regions)));
-                props.put(PROP_regionPackage, convert(LauncherProperties.getRegionNametoPackagesMap(regions)));
+        ExtensionHandlerContext context = new ContextImpl(result);
 
-                result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
-                        props, null, InstallableResource.TYPE_CONFIG, null));
-            } catch (final IOException ioe) {
-                logger.warn("Unable to parse region information " + feature.getId().toMvnId(), ioe);
-                return null;
+        for (Extension ext : feature.getExtensions()) {
+            boolean handlerFound = false;
+            for (ExtensionHandler eh : extensionHandlers) {
+                try {
+                    handlerFound |= eh.handle(context, ext, feature);
+                } catch (Exception e) {
+                    logger.error("Exception while processing extension {} with handler {}", ext, eh, e);
+                }
+            }
+            if (!handlerFound) {
+                if (ExtensionType.ARTIFACTS == ext.getType()) {
+                    // Unhandled ARTIFACTS extensions get stored
+                    for (final Artifact artifact : ext.getArtifacts()) {
+                        addArtifact(artifact, result);
+                    }
+                } else {
+                    // should this be an error?
+                    logger.warn("No extension handler found for mandartory extension " + ext);
+                }
             }
         }
 
@@ -206,27 +191,9 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             }
         }
 
-        // artifact extensions
-        for(final Extension ext : feature.getExtensions()) {
-            if ( ext.getType() == ExtensionType.ARTIFACTS ) {
-                for (final Artifact artifact : ext.getArtifacts()) {
-                    addArtifact(artifact, result);
-                }
-            }
-        }
-
         return result;
     }
 
-    private String[] convert(final Properties props) {
-        final List<String> result = new ArrayList<>();
-
-        for(final Map.Entry<Object, Object> entry : props.entrySet()) {
-            result.add(entry.getKey().toString().concat("=").concat(entry.getValue().toString()));
-        }
-        return result.toArray(new String[result.size()]);
-    }
-
     private boolean addArtifact(final Artifact artifact,
             final List<InstallableResource> result) {
         File artifactFile = (this.installContext.storageDirectory == null ? null
@@ -274,4 +241,79 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
     public String getSortKey() {
         return "30-" + getResource().getAttribute(FeatureModelInstallerPlugin.ATTR_ID);
     }
+
+    private ArtifactProvider getLocalArtifactProvider() {
+        // TODO share with addArtifact()
+        return new ArtifactProvider() {
+            @Override
+            public URL provide(ArtifactId id) {
+                File artifactFile = (installContext.storageDirectory == null ? null
+                        : getArtifactFile(installContext.storageDirectory, id));
+                ArtifactHandler handler;
+                if (artifactFile == null || !artifactFile.exists()) {
+                    try {
+                        handler = installContext.artifactManager.getArtifactHandler(id.toMvnUrl());
+                    } catch (final IOException ignore) {
+                        return null;
+                    }
+                } else {
+                    try {
+                        handler = new ArtifactHandler(artifactFile);
+                    } catch (final MalformedURLException e) {
+                        return null;
+                    }
+                }
+                if (handler == null) {
+                    return null;
+                }
+                return handler.getLocalURL();
+            }
+        };
+    }
+
+    private class ContextImpl implements ExtensionHandlerContext {
+        private final List<InstallableResource> results;
+
+        public ContextImpl(List<InstallableResource> results) {
+            this.results = results;
+        }
+
+        @Override
+        public void addBundle(ArtifactId id, URL file, Integer startLevel) {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+        public void addInstallableArtifact(ArtifactId id, URL url, Map<String,Object> props) {
+            try {
+                Dictionary <String,Object> dict = new Hashtable<>();
+                props.entrySet().stream()
+                    .filter(e -> e.getValue() != null)
+                    .forEach(e -> dict.put(e.getKey(), e.getValue()));
+
+                InputStream is = url.openStream();
+                results.add(new InstallableResource("/".concat(id.toMvnName()), is, dict, null /* TODO digest? */,
+                        InstallableResource.TYPE_FILE, null));
+            } catch (IOException e) {
+                logger.warn("Unable to read artifact " + id + " from url " + url, e);
+            }
+        }
+
+        @Override
+        public void addConfiguration(String pid, String factoryPid, Dictionary<String, Object> properties) {
+            // TODO handler factoryPid, is this ok?
+            String cfgPid = pid;
+            if (factoryPid != null) {
+                cfgPid = factoryPid;
+            }
+
+            results.add(new InstallableResource("/".concat(cfgPid).concat(".config"), null,
+                    properties, null, InstallableResource.TYPE_CONFIG, null));
+        }
+
+        @Override
+        public ArtifactProvider getArtifactProvider() {
+            return getLocalArtifactProvider();
+        }
+    }
 }
diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandler.java b/src/main/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandler.java
new file mode 100644
index 0000000..8440df7
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandler.java
@@ -0,0 +1,51 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.spi.context.ExtensionHandler;
+import org.apache.sling.feature.spi.context.ExtensionHandlerContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+@Component
+public class RepoinitExtensionHandler implements ExtensionHandler {
+    private static final String REPOINIT_FACTORY_PID = "org.apache.sling.jcr.repoinit.RepositoryInitializer~";
+
+    @Override
+    public boolean handle(ExtensionHandlerContext context, Extension extension, Feature feature) throws Exception {
+        if (!extension.getName().equals(Extension.EXTENSION_NAME_REPOINIT) ||
+                extension.getType() != ExtensionType.TEXT) {
+            return false;
+        }
+
+        final String configPid = REPOINIT_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
+        final Dictionary<String, Object> props = new Hashtable<>();
+        props.put("scripts", extension.getText());
+        props.put(Constants.SERVICE_RANKING, 200);
+
+        context.addConfiguration(null, configPid, props);
+        return true;
+    }
+}
diff --git a/src/test/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandlerTest.java b/src/test/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandlerTest.java
new file mode 100644
index 0000000..6ffb93d
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/factory/model/impl/APIRegionsExtensionHandlerTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionState;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.spi.context.ExtensionHandlerContext;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class APIRegionsExtensionHandlerTest {
+    private static String FEATURE_EXT_1 =
+            "[" +
+            "   {" +
+            "     \"name\": \"my-region\"," +
+            "     \"exports\": [\"org.foo.bar\", \"la.di.da\"]" +
+            "   }" +
+            "]";
+
+    @Test
+    public void testHandle() throws Exception {
+        APIRegionsExtensionHandler areh = new APIRegionsExtensionHandler();
+
+        ExtensionHandlerContext ctx = Mockito.mock(ExtensionHandlerContext.class);
+
+        Extension ext = new Extension(ExtensionType.JSON, "api-regions", ExtensionState.REQUIRED);
+        ext.setJSON(FEATURE_EXT_1);
+
+        Feature feat = new Feature(ArtifactId.fromMvnId("x:y:8"));
+        assertTrue(areh.handle(ctx, ext, feat));
+
+        Mockito.verify(ctx).addConfiguration(Mockito.isNull(),
+            Mockito.eq("org.apache.sling.feature.apiregions.factory~y_8.jar"),
+            Mockito.argThat(p -> {
+                String[] pkgs = (String[]) p.get("mapping.region.packages");
+                return Arrays.deepEquals(new String [] {"my-region=org.foo.bar,la.di.da"}, pkgs);
+            }));
+    }
+
+    @Test
+    public void testDoesNotHandle() throws Exception {
+        APIRegionsExtensionHandler areh = new APIRegionsExtensionHandler();
+
+        Extension ext = new Extension(ExtensionType.TEXT, "api-regions", ExtensionState.REQUIRED);
+        assertFalse(areh.handle(null, ext, null));
+    }
+}
diff --git a/src/test/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTaskTest.java b/src/test/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTaskTest.java
new file mode 100644
index 0000000..b3afe1a
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTaskTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.io.artifacts.ArtifactManager;
+import org.apache.sling.feature.spi.context.ExtensionHandler;
+import org.apache.sling.feature.spi.context.ExtensionHandlerContext;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+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.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class InstallFeatureModelTaskTest {
+    private static String FEATURE_JSON_1 = "{" +
+            "  \"id\":\"org.apache.sling.someproj:feature:7.0.126\"," +
+            "  \"system-fonts:ARTIFACTS|true\": [" +
+            "    \"org.apache.sling.feature:my-fonts:jar:0.7.1\"" +
+            "  ]," +
+            "  \"blahblahblah:ARTIFACTS|true\": [" +
+            "  ]," +
+            "  \"framework-properties\": {" +
+            "    \"foo\": \"bar\"" + "  }" +
+            "}";
+
+
+    private Path tempDir;
+
+    @Before
+    public void setUp() throws IOException {
+        tempDir = Files.createTempDirectory(getClass().getSimpleName());
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        // Delete the temp dir again
+        Files.walk(tempDir).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
+    }
+
+    @Test
+    public void testTransform() {
+        TaskResource resource = Mockito.mock(TaskResource.class);
+        Mockito.when(resource.getAttribute(FeatureModelInstallerPlugin.ATTR_MODEL)).thenReturn(FEATURE_JSON_1);
+
+        TaskResourceGroup group = Mockito.mock(TaskResourceGroup.class);
+        Mockito.when(group.getActiveResource()).thenReturn(resource);
+
+        InstallContext installContext = new InstallContext(null, null);
+        BundleContext bundleContext = Mockito.mock(BundleContext.class);
+
+        TestExtensionHandler testEH = new TestExtensionHandler("system-fonts", ExtensionType.ARTIFACTS);
+        List<ExtensionHandler> extensionHandlers = Arrays.asList(testEH);
+
+        InstallFeatureModelTask ifmt = new InstallFeatureModelTask(group, installContext, bundleContext, extensionHandlers);
+
+        InstallationContext ctx = Mockito.mock(InstallationContext.class);
+
+        assertEquals("Precondition", 0, testEH.handled.size());
+        assertEquals("Precondition", 0, testEH.notHandled.size());
+
+        ifmt.execute(ctx);
+
+        assertEquals(1, testEH.handled.size());
+        assertEquals("system-fonts", testEH.handled.get(0).getName());
+
+        assertEquals(1, testEH.notHandled.size());
+        assertEquals("blahblahblah", testEH.notHandled.get(0).getName());
+
+        Mockito.verify(group).setFinishState(ResourceState.INSTALLED);
+    }
+
+    @Test
+    public void testTransform2() throws IOException {
+        URL fmRes = getClass().getResource("/test2/test2.slingosgifeature");
+        URL farRes = getClass().getResource("/test2/test2.far");
+
+        String fm = new BufferedReader(new InputStreamReader(fmRes.openStream()))
+                .lines().collect(Collectors.joining("\n"));
+
+        TaskResource resource = Mockito.mock(TaskResource.class);
+        Mockito.when(resource.getAttribute(FeatureModelInstallerPlugin.ATTR_MODEL))
+            .thenReturn(fm);
+        Mockito.when(resource.getInputStream())
+            .thenReturn(farRes.openStream());
+
+        TaskResourceGroup group = Mockito.mock(TaskResourceGroup.class);
+        Mockito.when(group.getActiveResource()).thenReturn(resource);
+
+        ArtifactManager am = Mockito.mock(ArtifactManager.class);
+        InstallContext installContext = new InstallContext(am, tempDir.toFile());
+        BundleContext bundleContext = Mockito.mock(BundleContext.class);
+
+        List<ExtensionHandler> extensionHandlers = Arrays.asList();
+
+        InstallFeatureModelTask ifmt = new InstallFeatureModelTask(group, installContext,
+                bundleContext, extensionHandlers );
+
+        InstallationContext ctx = Mockito.mock(InstallationContext.class);
+
+        ifmt.execute(ctx);
+
+        Path actualJar = tempDir.resolve(
+                "org/apache/felix/org.apache.felix.converter/1.0.14/org.apache.felix.converter-1.0.14.jar");
+        assertTrue(Files.exists(actualJar));
+        assertEquals(116605, Files.size(actualJar));
+
+        Path actualFeatureModel = tempDir.resolve(
+                "org/apache/sling/someproj/feature/3.0.2/feature-3.0.2.slingosgifeature");
+        assertTrue(Files.exists(actualFeatureModel));
+
+        String expectedFM = new String(Files.readAllBytes(new File(fmRes.getFile()).toPath()));
+        assertEquals(expectedFM, new String(Files.readAllBytes(actualFeatureModel)));
+    }
+
+    private static class TestExtensionHandler implements ExtensionHandler {
+        private final String extensionName;
+        private final ExtensionType extensionType;
+        private final List<Extension> handled = new ArrayList<>();
+        private final List<Extension> notHandled = new ArrayList<>();
+
+        private TestExtensionHandler(String name, ExtensionType type) {
+            extensionName = name;
+            extensionType = type;
+        }
+
+        @Override
+        public boolean handle(ExtensionHandlerContext context, Extension extension, Feature feature) throws Exception {
+            if (extensionName.equals(extension.getName()) && extensionType == extension.getType()) {
+
+                handled.add(extension);
+                return true;
+            }
+
+            notHandled.add(extension);
+            return false;
+        }
+    }
+}
diff --git a/src/test/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandlerTest.java b/src/test/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandlerTest.java
new file mode 100644
index 0000000..b557e9b
--- /dev/null
+++ b/src/test/java/org/apache/sling/installer/factory/model/impl/RepoinitExtensionHandlerTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.installer.factory.model.impl;
+
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionState;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.spi.context.ExtensionHandlerContext;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Constants;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class RepoinitExtensionHandlerTest {
+    @Test
+    public void testExtensionHandler() throws Exception {
+        RepoinitExtensionHandler rieh = new RepoinitExtensionHandler();
+
+        ExtensionHandlerContext ctx = Mockito.mock(ExtensionHandlerContext.class);
+        Extension ex = new Extension(ExtensionType.TEXT,
+                Extension.EXTENSION_NAME_REPOINIT, ExtensionState.REQUIRED);
+        ex.setText("hello 123");
+
+        Feature feat = new Feature(ArtifactId.fromMvnId("a:b:1"));
+
+        assertTrue(rieh.handle(ctx, ex, feat));
+
+        Dictionary<String,Object> props = new Hashtable<>();
+        props.put("scripts", "hello 123");
+        props.put(Constants.SERVICE_RANKING, 200);
+
+        Mockito.verify(ctx).addConfiguration(null, "org.apache.sling.jcr.repoinit.RepositoryInitializer~b_1.jar", props);
+    }
+
+    @Test
+    public void testSkipUnrelatedExtensions() throws Exception {
+        RepoinitExtensionHandler rieh = new RepoinitExtensionHandler();
+
+        ExtensionHandlerContext ctx = Mockito.mock(ExtensionHandlerContext.class);
+        assertFalse(rieh.handle(ctx, new Extension(ExtensionType.TEXT,
+                "someother-extension", ExtensionState.REQUIRED), null));
+        assertFalse(rieh.handle(ctx, new Extension(ExtensionType.JSON,
+                Extension.EXTENSION_NAME_REPOINIT, ExtensionState.REQUIRED), null));
+    }
+}
diff --git a/src/test/resources/test2/test2.far b/src/test/resources/test2/test2.far
new file mode 100644
index 0000000..ca8c357
Binary files /dev/null and b/src/test/resources/test2/test2.far differ
diff --git a/src/test/resources/test2/test2.slingosgifeature b/src/test/resources/test2/test2.slingosgifeature
new file mode 100644
index 0000000..9442e7f
--- /dev/null
+++ b/src/test/resources/test2/test2.slingosgifeature
@@ -0,0 +1,10 @@
+{
+  "id":"org.apache.sling.someproj:feature:3.0.2",
+  "bundles": [
+    "org.apache.felix:org.apache.felix.converter:1.0.14"
+  ],
+  "framework-properties": {
+    "foo": "bar"
+  }
+}
+


[sling-org-apache-sling-installer-factory-feature] 17/32: [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.2.0

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 2f52e0085473f001203c83d5ad477ed23866ef4e
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 18:16:09 2020 +0200

    [maven-release-plugin] prepare release org.apache.sling.installer.factory.feature-0.2.0
---
 pom.xml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index d2f1bbb..a28f428 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.1.1-SNAPSHOT</version>
+    <version>0.2.0</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 
@@ -38,6 +38,7 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-feature.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-factory-feature.git</url>
+    <tag>org.apache.sling.installer.factory.feature-0.2.0</tag>
   </scm>
 
     <build>


[sling-org-apache-sling-installer-factory-feature] 18/32: [maven-release-plugin] prepare for next development iteration

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 5ffee984e8e2072729f18812bae196cf3b94fe1a
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 18:16:22 2020 +0200

    [maven-release-plugin] prepare for next development iteration
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index a28f428..b8b9c2c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.installer.factory.feature</artifactId>
-    <version>0.2.0</version>
+    <version>0.2.1-SNAPSHOT</version>
 
     <name>Apache Sling Installer Feature Model Support</name>
     <description> 


[sling-org-apache-sling-installer-factory-feature] 14/32: Convert Properies to String[]

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit a81ba6791d69b94f5a6bcb1cb44ec4c4d8060463
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 16:34:25 2020 +0200

    Convert Properies to String[]
---
 .../factory/model/impl/InstallFeatureModelTask.java   | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index 7dbb111..1570a59 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -31,6 +31,8 @@ import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
+import java.util.Properties;
 
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
@@ -182,10 +184,10 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
 
                 final String configPid = REGION_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
                 final Dictionary<String, Object> props = new Hashtable<>();
-                props.put(PROP_idbsnver, LauncherProperties.getBundleIDtoBSNandVersionMap(feature, this.installContext.artifactManager));
-                props.put(PROP_bundleFeatures, LauncherProperties.getBundleIDtoFeaturesMap(feature));
-                props.put(PROP_featureRegions, LauncherProperties.getFeatureIDtoRegionsMap(regions));
-                props.put(PROP_regionPackage, LauncherProperties.getRegionNametoPackagesMap(regions));
+                props.put(PROP_idbsnver, convert(LauncherProperties.getBundleIDtoBSNandVersionMap(feature, this.installContext.artifactManager)));
+                props.put(PROP_bundleFeatures, convert(LauncherProperties.getBundleIDtoFeaturesMap(feature)));
+                props.put(PROP_featureRegions, convert(LauncherProperties.getFeatureIDtoRegionsMap(regions)));
+                props.put(PROP_regionPackage, convert(LauncherProperties.getRegionNametoPackagesMap(regions)));
 
                 result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
                         props, null, InstallableResource.TYPE_CONFIG, null));
@@ -213,6 +215,15 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
         return result;
     }
 
+    private String[] convert(final Properties props) {
+        final List<String> result = new ArrayList<>();
+
+        for(final Map.Entry<Object, Object> entry : props.entrySet()) {
+            result.add(entry.getKey().toString().concat("=").concat(entry.getValue().toString()));
+        }
+        return result.toArray(new String[result.size()]);
+    }
+
     private boolean addArtifact(final Artifact artifact,
             final List<InstallableResource> result) {
         File artifactFile = (this.installContext.storageDirectory == null ? null


[sling-org-apache-sling-installer-factory-feature] 27/32: Updating badges for org-apache-sling-installer-factory-feature

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 20eeb103ec7bf132f394727bb58c54249c9ac3b9
Author: Radu Cotescu <co...@adobe.com>
AuthorDate: Mon Aug 24 18:47:24 2020 +0200

    Updating badges for org-apache-sling-installer-factory-feature
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 575bee8..68d698a 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 [<img src="https://sling.apache.org/res/logos/sling.png"/>](https://sling.apache.org)
 
- [![Build Status](https://builds.apache.org/buildStatus/icon?job=Sling/sling-org-apache-sling-installer-factory-feature/master)](https://builds.apache.org/job/Sling/job/sling-org-apache-sling-installer-factory-feature/job/master) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![installer](https://sling.apache.org/badges/group-installer.svg)](https://github.com/apache/sling-aggregator/blob/master/docs/groups/installer.md)
+ [![Build Status](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/badge/icon)](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/) [![Test Status](https://img.shields.io/jenkins/tests.svg?jobUrl=https://ci-builds.apache.org/job/Sling/job/modules/job/sling-org-apache-sling-installer-factory-feature/job/master/)](https://ci-builds.apache.org/job/Sling/job/modu [...]
 
 # Apache Sling Installer Feature Model Support
 


[sling-org-apache-sling-installer-factory-feature] 04/32: Disable baseline check as this is a new module

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit 2d8e4a1fd9006d6f54da98e0eb86673a680d4dd5
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 15 15:08:14 2020 +0200

    Disable baseline check as this is a new module
---
 pom.xml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/pom.xml b/pom.xml
index 5991eae..2bcd34a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,13 @@
                     </excludePackageNames>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>biz.aQute.bnd</groupId>
+                <artifactId>bnd-baseline-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 


[sling-org-apache-sling-installer-factory-feature] 16/32: Make sure factory configurations are installed after normal configuration

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit de89896e2da46e5b7347f1fa6573c9d30bd0b029
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 29 18:04:42 2020 +0200

    Make sure factory configurations are installed after normal configuration
---
 .../sling/installer/factory/model/impl/InstallFeatureModelTask.java     | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
index 1570a59..c3519aa 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/InstallFeatureModelTask.java
@@ -52,6 +52,7 @@ import org.apache.sling.installer.api.tasks.ResourceState;
 import org.apache.sling.installer.api.tasks.TaskResource;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 
 /**
  * This task installs a feature model resources.
@@ -144,6 +145,7 @@ public class InstallFeatureModelTask extends AbstractFeatureModelTask {
             final String configPid = REPOINIT_FACTORY_PID.concat(feature.getId().toMvnName().replace('-', '_'));
             final Dictionary<String, Object> props = new Hashtable<>();
             props.put("scripts", repoInit.getText());
+            props.put(Constants.SERVICE_RANKING, 200);
 
             result.add(new InstallableResource("/".concat(configPid).concat(".config"), null,
                     props, null, InstallableResource.TYPE_CONFIG, null));


[sling-org-apache-sling-installer-factory-feature] 30/32: Remove unnecessary dependency

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit d37d3fb57942cb303b11eb81c2b20cf517aebae6
Author: David Bosschaert <da...@apache.org>
AuthorDate: Tue Sep 1 15:32:33 2020 +0100

    Remove unnecessary dependency
---
 bnd.bnd | 2 +-
 pom.xml | 8 +-------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
index 3e6776b..d2c832f 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -1,2 +1,2 @@
 -includeresource: @org.apache.sling.feature.extension.apiregions-[0-9.]*.jar!/org/apache/sling/feature/extension/apiregions/launcher/LauncherProperties.*
-Conditional-Package: org.apache.sling.feature.extension.apiregions.api,org.apache.felix.utils.manifest
+Conditional-Package: org.apache.sling.feature.extension.apiregions.api
diff --git a/pom.xml b/pom.xml
index ff8c46a..eab75bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,14 +112,8 @@
             <version>1.1.4</version>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.utils</artifactId>
-            <version>1.11.4</version>
-            <scope>provided</scope>
-        </dependency>
         
-   <!-- Testing -->
+        <!-- Testing -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>


[sling-org-apache-sling-installer-factory-feature] 23/32: SLING-9470 : Variables in feature model are not replaced on installation

Posted by da...@apache.org.
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-org-apache-sling-installer-factory-feature.git

commit e1528c693f4ab4f0516dfbdedaf7c928333fb653
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 25 12:11:30 2020 +0200

    SLING-9470 : Variables in feature model are not replaced on installation
---
 .../sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
index cc86f97..eaec3c5 100644
--- a/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
+++ b/src/main/java/org/apache/sling/installer/factory/model/impl/FeatureModelInstallerPlugin.java
@@ -183,6 +183,8 @@ public class FeatureModelInstallerPlugin implements InstallTaskFactory, Resource
                     feature = FeatureBuilder.assemble(feature, ctx);
                 }
 
+                FeatureBuilder.resolveVariables(feature, null);
+
                 String featureJson = null;
                 try (final StringWriter sw = new StringWriter()) {
                     FeatureJSONWriter.write(sw, feature);