How to refer to another property in java.util.Properties?

Can a Java properties file refer to a file of other properties?

## define a default directory for Input files dir.default=/home/data/in/ dir.proj1=${dir.default}p1 dir.proj2=${dir.default}p2 dir.proj3=${dir.default}p3 

Is it possible?

+52
java properties
May 16 '09 at 11:50
source share
10 answers

The Chris Mayr XProperties class can be a good starting point.

You can replace the constant anywhere in the property value and even have more than one constant in the value, as in the following example:

 CONST_1 = shoes and ships CONST_2 = sealing wax SomeValue = {CONST_1} and {CONST_2} 

In this example, the SomeValue property evaluates to "shoes, ships, and wax."




See also: http://webcache.googleusercontent.com/search?q=cache:gCgFCpEgmsgJ:www2.sys-con.com/itsg/virtualcd/java/source/6-12/52.html+&cd=1&hl=en&ct = clnk & gl = us

+51
Nov 07 '09 at 0:05
source share

Eproperties is an open source project that provides variable replacement along with several other features, although replacement may be most useful. This is a subclass of java.util.Properties and can be used by any other class that can receive configuration information as Properties.

+12
Nov 06 '09 at 23:54
source share

Commons Config lib can also do this. http://commons.apache.org/configuration/userguide/overview.html#Using_Configuration

However, as already stated, take a look at the EProperties library; http://code.google.com/p/eproperties/

It supports a number of neat features (such as wildcard, nesting, lists), including inclusion, the extension of Java properties, and slightly less weight than Commons Config (which also allows you to include properties using include syntax).

+7
Feb 18 '13 at 0:09
source share

Standard property files are just key-value pairs. In a text format, Properties simply separates the key from the value and performs some simple actions, such as resolving escaped characters. You may be able to define objects in the detailed XML syntax.

If you need your own wildcard syntax, you can manipulate the return value just like with any other string. Alternatively, you can write your own version of Properties or perform wildcard expansion when creating a file.

+6
May 16 '09 at 12:19
source share

The java.util.Properties class will not do this for you. It would not be too difficult to subclass the properties, override the load () method and perform the substitution yourself.

+5
May 16 '09 at 12:14
source share

