From a26dfee4e893821a3e9ffdd6602d984888008ba3 Mon Sep 17 00:00:00 2001 From: Markus Rathgeb Date: Mon, 5 Oct 2015 16:56:19 +0200 Subject: [PATCH] [KARAF-3262] feature configfile: substitution Add variable substitution to the configfile finalname of a feature. Old situation: * All ${...} are removed from the config file name and not used. * The given path is prefixed with / relative to ${karaf.base} on installation New behaviour: * If the final name starts not with "${", the path is prefixed with / relative to karaf.base. * All ${...} are substituted. * If the substituted string starts with an variable (the first one * has been unknown), it is prefixed with / relative to karaf.base. * All unknown variables are removed from the resulting final name. Signed-off-by: Markus Rathgeb --- .../service/FeatureConfigInstaller.java | 62 ++++++++++++++++--- .../service/FeatureConfigInstallerTest.java | 35 +++++++++++ 2 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 features/core/src/test/java/org/apache/karaf/features/internal/service/FeatureConfigInstallerTest.java diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java index b1f284ffbc6..6f71702f8bc 100644 --- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java +++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java @@ -32,6 +32,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.felix.utils.properties.InterpolationHelper; +import org.apache.felix.utils.properties.InterpolationHelper.SubstitutionCallback; import org.apache.karaf.features.ConfigFileInfo; import org.apache.karaf.features.ConfigInfo; import org.apache.karaf.features.Feature; @@ -134,16 +136,62 @@ private String createConfigurationKey(String pid, String factoryPid) { return factoryPid == null ? pid : pid + "-" + factoryPid; } - private void installConfigurationFile(String fileLocation, String finalname, boolean override) throws IOException { - String basePath = System.getProperty("karaf.base"); + /** + * Substitute variables in the final name and append prefix if necessary. + * + *

+ *

    + *
  1. If the final name does not start with '${' it is prefixed with + * karaf.base (+ file separator).
  2. + *
  3. It substitute also all variables (scheme ${...}) with the respective + * configuration values and system properties.
  4. + *
  5. All unknown variables kept unchanged.
  6. + *
  7. If the substituted string starts with an variable that could not be + * substituted, it will be prefixed with karaf.base (+ file separator), too. + *
  8. + *
+ *

+ * + * @param finalname + * The final name that should be processed. + * @return the location in the file system that should be accesses. + */ + protected static String substFinalName(String finalname) { + final String markerVarBeg = "${"; + final String markerVarEnd = "}"; + + boolean startsWithVariable = finalname.startsWith(markerVarBeg) && finalname.contains(markerVarEnd); + + // Substitute all variables, but keep unknown ones. + final String dummyKey = ""; + try { + finalname = InterpolationHelper.substVars(finalname, dummyKey, null, null, (SubstitutionCallback) null, + true, true, false); + } catch (final IllegalArgumentException ex) { + LOGGER.info("Substitution failed. Skip substitution of variables of configuration final name ({}).", + finalname); + } + + // Prefix with karaf base if the initial final name does not start with + // a variable or the first variable was not substituted. + if (!startsWithVariable || finalname.startsWith(markerVarBeg)) { + final String basePath = System.getProperty("karaf.base"); + finalname = basePath + File.separator + finalname; + } - if (finalname.contains("${")) { - //remove any placeholder or variable part, this is not valid. - int marker = finalname.indexOf("}"); - finalname = finalname.substring(marker + 1); + // Remove all unknown variables. + while (finalname.contains(markerVarBeg) && finalname.contains(markerVarEnd)) { + int beg = finalname.indexOf(markerVarBeg); + int end = finalname.indexOf(markerVarEnd); + final String rem = finalname.substring(beg, end + markerVarEnd.length()); + finalname = finalname.replace(rem, ""); } - finalname = basePath + File.separator + finalname; + return finalname; + } + + private void installConfigurationFile(String fileLocation, String finalname, boolean override) throws IOException { + finalname = substFinalName(finalname); File file = new File(finalname); if (file.exists()) { diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeatureConfigInstallerTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeatureConfigInstallerTest.java new file mode 100644 index 00000000000..3c3ee473203 --- /dev/null +++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeatureConfigInstallerTest.java @@ -0,0 +1,35 @@ +package org.apache.karaf.features.internal.service; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +import java.io.File; + +public class FeatureConfigInstallerTest { + + private void substEqual(final String src, final String subst) { + assertEquals(FeatureConfigInstaller.substFinalName(src), subst); + } + + @Test + public void testSubstFinalName() { + final String karafBase = "/tmp/karaf.base"; + final String foo = "/foo"; + + System.setProperty("karaf.base", karafBase); + System.setProperty("foo", foo); + + substEqual("etc/test.cfg", karafBase + File.separator + "etc/test.cfg"); + substEqual("/etc/test.cfg", karafBase + File.separator + "/etc/test.cfg"); + substEqual("${karaf.base}/etc/test.cfg", karafBase + "/etc/test.cfg"); + substEqual("etc/${foo}/test.cfg", karafBase + File.separator + "etc/" + foo + "/test.cfg"); + substEqual("${foo}/test.cfg", foo + "/test.cfg"); + substEqual("etc${bar}/${bar}test.cfg", karafBase + File.separator + "etc/test.cfg"); + substEqual("${bar}/etc/test.cfg${bar}", karafBase + File.separator + "/etc/test.cfg"); + substEqual("${karaf.base}${bar}/etc/test.cfg", karafBase + "/etc/test.cfg"); + substEqual("etc${}/${foo}/test.cfg", karafBase + File.separator + "etc//test.cfg"); + substEqual("${foo}${bar}/${bar}${foo}", foo + "/" + foo); + } + +}