Maybe we should just include a copy of the org.apache.felix.utils.properties.InterpolationHelper in the main jar instead of maintaining duplicate code. This class is already either directly or through the felix utils Properties file
On Mon, Mar 26, 2012 at 18:12, <[email protected]> wrote: > Author: cschneider > Date: Mon Mar 26 16:12:39 2012 > New Revision: 1305423 > > URL: http://svn.apache.org/viewvc?rev=1305423&view=rev > Log: > KARAF-713 Extracting variable substitution and FrameworkFactory > > Added: > > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/SubstHelper.java > Modified: > karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java > karaf/trunk/main/src/main/java/org/apache/karaf/main/Stop.java > > > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/BootstrapLogManager.java > > Modified: karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java > URL: > http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java?rev=1305423&r1=1305422&r2=1305423&view=diff > > ============================================================================== > --- karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java > (original) > +++ karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java Mon Mar > 26 16:12:39 2012 > @@ -57,6 +57,7 @@ import org.apache.karaf.main.lock.Simple > import org.apache.karaf.main.util.BootstrapLogManager; > import org.apache.karaf.main.util.ServerInfoImpl; > import org.apache.karaf.main.util.StringMap; > +import org.apache.karaf.main.util.SubstHelper; > import org.apache.karaf.main.util.Utils; > import org.osgi.framework.Bundle; > import org.osgi.framework.BundleActivator; > @@ -274,16 +275,9 @@ public class Main { > lockDelay = > Integer.parseInt(configProps.getProperty(PROPERTY_LOCK_DELAY, > Integer.toString(lockDelay))); > configProps.setProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, > Integer.toString(lockStartLevel)); > shutdownTimeout = > Integer.parseInt(configProps.getProperty(KARAF_SHUTDOWN_TIMEOUT, > Integer.toString(shutdownTimeout))); > - // Start up the OSGI framework > > - String factoryClass = > configProps.getProperty(KARAF_FRAMEWORK_FACTORY); > - if (factoryClass == null) { > - InputStream is = > classLoader.getResourceAsStream("META-INF/services/" + > FrameworkFactory.class.getName()); > - BufferedReader br = new BufferedReader(new > InputStreamReader(is, "UTF-8")); > - factoryClass = br.readLine(); > - br.close(); > - } > - FrameworkFactory factory = (FrameworkFactory) > classLoader.loadClass(factoryClass).newInstance(); > + // Start up the OSGI framework > + FrameworkFactory factory = loadFrameworkFactory(classLoader); > framework = factory.newFramework(new StringMap(configProps, > false)); > framework.init(); > // Process properties > @@ -304,6 +298,18 @@ public class Main { > }.start(); > } > > + private FrameworkFactory loadFrameworkFactory(ClassLoader > classLoader) throws Exception { > + String factoryClass = > configProps.getProperty(KARAF_FRAMEWORK_FACTORY); > + if (factoryClass == null) { > + InputStream is = > classLoader.getResourceAsStream("META-INF/services/" + > FrameworkFactory.class.getName()); > + BufferedReader br = new BufferedReader(new > InputStreamReader(is, "UTF-8")); > + factoryClass = br.readLine(); > + br.close(); > + } > + FrameworkFactory factory = (FrameworkFactory) > classLoader.loadClass(factoryClass).newInstance(); > + return factory; > + } > + > private void startKarafActivators(ClassLoader classLoader) throws > IOException { > Enumeration<URL> urls = > classLoader.getResources("META-INF/MANIFEST.MF"); > while (urls != null && urls.hasMoreElements()) { > @@ -811,7 +817,7 @@ public class Main { > for (Enumeration e = props.propertyNames(); e.hasMoreElements();) { > String name = (String) e.nextElement(); > String value = System.getProperty(name, > props.getProperty(name)); > - System.setProperty(name, substVars(value, name, null, props)); > + System.setProperty(name, SubstHelper.substVars(value, name, > null, props)); > } > } > > @@ -857,7 +863,7 @@ public class Main { > for (Enumeration e = configProps.propertyNames(); > e.hasMoreElements();) { > String name = (String) e.nextElement(); > configProps.setProperty(name, > - substVars(configProps.getProperty(name), name, null, > configProps)); > + SubstHelper.substVars(configProps.getProperty(name), > name, null, configProps)); > } > > return configProps; > @@ -1197,121 +1203,6 @@ public class Main { > } > } > > - private static final String DELIM_START = "${"; > - private static final String DELIM_STOP = "}"; > - > - /** > - * <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. > - * @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, > Properties configProps) > - throws IllegalArgumentException { > - // If there is currently no cycle map, then create > - // one for detecting cycles for this invocation. > - if (cycleMap == null) { > - cycleMap = new HashMap<String, String>(); > - } > - > - // Put the current key in the cycle map. > - cycleMap.put(currentKey, currentKey); > - > - // Assume we have a value that is something like: > - // "leading ${foo.${bar}} middle ${baz} trailing" > - > - // Find the first ending '}' variable delimiter, which > - // will correspond to the first deepest nested variable > - // placeholder. > - int stopDelim = val.indexOf(DELIM_STOP); > - > - // Find the matching starting "${" variable delimiter > - // by looping until we find a start delimiter that is > - // greater than the stop delimiter we have found. > - int startDelim = val.indexOf(DELIM_START); > - while (stopDelim >= 0) { > - int idx = val.indexOf(DELIM_START, startDelim + > DELIM_START.length()); > - if ((idx < 0) || (idx > stopDelim)) { > - break; > - } else if (idx < stopDelim) { > - startDelim = idx; > - } > - } > - > - // If we do not have a start or stop delimiter, then just > - // return the existing value. > - if ((startDelim < 0) && (stopDelim < 0)) { > - return val; > - } > - // At this point, we found a stop delimiter without a start, > - // so throw an exception. > - else if (((startDelim < 0) || (startDelim > stopDelim)) > - && (stopDelim >= 0)) { > - throw new IllegalArgumentException( > - "stop delimiter with no start delimiter: " > - + val); > - } > - > - // At this point, we have found a variable placeholder so > - // we must perform a variable substitution on it. > - // Using the start and stop delimiter indices, extract > - // the first, deepest nested variable placeholder. > - String variable = > - val.substring(startDelim + DELIM_START.length(), > stopDelim); > - > - // Verify that this is not a recursive variable reference. > - if (cycleMap.get(variable) != null) { > - throw new IllegalArgumentException( > - "recursive variable reference: " + variable); > - } > - > - // Get the value of the deepest nested variable placeholder. > - // Try to configuration properties first. > - String substValue = (configProps != null) > - ? configProps.getProperty(variable, null) > - : null; > - if (substValue == null) { > - // Ignore unknown property values. > - substValue = System.getProperty(variable, ""); > - } > - > - // Remove the found variable from the cycle map, since > - // it may appear more than once in the value and we don't > - // want such situations to appear as a recursive reference. > - cycleMap.remove(variable); > - > - // Append the leading characters, the substituted value of > - // the variable, and the trailing characters to get the new > - // value. > - val = val.substring(0, startDelim) > - + substValue > - + val.substring(stopDelim + DELIM_STOP.length(), > val.length()); > - > - // Now perform substitution again, since there could still > - // be substitutions to make. > - val = substVars(val, currentKey, cycleMap, configProps); > - > - // Return the value. > - return val; > - } > - > /** > * Retrieve the arguments used when launching Karaf > * > > Modified: karaf/trunk/main/src/main/java/org/apache/karaf/main/Stop.java > URL: > http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/apache/karaf/main/Stop.java?rev=1305423&r1=1305422&r2=1305423&view=diff > > ============================================================================== > --- karaf/trunk/main/src/main/java/org/apache/karaf/main/Stop.java > (original) > +++ karaf/trunk/main/src/main/java/org/apache/karaf/main/Stop.java Mon Mar > 26 16:12:39 2012 > @@ -27,6 +27,7 @@ import java.net.URL; > import java.util.Enumeration; > import java.util.Properties; > > +import org.apache.karaf.main.util.SubstHelper; > import org.apache.karaf.main.util.Utils; > > /** > @@ -55,7 +56,7 @@ public class Stop { > for (Enumeration e = props.propertyNames(); e.hasMoreElements();) { > String name = (String) e.nextElement(); > props.setProperty(name, > - Main.substVars(props.getProperty(name), name, null, > props)); > + SubstHelper.substVars(props.getProperty(name), name, > null, props)); > } > > int port = > Integer.parseInt(props.getProperty(Main.KARAF_SHUTDOWN_PORT, "0")); > > Modified: > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/BootstrapLogManager.java > URL: > http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/apache/karaf/main/util/BootstrapLogManager.java?rev=1305423&r1=1305422&r2=1305423&view=diff > > ============================================================================== > --- > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/BootstrapLogManager.java > (original) > +++ > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/BootstrapLogManager.java > Mon Mar 26 16:12:39 2012 > @@ -28,7 +28,6 @@ import java.util.logging.Handler; > import java.util.logging.LogRecord; > import java.util.logging.StreamHandler; > > -import org.apache.karaf.main.Main; > > /** > * Convenience class for configuring java.util.logging to append to > @@ -70,7 +69,7 @@ public class BootstrapLogManager { > } > } > } > - filename = > Main.substVars(props.getProperty("log4j.appender.out.file"), > "log4j.appender.out.file", null, null); > + filename = > SubstHelper.substVars(props.getProperty("log4j.appender.out.file"), > "log4j.appender.out.file", null, null); > log = new File(filename); > } > > > Added: > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/SubstHelper.java > URL: > http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/apache/karaf/main/util/SubstHelper.java?rev=1305423&view=auto > > ============================================================================== > --- > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/SubstHelper.java > (added) > +++ > karaf/trunk/main/src/main/java/org/apache/karaf/main/util/SubstHelper.java > Mon Mar 26 16:12:39 2012 > @@ -0,0 +1,141 @@ > +/* > + * 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.main.util; > + > +import java.util.HashMap; > +import java.util.Map; > +import java.util.Properties; > + > +public class SubstHelper { > + private static final String DELIM_START = "${"; > + private static final String DELIM_STOP = "}"; > + > + /** > + * <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. > + * @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, > Properties configProps) > + throws IllegalArgumentException { > + // If there is currently no cycle map, then create > + // one for detecting cycles for this invocation. > + if (cycleMap == null) { > + cycleMap = new HashMap<String, String>(); > + } > + > + // Put the current key in the cycle map. > + cycleMap.put(currentKey, currentKey); > + > + // Assume we have a value that is something like: > + // "leading ${foo.${bar}} middle ${baz} trailing" > + > + // Find the first ending '}' variable delimiter, which > + // will correspond to the first deepest nested variable > + // placeholder. > + int stopDelim = val.indexOf(DELIM_STOP); > + > + // Find the matching starting "${" variable delimiter > + // by looping until we find a start delimiter that is > + // greater than the stop delimiter we have found. > + int startDelim = val.indexOf(DELIM_START); > + while (stopDelim >= 0) { > + int idx = val.indexOf(DELIM_START, startDelim + > DELIM_START.length()); > + if ((idx < 0) || (idx > stopDelim)) { > + break; > + } else if (idx < stopDelim) { > + startDelim = idx; > + } > + } > + > + // If we do not have a start or stop delimiter, then just > + // return the existing value. > + if ((startDelim < 0) && (stopDelim < 0)) { > + return val; > + } > + // At this point, we found a stop delimiter without a start, > + // so throw an exception. > + else if (((startDelim < 0) || (startDelim > stopDelim)) > + && (stopDelim >= 0)) { > + throw new IllegalArgumentException( > + "stop delimiter with no start delimiter: " > + + val); > + } > + > + // At this point, we have found a variable placeholder so > + // we must perform a variable substitution on it. > + // Using the start and stop delimiter indices, extract > + // the first, deepest nested variable placeholder. > + String variable = > + val.substring(startDelim + DELIM_START.length(), > stopDelim); > + > + // Verify that this is not a recursive variable reference. > + if (cycleMap.get(variable) != null) { > + throw new IllegalArgumentException( > + "recursive variable reference: " + variable); > + } > + > + // Get the value of the deepest nested variable placeholder. > + // Try to configuration properties first. > + String substValue = (configProps != null) > + ? configProps.getProperty(variable, null) > + : null; > + if (substValue == null) { > + // Ignore unknown property values. > + substValue = System.getProperty(variable, ""); > + } > + > + // Remove the found variable from the cycle map, since > + // it may appear more than once in the value and we don't > + // want such situations to appear as a recursive reference. > + cycleMap.remove(variable); > + > + // Append the leading characters, the substituted value of > + // the variable, and the trailing characters to get the new > + // value. > + val = val.substring(0, startDelim) > + + substValue > + + val.substring(stopDelim + DELIM_STOP.length(), > val.length()); > + > + // Now perform substitution again, since there could still > + // be substitutions to make. > + val = substVars(val, currentKey, cycleMap, configProps); > + > + // Return the value. > + return val; > + } > + > +} > > > -- ------------------------ Guillaume Nodet ------------------------ Blog: http://gnodet.blogspot.com/ ------------------------ FuseSource, Integration everywhere http://fusesource.com
