You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2017/08/21 10:54:20 UTC

[1/2] karaf git commit: Remove unused code

Repository: karaf
Updated Branches:
  refs/heads/master 1c4149b6f -> b3281c12a


Remove unused code


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/61909845
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/61909845
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/61909845

Branch: refs/heads/master
Commit: 61909845158be8cabd43b22dbe798205a58061b9
Parents: 1c4149b
Author: Christian Schneider <ch...@die-schneider.net>
Authored: Mon Aug 21 12:07:47 2017 +0200
Committer: Christian Schneider <ch...@die-schneider.net>
Committed: Mon Aug 21 12:07:47 2017 +0200

----------------------------------------------------------------------
 .../profile/versioning/ComparableVersion.java   | 441 -------------------
 .../karaf/profile/versioning/VersionUtils.java  |  76 ----
 .../profile/versioning/VersionUtilsTest.java    |  40 --
 3 files changed, 557 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/61909845/profile/src/main/java/org/apache/karaf/profile/versioning/ComparableVersion.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/versioning/ComparableVersion.java b/profile/src/main/java/org/apache/karaf/profile/versioning/ComparableVersion.java
deleted file mode 100644
index 0362183..0000000
--- a/profile/src/main/java/org/apache/karaf/profile/versioning/ComparableVersion.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * This file is taken from the "maven-artifact" project because the artifact lacks OSGi informations.
- */
-package org.apache.karaf.profile.versioning;
-
-/*
- * 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.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.Stack;
-
-/**
- * Generic implementation of version comparison.
- *
- * <p>
- * Features:
- * <ul>
- * <li>mixing of '<code>-</code>' (hyphen) and '<code>.</code>' (dot) separators,</li>
- * <li>transition between characters and digits also constitutes a separator:
- * <code>1.0alpha1 =&gt; [1, 0, alpha, 1]</code></li>
- * <li>unlimited number of version components,</li>
- * <li>version components in the text can be digits or strings,</li>
- * <li>strings are checked for well-known qualifiers and the qualifier ordering is used for version ordering. Well-known
- * qualifiers (case insensitive) are:<ul>
- * <li><code>alpha</code> or <code>a</code></li>
- * <li><code>beta</code> or <code>b</code></li>
- * <li><code>milestone</code> or <code>m</code></li>
- * <li><code>rc</code> or <code>cr</code></li>
- * <li><code>snapshot</code></li>
- * <li><code>(the empty string)</code> or <code>ga</code> or <code>final</code></li>
- * <li><code>sp</code></li>
- * </ul>
- * Unknown qualifiers are considered after known qualifiers, with lexical order (always case insensitive),
- * </li>
- * <li>a hyphen usually precedes a qualifier, and is always less important than something preceded with a dot.</li>
- * </ul></p>
- *
- * @see <a href="https://cwiki.apache.org/confluence/display/MAVENOLD/Versioning">"Versioning" on Maven Wiki</a>
- * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
- * @author <a href="mailto:hboutemy@apache.org">Hervé Boutemy</a>
- */
-public class ComparableVersion
-        implements Comparable<ComparableVersion> {
-
-    private String value;
-
-    private String canonical;
-
-    private ListItem items;
-
-    private interface Item {
-
-        int INTEGER_ITEM = 0;
-        int STRING_ITEM = 1;
-        int LIST_ITEM = 2;
-
-        int compareTo(Item item);
-
-        int getType();
-
-        boolean isNull();
-    }
-
-    /**
-     * Represents a numeric item in the version item list.
-     */
-    private static class IntegerItem
-            implements Item {
-
-        private static final BigInteger BIG_INTEGER_ZERO = new BigInteger("0");
-
-        private final BigInteger value;
-
-        public static final IntegerItem ZERO = new IntegerItem();
-
-        private IntegerItem() {
-            this.value = BIG_INTEGER_ZERO;
-        }
-
-        public IntegerItem(String str) {
-            this.value = new BigInteger(str);
-        }
-
-        public int getType() {
-            return INTEGER_ITEM;
-        }
-
-        public boolean isNull() {
-            return BIG_INTEGER_ZERO.equals(value);
-        }
-
-        public int compareTo(Item item) {
-            if (item == null) {
-                return BIG_INTEGER_ZERO.equals(value) ? 0 : 1; // 1.0 == 1, 1.1 > 1
-            }
-
-            switch (item.getType()) {
-                case INTEGER_ITEM:
-                    return value.compareTo(((IntegerItem) item).value);
-
-                case STRING_ITEM:
-                    return 1; // 1.1 > 1-sp
-
-                case LIST_ITEM:
-                    return 1; // 1.1 > 1-1
-
-                default:
-                    throw new RuntimeException("invalid item: " + item.getClass());
-            }
-        }
-
-        public String toString() {
-            return value.toString();
-        }
-    }
-
-    /**
-     * Represents a string in the version item list, usually a qualifier.
-     */
-    private static class StringItem
-            implements Item {
-
-        private static final String[] QUALIFIERS = {"alpha", "beta", "milestone", "rc", "snapshot", "", "sp"};
-
-        @SuppressWarnings("checkstyle:constantname")
-        private static final List<String> _QUALIFIERS = Arrays.asList(QUALIFIERS);
-
-        private static final Properties ALIASES = new Properties();
-
-        static {
-            ALIASES.put("ga", "");
-            ALIASES.put("final", "");
-            ALIASES.put("cr", "rc");
-        }
-
-        /**
-         * A comparable value for the empty-string qualifier. This one is used to determine if a given qualifier makes
-         * the version older than one without a qualifier, or more recent.
-         */
-        private static final String RELEASE_VERSION_INDEX = String.valueOf(_QUALIFIERS.indexOf(""));
-
-        private String value;
-
-        public StringItem(String value, boolean followedByDigit) {
-            if (followedByDigit && value.length() == 1) {
-                // a1 = alpha-1, b1 = beta-1, m1 = milestone-1
-                switch (value.charAt(0)) {
-                    case 'a':
-                        value = "alpha";
-                        break;
-                    case 'b':
-                        value = "beta";
-                        break;
-                    case 'm':
-                        value = "milestone";
-                        break;
-                    default:
-                }
-            }
-            this.value = ALIASES.getProperty(value, value);
-        }
-
-        public int getType() {
-            return STRING_ITEM;
-        }
-
-        public boolean isNull() {
-            return (comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX) == 0);
-        }
-
-        /**
-         * Returns a comparable value for a qualifier.
-         *
-         * This method takes into account the ordering of known qualifiers then unknown qualifiers with lexical
-         * ordering.
-         *
-         * just returning an Integer with the index here is faster, but requires a lot of if/then/else to check for -1
-         * or QUALIFIERS.size and then resort to lexical ordering. Most comparisons are decided by the first character,
-         * so this is still fast. If more characters are needed then it requires a lexical sort anyway.
-         *
-         * @param qualifier
-         * @return an equivalent value that can be used with lexical comparison
-         */
-        public static String comparableQualifier(String qualifier) {
-            int i = _QUALIFIERS.indexOf(qualifier);
-
-            return i == -1 ? (_QUALIFIERS.size() + "-" + qualifier) : String.valueOf(i);
-        }
-
-        public int compareTo(Item item) {
-            if (item == null) {
-                // 1-rc < 1, 1-ga > 1
-                return comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX);
-            }
-            switch (item.getType()) {
-                case INTEGER_ITEM:
-                    return -1; // 1.any < 1.1 ?
-
-                case STRING_ITEM:
-                    return comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value));
-
-                case LIST_ITEM:
-                    return -1; // 1.any < 1-1
-
-                default:
-                    throw new RuntimeException("invalid item: " + item.getClass());
-            }
-        }
-
-        public String toString() {
-            return value;
-        }
-    }
-
-    /**
-     * Represents a version list item. This class is used both for the global item list and for sub-lists (which start
-     * with '-(number)' in the version specification).
-     */
-    private static class ListItem
-            extends ArrayList<Item>
-            implements Item {
-
-        public int getType() {
-            return LIST_ITEM;
-        }
-
-        public boolean isNull() {
-            return (size() == 0);
-        }
-
-        void normalize() {
-            for (int i = size() - 1; i >= 0; i--) {
-                Item lastItem = get(i);
-
-                if (lastItem.isNull()) {
-                    // remove null trailing items: 0, "", empty list
-                    remove(i);
-                } else if (!(lastItem instanceof ListItem)) {
-                    break;
-                }
-            }
-        }
-
-        public int compareTo(Item item) {
-            if (item == null) {
-                if (size() == 0) {
-                    return 0; // 1-0 = 1- (normalize) = 1
-                }
-                Item first = get(0);
-                return first.compareTo(null);
-            }
-            switch (item.getType()) {
-                case INTEGER_ITEM:
-                    return -1; // 1-1 < 1.0.x
-
-                case STRING_ITEM:
-                    return 1; // 1-1 > 1-sp
-
-                case LIST_ITEM:
-                    Iterator<Item> left = iterator();
-                    Iterator<Item> right = ((ListItem) item).iterator();
-
-                    while (left.hasNext() || right.hasNext()) {
-                        Item l = left.hasNext() ? left.next() : null;
-                        Item r = right.hasNext() ? right.next() : null;
-
-                        // if this is shorter, then invert the compare and mul with -1
-                        int result = l == null ? (r == null ? 0 : -1 * r.compareTo(l)) : l.compareTo(r);
-
-                        if (result != 0) {
-                            return result;
-                        }
-                    }
-
-                    return 0;
-
-                default:
-                    throw new RuntimeException("invalid item: " + item.getClass());
-            }
-        }
-
-        public String toString() {
-            StringBuilder buffer = new StringBuilder();
-            for (Item item : this) {
-                if (buffer.length() > 0) {
-                    buffer.append((item instanceof ListItem) ? '-' : '.');
-                }
-                buffer.append(item);
-            }
-            return buffer.toString();
-        }
-    }
-
-    public ComparableVersion(String version) {
-        parseVersion(version);
-    }
-
-    public final void parseVersion(String version) {
-        this.value = version;
-
-        items = new ListItem();
-
-        version = version.toLowerCase(Locale.ENGLISH);
-
-        ListItem list = items;
-
-        Stack<Item> stack = new Stack<>();
-        stack.push(list);
-
-        boolean isDigit = false;
-
-        int startIndex = 0;
-
-        for (int i = 0; i < version.length(); i++) {
-            char c = version.charAt(i);
-
-            if (c == '.') {
-                if (i == startIndex) {
-                    list.add(IntegerItem.ZERO);
-                } else {
-                    list.add(parseItem(isDigit, version.substring(startIndex, i)));
-                }
-                startIndex = i + 1;
-            } else if (c == '-') {
-                if (i == startIndex) {
-                    list.add(IntegerItem.ZERO);
-                } else {
-                    list.add(parseItem(isDigit, version.substring(startIndex, i)));
-                }
-                startIndex = i + 1;
-
-                list.add(list = new ListItem());
-                stack.push(list);
-            } else if (Character.isDigit(c)) {
-                if (!isDigit && i > startIndex) {
-                    list.add(new StringItem(version.substring(startIndex, i), true));
-                    startIndex = i;
-
-                    list.add(list = new ListItem());
-                    stack.push(list);
-                }
-
-                isDigit = true;
-            } else {
-                if (isDigit && i > startIndex) {
-                    list.add(parseItem(true, version.substring(startIndex, i)));
-                    startIndex = i;
-
-                    list.add(list = new ListItem());
-                    stack.push(list);
-                }
-
-                isDigit = false;
-            }
-        }
-
-        if (version.length() > startIndex) {
-            list.add(parseItem(isDigit, version.substring(startIndex)));
-        }
-
-        while (!stack.isEmpty()) {
-            list = (ListItem) stack.pop();
-            list.normalize();
-        }
-
-        canonical = items.toString();
-    }
-
-    private static Item parseItem(boolean isDigit, String buf) {
-        return isDigit ? new IntegerItem(buf) : new StringItem(buf, false);
-    }
-
-    public int compareTo(ComparableVersion o) {
-        return items.compareTo(o.items);
-    }
-
-    public String toString() {
-        return value;
-    }
-
-    public String getCanonical() {
-        return canonical;
-    }
-
-    public boolean equals(Object o) {
-        return (o instanceof ComparableVersion) && canonical.equals(((ComparableVersion) o).canonical);
-    }
-
-    public int hashCode() {
-        return canonical.hashCode();
-    }
-
-    /**
-     * Main to test version parsing and comparison.
-     *
-     * @param args the version strings to parse and compare
-     */
-    public static void main(String... args) {
-        System.out.println("Display parameters as parsed by Maven (in canonical form) and comparison result:");
-        if (args.length == 0) {
-            return;
-        }
-
-        ComparableVersion prev = null;
-        int i = 1;
-        for (String version : args) {
-            ComparableVersion c = new ComparableVersion(version);
-
-            if (prev != null) {
-                int compare = prev.compareTo(c);
-                System.out.println("   " + prev.toString() + ' '
-                        + ((compare == 0) ? "==" : ((compare < 0) ? "<" : ">")) + ' ' + version);
-            }
-
-            System.out.println(String.valueOf(i++) + ". " + version + " == " + c.getCanonical());
-
-            prev = c;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/61909845/profile/src/main/java/org/apache/karaf/profile/versioning/VersionUtils.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/versioning/VersionUtils.java b/profile/src/main/java/org/apache/karaf/profile/versioning/VersionUtils.java
deleted file mode 100644
index cd42256..0000000
--- a/profile/src/main/java/org/apache/karaf/profile/versioning/VersionUtils.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2016 The Apache Software Foundation.
- *
- * 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.
- */
-package org.apache.karaf.profile.versioning;
-
-public class VersionUtils {
-
-    private static final String SNAPSHOT = "SNAPSHOT";
-    private static final char DELIM_DASH = '-';
-    private static final char DELIM_DOT = '.';
-    private static final String EMPTY_VERSION = "0.0.0";
-
-    private VersionUtils() {
-    }
-
-    public static boolean versionEquals(String versionOne, String versionTwo) {
-        if (isSnapshotVersion(versionOne) && isSnapshotVersion(versionTwo)) {
-            // If both (and only if both) versions are snapshots, we compare without the snapshot classifier.
-            // This is done to consider e.g. 1.2.0.SNAPSHOT and 1.2.SNAPSHOT equal.
-            versionOne = versionWithoutSnapshot(versionOne);
-            versionTwo = versionWithoutSnapshot(versionTwo);
-        }
-
-        // Create comparable version objects.
-        final ComparableVersion cvOne = new ComparableVersion(versionOne);
-        final ComparableVersion cvTwo = new ComparableVersion(versionTwo);
-
-        // Use equals of comparable version class.
-        return cvOne.equals(cvTwo);
-    }
-
-    /**
-     * Check if a version is a snapshot version.
-     *
-     * @param version the version to check
-     * @return true if {@code version} refers a snapshot version otherwise false
-     */
-    protected static boolean isSnapshotVersion(final String version) {
-        return version.endsWith(SNAPSHOT);
-    }
-
-    /**
-     * Remove the snapshot classifier at the end of a version.
-     *
-     * @param version the version
-     * @return the given {@code version} without the snapshot classifier
-     */
-    protected static String versionWithoutSnapshot(final String version) {
-        int idx;
-        idx = version.lastIndexOf(SNAPSHOT);
-        if (idx < 0) {
-            return version;
-        } else if (idx == 0) {
-            return EMPTY_VERSION;
-        } else {
-            final char delim = version.charAt(idx - 1);
-            if (delim == DELIM_DOT || delim == DELIM_DASH) {
-                --idx;
-            }
-            return version.substring(0, idx);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/61909845/profile/src/test/java/org/apache/karaf/profile/versioning/VersionUtilsTest.java
----------------------------------------------------------------------
diff --git a/profile/src/test/java/org/apache/karaf/profile/versioning/VersionUtilsTest.java b/profile/src/test/java/org/apache/karaf/profile/versioning/VersionUtilsTest.java
deleted file mode 100644
index a63d979..0000000
--- a/profile/src/test/java/org/apache/karaf/profile/versioning/VersionUtilsTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2016 The Apache Software Foundation.
- *
- * 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.
- */
-package org.apache.karaf.profile.versioning;
-
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-public class VersionUtilsTest {
-
-    @Test
-    public void testVersionWithoutSnapshot() {
-        assertEquals(VersionUtils.versionWithoutSnapshot("1.2.0-SNAPSHOT"), "1.2.0");
-        assertEquals(VersionUtils.versionWithoutSnapshot("1.2.0.SNAPSHOT"), "1.2.0");
-        assertEquals(VersionUtils.versionWithoutSnapshot("1.2.0SNAPSHOT"), "1.2.0");
-    }
-
-    @Test
-    public void testVersions() {
-        assertTrue(VersionUtils.versionEquals("1.2", "1.2"));
-        assertTrue(VersionUtils.versionEquals("1.2", "1.2.0"));
-        assertTrue(VersionUtils.versionEquals("1.2.0", "1.2"));
-        assertFalse(VersionUtils.versionEquals("1.2.0", "1.2.1"));
-        assertFalse(VersionUtils.versionEquals("1.2", "1.2.1"));
-        assertTrue(VersionUtils.versionEquals("1.2.0-SNAPSHOT", "1.2.0.SNAPSHOT"));
-        assertTrue(VersionUtils.versionEquals("1.3-SNAPSHOT", "1.3.0.SNAPSHOT"));
-    }
-}


[2/2] karaf git commit: Extract ConfigInstaller

Posted by cs...@apache.org.
Extract ConfigInstaller


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b3281c12
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b3281c12
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b3281c12

Branch: refs/heads/master
Commit: b3281c12a72d11831e152e4d2981c655623353eb
Parents: 6190984
Author: Christian Schneider <ch...@die-schneider.net>
Authored: Mon Aug 21 12:37:22 2017 +0200
Committer: Christian Schneider <ch...@die-schneider.net>
Committed: Mon Aug 21 12:37:22 2017 +0200

----------------------------------------------------------------------
 .../apache/karaf/profile/assembly/Builder.java  | 143 +-------------
 .../karaf/profile/assembly/ConfigInstaller.java | 187 +++++++++++++++++++
 2 files changed, 191 insertions(+), 139 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/b3281c12/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
index 2fdd5f0..f837a18 100644
--- a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
@@ -48,7 +48,6 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.function.Function;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
-import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -63,9 +62,7 @@ import org.apache.karaf.features.internal.download.Downloader;
 import org.apache.karaf.features.internal.download.StreamProvider;
 import org.apache.karaf.features.internal.model.Bundle;
 import org.apache.karaf.features.internal.model.Conditional;
-import org.apache.karaf.features.internal.model.Config;
 import org.apache.karaf.features.internal.model.ConfigFile;
-import org.apache.karaf.features.internal.model.Content;
 import org.apache.karaf.features.internal.model.Dependency;
 import org.apache.karaf.features.internal.model.Feature;
 import org.apache.karaf.features.internal.model.Features;
@@ -921,36 +918,9 @@ public class Builder {
                     }
                 }
             }
-            List<Content> contents = new ArrayList<>();
-            contents.add(feature);
-            contents.addAll(feature.getConditional());
-            for (Content content : contents) {
-                // Install config files
-                for (Config config : content.getConfig()) {
-                    if (config.isExternal()) {
-                        installer.installArtifact(config.getValue().trim());
-                    }
-                }
-                for (ConfigFile configFile : content.getConfigfile()) {
-                    installer.installArtifact(configFile.getLocation().trim());
-                }
-                // Extract configs
-                for (Config config : content.getConfig()) {
-                    if (pidMatching(config.getName())) {
-                        Path configFile = etcDirectory.resolve(config.getName() + ".cfg");
-                        LOGGER.info("      adding config file: {}", homeDirectory.relativize(configFile));
-                        if (config.isExternal()) {
-                            downloader.download(config.getValue().trim(), provider -> {
-                                synchronized (provider) {
-                                    Files.copy(provider.getFile().toPath(), configFile, StandardCopyOption.REPLACE_EXISTING);
-                                }
-                            });
-                        } else {
-                            Files.write(configFile, config.getValue().getBytes());
-                        }
-                    }
-                }
-            }
+
+            new ConfigInstaller(etcDirectory, pidsToExtract)
+                .installConfigs(feature, downloader, installer);
             // Install libraries
             List<String> libraries = new ArrayList<>();
             for (Library library : feature.getLibraries()) {
@@ -1019,112 +989,7 @@ public class Builder {
         return allBootFeatures;
     }
 
-    private boolean pidMatching(String name) {
-        if (pidsToExtract == null) {
-            return true;
-        }
-        for (String p : pidsToExtract) {
-            boolean negated = false;
-            if (p.startsWith("!")) {
-                negated = true;
-                p = p.substring(1);
-            }
-            String r = globToRegex(p);
-            if (Pattern.matches(r, name)) {
-                return !negated;
-            }
-        }
-        return false;
-    }
-
-    private String globToRegex(String pattern) {
-        StringBuilder sb = new StringBuilder(pattern.length());
-        int inGroup = 0;
-        int inClass = 0;
-        int firstIndexInClass = -1;
-        char[] arr = pattern.toCharArray();
-        for (int i = 0; i < arr.length; i++) {
-            char ch = arr[i];
-            switch (ch) {
-                case '\\':
-                    if (++i >= arr.length) {
-                        sb.append('\\');
-                    } else {
-                        char next = arr[i];
-                        switch (next) {
-                            case ',':
-                                // escape not needed
-                                break;
-                            case 'Q':
-                            case 'E':
-                                // extra escape needed
-                                sb.append('\\');
-                            default:
-                                sb.append('\\');
-                        }
-                        sb.append(next);
-                    }
-                    break;
-                case '*':
-                    if (inClass == 0)
-                        sb.append(".*");
-                    else
-                        sb.append('*');
-                    break;
-                case '?':
-                    if (inClass == 0)
-                        sb.append('.');
-                    else
-                        sb.append('?');
-                    break;
-                case '[':
-                    inClass++;
-                    firstIndexInClass = i + 1;
-                    sb.append('[');
-                    break;
-                case ']':
-                    inClass--;
-                    sb.append(']');
-                    break;
-                case '.':
-                case '(':
-                case ')':
-                case '+':
-                case '|':
-                case '^':
-                case '$':
-                case '@':
-                case '%':
-                    if (inClass == 0 || (firstIndexInClass == i && ch == '^'))
-                        sb.append('\\');
-                    sb.append(ch);
-                    break;
-                case '!':
-                    if (firstIndexInClass == i)
-                        sb.append('^');
-                    else
-                        sb.append('!');
-                    break;
-                case '{':
-                    inGroup++;
-                    sb.append('(');
-                    break;
-                case '}':
-                    inGroup--;
-                    sb.append(')');
-                    break;
-                case ',':
-                    if (inGroup > 0)
-                        sb.append('|');
-                    else
-                        sb.append(',');
-                    break;
-                default:
-                    sb.append(ch);
-            }
-        }
-        return sb.toString();
-    }
+
 
     private String getRepos(Features rep) {
         StringBuilder repos = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/karaf/blob/b3281c12/profile/src/main/java/org/apache/karaf/profile/assembly/ConfigInstaller.java
----------------------------------------------------------------------
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/ConfigInstaller.java b/profile/src/main/java/org/apache/karaf/profile/assembly/ConfigInstaller.java
new file mode 100644
index 0000000..13943a2
--- /dev/null
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/ConfigInstaller.java
@@ -0,0 +1,187 @@
+/*
+ * 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.karaf.profile.assembly;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.karaf.features.internal.download.Downloader;
+import org.apache.karaf.features.internal.model.Config;
+import org.apache.karaf.features.internal.model.ConfigFile;
+import org.apache.karaf.features.internal.model.Content;
+import org.apache.karaf.features.internal.model.Feature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConfigInstaller {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigInstaller.class);
+    private Path etcDirectory;
+    private List<String> pidsToExtract;
+    
+    public ConfigInstaller(Path etcDirectory, List<String> pidsToExtract) {
+        this.etcDirectory = etcDirectory;
+        this.pidsToExtract = pidsToExtract;
+        // TODO Auto-generated constructor stub
+    }
+
+    public void installConfigs(Feature feature, Downloader downloader, ArtifactInstaller installer)
+        throws Exception, MalformedURLException, IOException {
+        List<Content> contents = new ArrayList<>();
+        contents.add(feature);
+        contents.addAll(feature.getConditional());
+        for (Content content : contents) {
+            // Install config files
+            for (Config config : content.getConfig()) {
+                if (config.isExternal()) {
+                    installer.installArtifact(config.getValue().trim());
+                }
+            }
+            for (ConfigFile configFile : content.getConfigfile()) {
+                installer.installArtifact(configFile.getLocation().trim());
+            }
+            // Extract configs
+            for (Config config : content.getConfig()) {
+                if (pidMatching(config.getName())) {
+                    Path configFile = etcDirectory.resolve(config.getName() + ".cfg");
+                    LOGGER.info("      adding config file: {}", configFile);
+                    if (config.isExternal()) {
+                        downloader.download(config.getValue().trim(), provider -> {
+                            synchronized (provider) {
+                                Files.copy(provider.getFile().toPath(), configFile, StandardCopyOption.REPLACE_EXISTING);
+                            }
+                        });
+                    } else {
+                        Files.write(configFile, config.getValue().getBytes());
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean pidMatching(String name) {
+        if (pidsToExtract == null) {
+            return true;
+        }
+        for (String p : pidsToExtract) {
+            boolean negated = false;
+            if (p.startsWith("!")) {
+                negated = true;
+                p = p.substring(1);
+            }
+            String r = globToRegex(p);
+            if (Pattern.matches(r, name)) {
+                return !negated;
+            }
+        }
+        return false;
+    }
+
+    private String globToRegex(String pattern) {
+        StringBuilder sb = new StringBuilder(pattern.length());
+        int inGroup = 0;
+        int inClass = 0;
+        int firstIndexInClass = -1;
+        char[] arr = pattern.toCharArray();
+        for (int i = 0; i < arr.length; i++) {
+            char ch = arr[i];
+            switch (ch) {
+                case '\\':
+                    if (++i >= arr.length) {
+                        sb.append('\\');
+                    } else {
+                        char next = arr[i];
+                        switch (next) {
+                            case ',':
+                                // escape not needed
+                                break;
+                            case 'Q':
+                            case 'E':
+                                // extra escape needed
+                                sb.append('\\');
+                            default:
+                                sb.append('\\');
+                        }
+                        sb.append(next);
+                    }
+                    break;
+                case '*':
+                    if (inClass == 0)
+                        sb.append(".*");
+                    else
+                        sb.append('*');
+                    break;
+                case '?':
+                    if (inClass == 0)
+                        sb.append('.');
+                    else
+                        sb.append('?');
+                    break;
+                case '[':
+                    inClass++;
+                    firstIndexInClass = i + 1;
+                    sb.append('[');
+                    break;
+                case ']':
+                    inClass--;
+                    sb.append(']');
+                    break;
+                case '.':
+                case '(':
+                case ')':
+                case '+':
+                case '|':
+                case '^':
+                case '$':
+                case '@':
+                case '%':
+                    if (inClass == 0 || (firstIndexInClass == i && ch == '^'))
+                        sb.append('\\');
+                    sb.append(ch);
+                    break;
+                case '!':
+                    if (firstIndexInClass == i)
+                        sb.append('^');
+                    else
+                        sb.append('!');
+                    break;
+                case '{':
+                    inGroup++;
+                    sb.append('(');
+                    break;
+                case '}':
+                    inGroup--;
+                    sb.append(')');
+                    break;
+                case ',':
+                    if (inGroup > 0)
+                        sb.append('|');
+                    else
+                        sb.append(',');
+                    break;
+                default:
+                    sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+}