[FELIX-2988] Allow the substitution methods to receive a callback to obtain custom values
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1134229 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/utils/src/main/java/org/apache/felix/utils/properties/InterpolationHelper.java b/utils/src/main/java/org/apache/felix/utils/properties/InterpolationHelper.java
index c9c210f..66178f0 100644
--- a/utils/src/main/java/org/apache/felix/utils/properties/InterpolationHelper.java
+++ b/utils/src/main/java/org/apache/felix/utils/properties/InterpolationHelper.java
@@ -16,22 +16,10 @@
*/
package org.apache.felix.utils.properties;
-import org.osgi.framework.BundleContext;
+import java.util.HashMap;
+import java.util.Map;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URL;
-import java.util.*;
+import org.osgi.framework.BundleContext;
/**
* <p>
@@ -50,6 +38,16 @@
private static final String DELIM_START = "${";
private static final String DELIM_STOP = "}";
+
+ /**
+ * Callback for substitution
+ */
+ public interface SubstitutionCallback {
+
+ public String getValue(String key);
+
+ }
+
/**
* Perform substitution on a property set
*
@@ -57,7 +55,7 @@
*/
public static void performSubstitution(Map<String,String> properties)
{
- performSubstitution(properties, null);
+ performSubstitution(properties, (BundleContext) null);
}
/**
@@ -67,10 +65,20 @@
*/
public static void performSubstitution(Map<String,String> properties, BundleContext context)
{
+ performSubstitution(properties, new BundleContextSubstitutionCallback(context));
+ }
+
+ /**
+ * Perform substitution on a property set
+ *
+ * @param properties the property set to perform substitution on
+ */
+ public static void performSubstitution(Map<String,String> properties, SubstitutionCallback callback)
+ {
for (String name : properties.keySet())
{
String value = properties.get(name);
- properties.put(name, substVars(value, name, null, properties, context));
+ properties.put(name, substVars(value, name, null, properties, callback));
}
}
@@ -86,6 +94,7 @@
* are substituted from inner most to outer most. Configuration
* properties override system properties.
* </p>
+ *
* @param val The string on which to perform property substitution.
* @param currentKey The key of the property being evaluated used to
* detect cycles.
@@ -101,7 +110,40 @@
Map<String,String> cycleMap,
Map<String,String> configProps,
BundleContext context)
- throws IllegalArgumentException
+ throws IllegalArgumentException
+ {
+ return substVars(val, currentKey, cycleMap, configProps, new BundleContextSubstitutionCallback(context));
+ }
+
+ /**
+ * <p>
+ * This method performs property variable substitution on the
+ * specified value. If the specified value contains the syntax
+ * <tt>${<prop-name>}</tt>, where <tt><prop-name></tt>
+ * refers to either a configuration property or a system property,
+ * then the corresponding property value is substituted for the variable
+ * placeholder. Multiple variable placeholders may exist in the
+ * specified value as well as nested variable placeholders, which
+ * are substituted from inner most to outer most. Configuration
+ * properties override system properties.
+ * </p>
+ *
+ * @param val The string on which to perform property substitution.
+ * @param currentKey The key of the property being evaluated used to
+ * detect cycles.
+ * @param cycleMap Map of variable references used to detect nested cycles.
+ * @param configProps Set of configuration properties.
+ * @param callback the callback to obtain substitution values
+ * @return The value of the specified string after system property substitution.
+ * @throws IllegalArgumentException If there was a syntax error in the
+ * property placeholder syntax or a recursive variable reference.
+ **/
+ public static String substVars(String val,
+ String currentKey,
+ Map<String,String> cycleMap,
+ Map<String,String> configProps,
+ SubstitutionCallback callback)
+ throws IllegalArgumentException
{
if (cycleMap == null)
{
@@ -168,17 +210,16 @@
{
substValue = "";
}
- else if (context != null)
- {
- substValue = context.getProperty(variable);
- if (substValue == null)
- {
- substValue = "";
- }
- }
else
{
- substValue = System.getProperty(variable, "");
+ if (callback != null)
+ {
+ substValue = callback.getValue(variable);
+ }
+ if (substValue == null)
+ {
+ substValue = System.getProperty(variable, "");
+ }
}
}
@@ -194,7 +235,7 @@
// Now perform substitution again, since there could still
// be substitutions to make.
- val = substVars(val, currentKey, cycleMap, configProps, context);
+ val = substVars(val, currentKey, cycleMap, configProps, callback);
// Remove escape characters preceding {, } and \
val = unescape(val);
@@ -203,7 +244,8 @@
return val;
}
- private static String unescape(String val) {
+ private static String unescape(String val)
+ {
int escape = val.indexOf(ESCAPE_CHAR);
while (escape >= 0 && escape < val.length() - 1)
{
@@ -217,4 +259,28 @@
return val;
}
+ private static class BundleContextSubstitutionCallback implements SubstitutionCallback
+ {
+ private final BundleContext context;
+
+ private BundleContextSubstitutionCallback(BundleContext context)
+ {
+ this.context = context;
+ }
+
+ public String getValue(String key)
+ {
+ String value = null;
+ if (context != null)
+ {
+ value = context.getProperty(key);
+ }
+ if (value == null)
+ {
+ value = System.getProperty(key, "");
+ }
+ return value;
+ }
+ }
+
}
\ No newline at end of file