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 2018/04/25 12:44:26 UTC

[sling-whiteboard] branch master updated: [Sling Feature Model] Refactor FeatureUtil out of the support module

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

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new a865a80  [Sling Feature Model] Refactor FeatureUtil out of the support module
a865a80 is described below

commit a865a801ca60a400db75a0c28b8c740bac30737c
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Wed Apr 25 13:40:18 2018 +0100

    [Sling Feature Model] Refactor FeatureUtil out of the support module
    
    Also move the Resolver API to the resolver module.
---
 featuremodel/feature-analyser/pom.xml              |  8 ++++
 .../apache/sling/feature/analyser/main/Main.java   | 12 ++---
 .../feature/applicationbuilder/impl/Main.java      |  9 ++--
 .../impl/ApplicationBuilderTest.java               |  8 ++--
 .../feature/io/{FileUtils.java => IOUtils.java}    | 44 +++++++++++++++--
 .../io/{FeatureUtilTest.java => IOUtilsTest.java}  |  6 +--
 .../feature/launcher/impl/FeatureProcessor.java    |  8 ++--
 .../modelconverter/impl/FeatureToProvisioning.java | 45 ++++++++---------
 .../modelconverter/impl/ProvisioningToFeature.java |  4 +-
 .../modelconverter/impl/ModelConverterTest.java    | 10 ++--
 .../resolver/ApplicationResolverAssembler.java}    | 56 +++++-----------------
 .../sling/feature}/resolver/FeatureResolver.java   |  2 +-
 .../sling/feature}/resolver/FeatureResource.java   |  2 +-
 .../sling/feature/resolver/FrameworkResolver.java  |  2 -
 .../feature/resolver/impl/BundleResourceImpl.java  |  2 +-
 .../feature/resolver/impl/FeatureResourceImpl.java |  2 +-
 .../sling/feature/resolver}/AnalyserTest.java      | 27 +++++------
 .../feature/resolver/FrameworkResolverTest.java    |  2 -
 .../feature/resolver}/TestBundleResourceImpl.java  |  3 +-
 .../resolver/impl/BundleResourceImplTest.java      |  2 +-
 .../src/test/resources/feature_complete.json       |  0
 .../src/test/resources/feature_incomplete.json     |  0
 .../apache/sling/feature/maven/Preprocessor.java   |  2 +-
 23 files changed, 130 insertions(+), 126 deletions(-)

diff --git a/featuremodel/feature-analyser/pom.xml b/featuremodel/feature-analyser/pom.xml
index a2bca4b..c8e69fa 100644
--- a/featuremodel/feature-analyser/pom.xml
+++ b/featuremodel/feature-analyser/pom.xml
@@ -167,5 +167,13 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <!-- 
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.resolver</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+         -->        
     </dependencies>
 </project>
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java
index 7874afa..79cc35b 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java
@@ -16,19 +16,19 @@
  */
 package org.apache.sling.feature.analyser.main;
 
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-
 import org.apache.sling.feature.Application;
 import org.apache.sling.feature.analyser.Analyser;
 import org.apache.sling.feature.io.ArtifactManagerConfig;
+import org.apache.sling.feature.io.IOUtils;
 import org.apache.sling.feature.io.json.ApplicationJSONReader;
 import org.apache.sling.feature.scanner.Scanner;