Since the properties of eproperties are not supported, and the general configuration is dependent on logging (which, ironically, you cannot use it to configure logging), I use this piece of code that only requires commons-lang(3) to load interpolated properties:

 @SuppressWarnings("serial") public static Map<String,String> loadPropertiesMap(InputStream s) throws IOException { final Map<String, String> ordered = new LinkedHashMap<String, String>(); //Hack to use properties class to parse but our map for preserved order Properties bp = new Properties() { @Override public synchronized Object put(Object key, Object value) { ordered.put((String)key, (String)value); return super.put(key, value); } }; bp.load(s); final Map<String,String> resolved = new LinkedHashMap<String, String>(ordered.size()); StrSubstitutor sub = new StrSubstitutor(new StrLookup<String>() { @Override public String lookup(String key) { String value = resolved.get(key); if (value == null) return System.getProperty(key); return value; } }); for (String k : ordered.keySet()) { String value = sub.replace(ordered.get(k)); resolved.put(k, value); } return resolved; } 

Enter

 blah=${user.dir} one=1 two=2 five=5 fifteen=${one}${five} twoonefive=${two}${fifteen} six=6 

Exit

 blah=/current/working/dir one=1 two=2 five=5 fifteen=15 twoonefive=215 six=6 

Obviously, you can convert Map<String,String> back to a Properties object if you need it. I decide based on previously declared system properties and properties, but you can obviously change this in StrSubstitutor.lookup .

+3
Dec 31 '15 at 17:21
source share

In this particular case (and in others as well), you better solve duplication by specifying various properties:

  • change: dir.proj1=dir.default /p1 to dir.proj1_extension=/p1
  • prepend: dir.default to dir.proj1_extension to get the full location of proj1 in your application code.

Do the same for other projects.

+1
Jan 15 '12 at 12:33
source share

The configuration file consists of statements in the format key=value or key:value . Their possible way is when the key value can refer to another key value. The line between opening "$ {" and closing "}" is interpreted as a key. The value of the substituted variable can be defined as a system property or in the configuration file itself.

Because Properties inherits from Hashtable , the put and putAll can be applied to the Properties object .

 Map<String, String> map = new LinkedHashMap<String, String>(); map.put("key", "vlaue"); Properties props = new Properties(); props.putAll( map ); 

work out the @Adam Gent message in detail. commons-text-1.1.jar

 import org.apache.commons.text.StrLookup; import org.apache.commons.text.StrSubstitutor; public class Properties_With_ReferedKeys { public static void main(String[] args) { ClassLoader classLoader = Properties_With_ReferedKeys.class.getClassLoader(); String propertiesFilename = "keys_ReferedKeys.properties"; Properties props = getMappedProperties(classLoader, propertiesFilename); System.out.println( props.getProperty("jdk") ); } public static Properties getMappedProperties( ClassLoader classLoader, String configFilename ) { Properties fileProperties = new Properties(); try { InputStream resourceAsStream = classLoader.getResourceAsStream( configFilename ); Map<String, String> loadPropertiesMap = loadPropertiesMap( resourceAsStream ); Set<String> keySet = loadPropertiesMap.keySet(); System.out.println("Provided 'Key':'Value' pairs are..."); for (String key : keySet) { System.out.println( key + " : " + loadPropertiesMap.get(key) ); } fileProperties.putAll( loadPropertiesMap ); } catch ( IOException e ) { e.printStackTrace(); } return fileProperties; } public static Map<String,String> loadPropertiesMap( InputStream inputStream ) throws IOException { final Map<String, String> unResolvedProps = new LinkedHashMap<String, String>(); /*Reads a property list (key and element pairs) from the input byte stream. * The input stream is in a simple line-oriented format. */ @SuppressWarnings("serial") Properties props = new Properties() { @Override public synchronized Object put(Object key, Object value) { unResolvedProps.put( (String)key, (String)value ); return super.put( key, value ); } }; props.load( inputStream ); final Map<String,String> resolvedProps = new LinkedHashMap<String, String>( unResolvedProps.size() ); // Substitutes variables within a string by values. StrSubstitutor sub = new StrSubstitutor( new StrLookup<String>() { @Override public String lookup( String key ) { /*The value of the key is first searched in the configuration file, * and if not found there, it is then searched in the system properties.*/ String value = resolvedProps.get( key ); if (value == null) return System.getProperty( key ); return value; } } ); for ( String key : unResolvedProps.keySet() ) { /*Replaces all the occurrences of variables with their matching values from the resolver using the given * source string as a template. By using the default ${} the corresponding value replaces the ${variableName} sequence.*/ String value = sub.replace( unResolvedProps.get( key ) ); resolvedProps.put( key, value ); } return resolvedProps; } } 

Configuration file "If you want the link to be ignored and not replaced, you can use the format below.

  $${${name}} must be used for output ${ Yash }. EX: jdk = ${jre-1.8} 

File: keys_ReferedKeys.properties

 # MySQL Key for each developer for their local machine dbIP = 127.0.0.1 dbName = myApplicationDB dbUser = scott dbPassword = tiger # MySQL Properties # To replace fixed-keys with corresponding build environment values. like « predev,testing,preprd. config.db.driverClassName : com.mysql.jdbc.Driver config.db.url : jdbc:mysql://${dbIP}:3306/${dbName} config.db.username : ${dbUser} config.db.password : ${dbPassword} # SystemProperties userDir = ${user.dir} os.name = ${os.name} java.version = ${java.version} java.specification.version = ${java.specification.version} # If you want reference to be ignored and won't be replaced. # $${${name}} must be used for output ${ Yash }. EX: jdk = ${jre-1.8} jdk = $${jre-${java.specification.version}} 



Example Java properties (key = value) log4j.properties

+1
Dec 15 '17 at 9:14
source share

Below is a snippet of code in Java for reading properties that reference other properties. In particular, these are repeated requests, but may be different.

 LinkedHashMap<String, String> sqlsRaw = loadPropertiesFromFile(); LinkedHashMap<String, String> sqls = new LinkedHashMap<>(); StrSubstitutor substitutor = new StrSubstitutor(sqls); for (Map.Entry<String, String> entry : sqlsRaw.entrySet()) { String sql = entry.getValue(); try { sql = substitutor.replace(sql); } catch (Exception e) { throw new RuntimeException("Found an sql with a non replaced reference to another. Please validate that the required key was defined before this sql: " + entry.getValue(), e); } sqls.put(entry.getKey(), sql); } 

Example Properties:

 key1=value1 key21=value2 ${key1} 

After starting, key21 will have value2 value1 .

* Using apache StrSubstitutor .

0
Aug 11 '16 at 15:37
source share

None of the above solutions I really liked. EProperties is not supported and not available in Maven Central. Commons Config is too large for this. The StrSubstitutor in the public domain is deprecated.

My solution relies only on plain text:

 public static Properties interpolateProperties(Properties rawProperties) { Properties newProperties = new Properties(); interpolateProperties(rawProperties, newProperties); return newProperties; } public static void interpolateProperties(Properties rawProperties, Properties dstProperties) { StringSubstitutor sub = new StringSubstitutor((Map)rawProperties); for (Map.Entry<Object, Object> e : rawProperties.entrySet()) { dstProperties.put(e.getKey(), sub.replace(e.getValue())); } } 

i.e:

 Properties props = new Properties(); props.put("another_name", "lqbweb"); props.put("car", "this is a car from ${name}"); props.put("name", "${another_name}"); System.out.println(interpolateProperties(props)); 

prints out:

{car = this is a car from ruben, name = ruben, another name = ruben}

0
Jul 04 '19 at 10:26
source share



All Articles