-import org.apache.sling.feature.support.FeatureUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
 public class Main {
 
     public static void main(final String[] args) {
@@ -59,7 +59,7 @@ public class Main {
             System.exit(1);
         }
         if ( app.getFramework() == null ) {
-            app.setFramework(FeatureUtil.getFelixFrameworkId(null));
+            app.setFramework(IOUtils.getFelixFrameworkId(null));
         }
 
         try {
diff --git a/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java b/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java
index 58f8e44..d07be10 100644
--- a/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java
+++ b/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java
@@ -26,10 +26,11 @@ import org.apache.sling.feature.Application;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.io.ArtifactManager;
 import org.apache.sling.feature.io.ArtifactManagerConfig;
+import org.apache.sling.feature.io.IOUtils;
 import org.apache.sling.feature.io.json.ApplicationJSONWriter;
+import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
+import org.apache.sling.feature.resolver.FeatureResolver;
 import org.apache.sling.feature.resolver.FrameworkResolver;
-import org.apache.sling.feature.support.FeatureUtil;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -163,7 +164,7 @@ public class Main {
         }
 
         try (FeatureResolver fr = getFeatureResolver(am)) {
-            writeApplication(buildApplication(FeatureUtil.assembleApplication(null, am, fr, files)), output == null ? "application.json" : output);
+            writeApplication(buildApplication(ApplicationResolverAssembler.assembleApplication(null, am, fr, files)), output == null ? "application.json" : output);
 
         } catch ( final IOException ioe) {
             LOGGER.error("Unable to read feature/application files " + ioe.getMessage(), ioe);
@@ -185,7 +186,7 @@ public class Main {
 
         }
         // felix framework hard coded for now
-        app.setFramework(FeatureUtil.getFelixFrameworkId(null));
+        app.setFramework(IOUtils.getFelixFrameworkId(null));
         return app;
     }
 
diff --git a/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java b/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java
index 9426520..c80f485 100644
--- a/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java
+++ b/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java
@@ -48,9 +48,9 @@ import org.apache.sling.feature.io.ArtifactManagerConfig;
 import org.apache.sling.feature.io.json.ApplicationJSONWriter;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
 import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
+import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
+import org.apache.sling.feature.resolver.FeatureResolver;
 import org.apache.sling.feature.resolver.FrameworkResolver;
-import org.apache.sling.feature.support.FeatureUtil;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -88,7 +88,7 @@ public class ApplicationBuilderTest {
         Feature[] features = {fa, fb};
 
         try (FeatureResolver fr = new FrameworkResolver(am, getFrameworkProps())) {
-            Application app = ApplicationBuilder.assemble(null, bc, FeatureUtil.sortFeatures(fr, features));
+            Application app = ApplicationBuilder.assemble(null, bc, ApplicationResolverAssembler.sortFeatures(fr, features));
             String actualJSON = writeApplication(app);
 
             String expectedJSON = "{\"features\":["
@@ -120,7 +120,7 @@ public class ApplicationBuilderTest {
         Feature[] features = {fd, fc};
 
         try (FeatureResolver fr = new FrameworkResolver(am, getFrameworkProps())) {
-            Application app = ApplicationBuilder.assemble(null, bc, FeatureUtil.sortFeatures(fr, features));
+            Application app = ApplicationBuilder.assemble(null, bc, ApplicationResolverAssembler.sortFeatures(fr, features));
             String genApp = writeApplication(app);
 
             String expected = "{\"features\":["
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/FileUtils.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java
similarity index 83%
rename from featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/FileUtils.java
rename to featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java
index a54d933..70af38c 100644
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/FileUtils.java
+++ b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java
@@ -16,7 +16,13 @@
  */
 package org.apache.sling.feature.io;
 
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
+
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.util.ArrayList;
@@ -24,7 +30,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
-public class FileUtils {
+public class IOUtils {
 
     /** The extension for a reference file. */
     public static final String EXTENSION_REF_FILE = ".ref";
@@ -155,8 +161,40 @@ public class FileUtils {
         return paths;
     }
 
-    static final Comparator<String> FEATURE_PATH_COMP = new Comparator<String>() {
+    /**
+     * Read the feature
+     *
+     * @param url The feature url
+     * @param artifactManager The artifact manager to read the feature
+     * @param substituteVariables Variable substitution handling
+     * @return The read feature
+     * @throws IOException If reading fails
+     */
+    public static Feature getFeature(final String url,
+            final ArtifactManager artifactManager,
+            final SubstituteVariables substituteVariables)
+    throws IOException {
+        final ArtifactHandler featureArtifact = artifactManager.getArtifactHandler(url);
 
+        try (final FileReader r = new FileReader(featureArtifact.getFile())) {
+            final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl(), substituteVariables);
+            return f;
+        }
+    }
+
+    /**
+     * Get an artifact id for the Apache Felix framework
+     * @param version The version to use or {@code null} for the default version
+     * @return The artifact id
+     * @throws IllegalArgumentException If the provided version is invalid
+     */
+    public static ArtifactId getFelixFrameworkId(final String version) {
+        return new ArtifactId("org.apache.felix",
+                "org.apache.felix.framework",
+                version != null ? version : "5.6.10", null, null);
+    }
+
+    static final Comparator<String> FEATURE_PATH_COMP = new Comparator<String>() {
         @Override
         public int compare(final String o1, final String o2) {
             // windows path conversion
@@ -194,8 +232,6 @@ public class FileUtils {
         }
     }
 
-
-
     private static void processFile(final List<String> paths, final File f)
     throws IOException {
         if ( f.getName().endsWith(EXTENSION_REF_FILE) ) {
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/FeatureUtilTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java
similarity index 92%
rename from featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/FeatureUtilTest.java
rename to featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java
index e06b175..08ce172 100644
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/FeatureUtilTest.java
+++ b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java
@@ -23,10 +23,10 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.sling.feature.io.FileUtils;
+import org.apache.sling.feature.io.IOUtils;
 import org.junit.Test;
 
-public class FeatureUtilTest {
+public class IOUtilsTest {
 
     @Test public void testFileSort() {
         final String[] files = new String[] {
@@ -41,7 +41,7 @@ public class FeatureUtilTest {
         };
 
         final List<String> l = new ArrayList<>(Arrays.asList(files));
-        Collections.sort(l, FileUtils.FEATURE_PATH_COMP);
+        Collections.sort(l, IOUtils.FEATURE_PATH_COMP);
         for(int i=0; i<files.length; i++) {
             assertEquals(files[i], l.get(i));
         }
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
index 2f2d7b0..149fa96 100644
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
+++ b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
@@ -34,10 +34,10 @@ import org.apache.sling.feature.io.ArtifactManager;
 import org.apache.sling.feature.io.json.ApplicationJSONReader;
 import org.apache.sling.feature.io.json.ApplicationJSONWriter;
 import org.apache.sling.feature.launcher.impl.LauncherConfig.StartupMode;
+import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
+import org.apache.sling.feature.resolver.FeatureResolver;
 import org.apache.sling.feature.resolver.FrameworkResolver;
-import org.apache.sling.feature.support.FeatureUtil;
 import org.apache.sling.feature.support.SlingConstants;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
 
 public class FeatureProcessor {
 
@@ -64,8 +64,8 @@ public class FeatureProcessor {
 
         } else {
             try (FeatureResolver resolver = new FrameworkResolver(artifactManager, Collections.emptyMap())) {
-                app = FeatureUtil.assembleApplication(null, artifactManager, resolver,
-                       org.apache.sling.feature.io.FileUtils.getFeatureFiles(config.getHomeDirectory(), config.getFeatureFiles()).toArray(new String[0]));
+                app = ApplicationResolverAssembler.assembleApplication(null, artifactManager, resolver,
+                       org.apache.sling.feature.io.IOUtils.getFeatureFiles(config.getHomeDirectory(), config.getFeatureFiles()).toArray(new String[0]));
             } catch (Exception ex) {
                 Main.LOG().error("Error while assembling application: {}", ex.getMessage(), ex);
                 System.exit(1);
diff --git a/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/FeatureToProvisioning.java b/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/FeatureToProvisioning.java
index 11041f8..995d47f 100644
--- a/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/FeatureToProvisioning.java
+++ b/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/FeatureToProvisioning.java
@@ -16,24 +16,6 @@
  */
 package org.apache.sling.feature.modelconverter.impl;
 
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonReader;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-
 import org.apache.sling.feature.Application;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Bundles;
@@ -43,11 +25,12 @@ import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Extensions;
 import org.apache.sling.feature.KeyValueMap;
 import org.apache.sling.feature.io.ArtifactManager;
+import org.apache.sling.feature.io.IOUtils;
 import org.apache.sling.feature.io.json.ApplicationJSONReader;
 import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.apache.sling.feature.support.FeatureUtil;
+import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
+import org.apache.sling.feature.resolver.FeatureResolver;
 import org.apache.sling.feature.support.SlingConstants;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
 import org.apache.sling.provisioning.model.Artifact;
 import org.apache.sling.provisioning.model.Configuration;
 import org.apache.sling.provisioning.model.Feature;
@@ -57,6 +40,24 @@ import org.apache.sling.provisioning.model.io.ModelWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+
 /** Converter that converts the feature model to the provisioning model.
  */
 public class FeatureToProvisioning {
@@ -64,7 +65,7 @@ public class FeatureToProvisioning {
     static final String PROVISIONING_MODEL_NAME_VARIABLE = "provisioning.model.name";
 
     public static void convert(File file, String output, ArtifactManager am) throws IOException {
-        org.apache.sling.feature.Feature feature = FeatureUtil.getFeature(file.getAbsolutePath(), am, SubstituteVariables.NONE);
+        org.apache.sling.feature.Feature feature = IOUtils.getFeature(file.getAbsolutePath(), am, SubstituteVariables.NONE);
 
         Object featureNameVar = feature.getVariables().remove(PROVISIONING_MODEL_NAME_VARIABLE);
         String featureName;
@@ -91,7 +92,7 @@ public class FeatureToProvisioning {
                     index++;
                 }
             } else {
-                final Application app = FeatureUtil.assembleApplication(null, am, fr, files.stream()
+                final Application app = ApplicationResolverAssembler.assembleApplication(null, am, fr, files.stream()
                         .map(File::getAbsolutePath)
                         .toArray(String[]::new));
                 FeatureToProvisioning.convert(app, 0, output);
diff --git a/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java b/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java
index cb166a7..f1e86d0 100644
--- a/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java
+++ b/featuremodel/feature-modelconverter/src/main/java/org/apache/sling/feature/modelconverter/impl/ProvisioningToFeature.java
@@ -27,9 +27,9 @@ import org.apache.sling.feature.KeyValueMap;
 import org.apache.sling.feature.io.ArtifactHandler;
 import org.apache.sling.feature.io.ArtifactManager;
 import org.apache.sling.feature.io.ArtifactManagerConfig;
+import org.apache.sling.feature.io.IOUtils;
 import org.apache.sling.feature.io.json.ApplicationJSONWriter;
 import org.apache.sling.feature.io.json.FeatureJSONWriter;
-import org.apache.sling.feature.support.FeatureUtil;
 import org.apache.sling.feature.support.SlingConstants;
 import org.apache.sling.provisioning.model.Artifact;
 import org.apache.sling.provisioning.model.ArtifactGroup;
@@ -317,7 +317,7 @@ public class ProvisioningToFeature {
 
         }
         // felix framework hard coded for now
-        app.setFramework(FeatureUtil.getFelixFrameworkId(null));
+        app.setFramework(IOUtils.getFelixFrameworkId(null));
         return app;
     }
 
diff --git a/featuremodel/feature-modelconverter/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java b/featuremodel/feature-modelconverter/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java
index 98449cf..ac49f3a 100644
--- a/featuremodel/feature-modelconverter/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java
+++ b/featuremodel/feature-modelconverter/src/test/java/org/apache/sling/feature/modelconverter/impl/ModelConverterTest.java
@@ -23,8 +23,8 @@ import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Extensions;
 import org.apache.sling.feature.io.ArtifactManager;
 import org.apache.sling.feature.io.ArtifactManagerConfig;
+import org.apache.sling.feature.io.IOUtils;
 import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.apache.sling.feature.support.FeatureUtil;
 import org.apache.sling.provisioning.model.Artifact;
 import org.apache.sling.provisioning.model.ArtifactGroup;
 import org.apache.sling.provisioning.model.Configuration;
@@ -175,8 +175,8 @@ public class ModelConverterTest {
         File outFile = files.get(0);
 
         String expectedFile = new File(getClass().getResource(expectedJSON).toURI()).getAbsolutePath();
-        org.apache.sling.feature.Feature expected = FeatureUtil.getFeature(expectedFile, artifactManager, SubstituteVariables.NONE);
-        org.apache.sling.feature.Feature actual = FeatureUtil.getFeature(outFile.getAbsolutePath(), artifactManager, SubstituteVariables.NONE);
+        org.apache.sling.feature.Feature expected = IOUtils.getFeature(expectedFile, artifactManager, SubstituteVariables.NONE);
+        org.apache.sling.feature.Feature actual = IOUtils.getFeature(outFile.getAbsolutePath(), artifactManager, SubstituteVariables.NONE);
         assertFeaturesEqual(expected, actual);
     }
 
@@ -206,8 +206,8 @@ public class ModelConverterTest {
         File outFile = files.get(0);
 
         String expectedFile = new File(getClass().getResource(expectedJSON).toURI()).getAbsolutePath();
-        org.apache.sling.feature.Feature expected = FeatureUtil.getFeature(expectedFile, artifactManager, SubstituteVariables.NONE);
-        org.apache.sling.feature.Feature actual = FeatureUtil.getFeature(outFile.getAbsolutePath(), artifactManager, SubstituteVariables.NONE);
+        org.apache.sling.feature.Feature expected = IOUtils.getFeature(expectedFile, artifactManager, SubstituteVariables.NONE);
+        org.apache.sling.feature.Feature actual = IOUtils.getFeature(outFile.getAbsolutePath(), artifactManager, SubstituteVariables.NONE);
         assertFeaturesEqual(expected, actual);
     }
 
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/ApplicationResolverAssembler.java
similarity index 73%
rename from featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java
rename to featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/ApplicationResolverAssembler.java
index 7c921a5..84c1e42 100644
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/FeatureUtil.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/ApplicationResolverAssembler.java
@@ -14,14 +14,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.sling.feature.support;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+package org.apache.sling.feature.resolver;
 
 import org.apache.sling.feature.Application;
 import org.apache.sling.feature.ArtifactId;
@@ -31,45 +24,18 @@ import org.apache.sling.feature.builder.BuilderContext;
 import org.apache.sling.feature.builder.FeatureProvider;
 import org.apache.sling.feature.io.ArtifactHandler;
 import org.apache.sling.feature.io.ArtifactManager;
+import org.apache.sling.feature.io.IOUtils;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
 import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
-import org.apache.sling.feature.support.resolver.FeatureResource;
 
-public class FeatureUtil {
-    /**
-     * Get an artifact id for the Apache Felix framework
-     * @param version The version to use or {@code null} for the default version
-     * @return The artifact id
-     * @throws IllegalArgumentException If the provided version is invalid
-     */
-    public static ArtifactId getFelixFrameworkId(final String version) {
-        return new ArtifactId("org.apache.felix",
-                "org.apache.felix.framework",
-                version != null ? version : "5.6.10", null, null);
-    }
-
-    /**
-     * Read the feature
-     *
-     * @param url The feature url
-     * @param artifactManager The artifact manager to read the feature
-     * @param substituteVariables Variable substitution handling
-     * @return The read feature
-     * @throws IOException If reading fails
-     */
-    public static Feature getFeature(final String url,
-            final ArtifactManager artifactManager,
-            final SubstituteVariables substituteVariables)
-    throws IOException {
-        final ArtifactHandler featureArtifact = artifactManager.getArtifactHandler(url);
-
-        try (final FileReader r = new FileReader(featureArtifact.getFile())) {
-            final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl(), substituteVariables);
-            return f;
-        }
-    }
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
+public class ApplicationResolverAssembler {
     /**
      * Assemble an application based on the given files.
      *
@@ -90,7 +56,7 @@ public class FeatureUtil {
     throws IOException {
         final List<Feature> features = new ArrayList<>();
         for(final String initFile : featureFiles) {
-            final Feature f = getFeature(initFile, artifactManager, SubstituteVariables.RESOLVE);
+            final Feature f = IOUtils.getFeature(initFile, artifactManager, SubstituteVariables.RESOLVE);
             features.add(f);
         }
 
@@ -154,7 +120,7 @@ public class FeatureUtil {
         // check framework
         if ( app.getFramework() == null ) {
             // use hard coded Apache Felix
-            app.setFramework(getFelixFrameworkId(null));
+            app.setFramework(IOUtils.getFelixFrameworkId(null));
         }
 
         return app;
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/resolver/FeatureResolver.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FeatureResolver.java
similarity index 96%
rename from featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/resolver/FeatureResolver.java
rename to featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FeatureResolver.java
index e5073ee..f40a9b1 100644
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/resolver/FeatureResolver.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FeatureResolver.java
@@ -14,7 +14,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.sling.feature.support.resolver;
+package org.apache.sling.feature.resolver;
 
 import java.util.List;
 
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/resolver/FeatureResource.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FeatureResource.java
similarity index 97%
rename from featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/resolver/FeatureResource.java
rename to featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FeatureResource.java
index 4b327d2..b420805 100644
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/resolver/FeatureResource.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FeatureResource.java
@@ -14,7 +14,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.sling.feature.support.resolver;
+package org.apache.sling.feature.resolver;
 
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.Feature;
diff --git a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FrameworkResolver.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FrameworkResolver.java
index 88efe0c..da09e69 100644
--- a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FrameworkResolver.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/FrameworkResolver.java
@@ -38,8 +38,6 @@ import org.apache.sling.feature.resolver.impl.FeatureResourceImpl;
 import org.apache.sling.feature.resolver.impl.ResolveContextImpl;
 import org.apache.sling.feature.scanner.BundleDescriptor;
 import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
-import org.apache.sling.feature.support.resolver.FeatureResource;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
diff --git a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
index 5e28c79..901b141 100644
--- a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
@@ -20,8 +20,8 @@ import org.apache.felix.utils.resource.CapabilityImpl;
 import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.resolver.FeatureResource;
 import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.resolver.FeatureResource;
 import org.apache.sling.feature.support.util.PackageInfo;
 import org.osgi.framework.Version;
 import org.osgi.framework.VersionRange;
diff --git a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/FeatureResourceImpl.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/FeatureResourceImpl.java
index f61e6e3..4acee42 100644
--- a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/FeatureResourceImpl.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/FeatureResourceImpl.java
@@ -20,7 +20,7 @@ import org.apache.felix.utils.resource.CapabilityImpl;
 import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.support.resolver.FeatureResource;
+import org.apache.sling.feature.resolver.FeatureResource;
 import org.osgi.framework.Version;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.resource.Capability;
diff --git a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/analyser/AnalyserTest.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
similarity index 89%
rename from featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/analyser/AnalyserTest.java
rename to featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
index 3d14b85..c4b8110 100644
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/analyser/AnalyserTest.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
@@ -14,16 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.feature.analyser;
-
-import static junit.framework.TestCase.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.List;
+package org.apache.sling.feature.resolver;
 
 import org.apache.sling.feature.Application;
 import org.apache.sling.feature.Artifact;
@@ -36,11 +27,17 @@ import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
 import org.apache.sling.feature.scanner.BundleDescriptor;
 import org.apache.sling.feature.scanner.Scanner;
 import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.support.FeatureUtil;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
-import org.apache.sling.feature.support.resolver.FeatureResource;
 import org.junit.Test;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.fail;
+
 public class AnalyserTest {
     @Test
     public void testAnalyserWithCompleteFeature() throws Exception {
@@ -50,7 +47,7 @@ public class AnalyserTest {
                 "UTF-8") ) {
             Feature feature = FeatureJSONReader.read(reader, "feature", SubstituteVariables.RESOLVE);
 
-            Application app = FeatureUtil.assembleApplication(null, ArtifactManager.getArtifactManager(new ArtifactManagerConfig()),
+            Application app = ApplicationResolverAssembler.assembleApplication(null, ArtifactManager.getArtifactManager(new ArtifactManagerConfig()),
                     getTestResolver(), feature);
 
             analyser.analyse(app);
@@ -65,7 +62,7 @@ public class AnalyserTest {
                 "UTF-8") ) {
             Feature feature = FeatureJSONReader.read(reader, "feature", SubstituteVariables.RESOLVE);
 
-            Application app = FeatureUtil.assembleApplication(null, ArtifactManager.getArtifactManager(new ArtifactManagerConfig()),
+            Application app = ApplicationResolverAssembler.assembleApplication(null, ArtifactManager.getArtifactManager(new ArtifactManagerConfig()),
                     getTestResolver(), feature);
 
             try {
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/FrameworkResolverTest.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/FrameworkResolverTest.java
index 7094876..8365101 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/FrameworkResolverTest.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/FrameworkResolverTest.java
@@ -22,8 +22,6 @@ import org.apache.sling.feature.io.ArtifactManager;
 import org.apache.sling.feature.io.ArtifactManagerConfig;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
 import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.apache.sling.feature.support.resolver.FeatureResolver;
-import org.apache.sling.feature.support.resolver.FeatureResource;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
diff --git a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/analyser/TestBundleResourceImpl.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
similarity index 98%
rename from featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/analyser/TestBundleResourceImpl.java
rename to featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
index a9e4808..86beec4 100644
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/analyser/TestBundleResourceImpl.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
@@ -14,14 +14,13 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.sling.feature.analyser;
+package org.apache.sling.feature.resolver;
 
 import org.apache.felix.utils.resource.CapabilityImpl;
 import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.resolver.FeatureResource;
 import org.apache.sling.feature.support.util.PackageInfo;
 import org.osgi.framework.Version;
 import org.osgi.framework.VersionRange;
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
index 3ca9870..eb307d2 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
@@ -21,10 +21,10 @@ import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.resolver.FeatureResource;
 import org.apache.sling.feature.scanner.BundleDescriptor;
 import org.apache.sling.feature.scanner.Descriptor;
 import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.support.resolver.FeatureResource;
 import org.apache.sling.feature.support.util.PackageInfo;
 import org.junit.Test;
 import org.mockito.Mockito;
diff --git a/featuremodel/feature-analyser/src/test/resources/feature_complete.json b/featuremodel/feature-resolver/src/test/resources/feature_complete.json
similarity index 100%
rename from featuremodel/feature-analyser/src/test/resources/feature_complete.json
rename to featuremodel/feature-resolver/src/test/resources/feature_complete.json
diff --git a/featuremodel/feature-analyser/src/test/resources/feature_incomplete.json b/featuremodel/feature-resolver/src/test/resources/feature_incomplete.json
similarity index 100%
rename from featuremodel/feature-analyser/src/test/resources/feature_incomplete.json
rename to featuremodel/feature-resolver/src/test/resources/feature_incomplete.json
diff --git a/featuremodel/osgifeature-maven-plugin/src/main/java/org/apache/sling/feature/maven/Preprocessor.java b/featuremodel/osgifeature-maven-plugin/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
index 2b50c2b..509e89e 100644
--- a/featuremodel/osgifeature-maven-plugin/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
+++ b/featuremodel/osgifeature-maven-plugin/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
@@ -235,7 +235,7 @@ public class Preprocessor {
 
             for(final File file : files) {
                 try {
-                    final List<String> features = org.apache.sling.feature.io.FileUtils.parseFeatureRefFile(file);
+                    final List<String> features = org.apache.sling.feature.io.IOUtils.parseFeatureRefFile(file);
                     if ( features.isEmpty() ) {
                         env.logger.debug("Empty feature ref file at " + file);
                     } else {

-- 
To stop receiving notification emails like this one, please contact
davidb@apache.org.