Come fare riferimento a un’altra proprietà in java.util.Properties?

Il file delle proprietà Java può fare riferimento ad altri file di proprietà?

## 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 

È ansible?

Questo è quello che vuoi, è un po ‘vecchio, ma può funzionare per le tue esigenze.

Abilitazione della sostituzione costante nei valori delle proprietà

È ansible sostituire una costante in qualsiasi punto del valore della proprietà e persino avere più di una costante all’interno di un valore, come nell’esempio seguente:

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

In questo esempio, la proprietà “SomeValue” restituisce “scarpe e navi e ceralacca”.

Eproperties è il progetto open source che fornisce una sostituzione variabile insieme ad alcune altre funzionalità, sebbene la sostituzione possa essere probabilmente la più utile. È una sottoclass di java.util.Properties e può essere utilizzata da qualsiasi altra class che può richiedere informazioni di configurazione come Proprietà.

I file di proprietà standard sono solo coppie chiave-valore. Nel formato di testo, Properties separa semplicemente la chiave dal valore e fa alcune cose semplici come consentire caratteri sfuggiti. Potrebbe essere ansible definire quadro nella syntax XML dettagliata.

Se si desidera la propria syntax di sostituzione, è ansible modificare un valore restituito come si farebbe con qualsiasi altra stringa. In alternativa, è ansible scrivere la propria versione di Properties o effettuare la sostituzione durante la generazione del file.

Anche la Commons Config lib può farlo. http://commons.apache.org/configuration/userguide/overview.html#Using_Configuration

Tuttavia, come già sottolineato, dai un’occhiata alla libreria EProperties; http://code.google.com/p/eproperties/

Supporta un certo numero di caratteristiche ordinate (come la sostituzione, l’annidamento, le liste) inclusa l’inclusione, estende le proprietà Java ed è un po ‘più leggero di Commons Config (che consente anche di includere proprietà usando la syntax di inclusione).

La class java.util.Properties non lo farà per te. Non sarebbe troppo difficile creare una sottoclass di proprietà, sovrascrivere il metodo load () e eseguire personalmente la sostituzione.

Poiché eproperties è un po ‘non mantenuto e la configurazione commons ha una dipendenza dal logging (che ironicamente significa che non puoi usarlo per configurare il logging) Io uso questo snippet di codice che richiede solo commons-lang(3) per caricare le proprietà interpolate:

 @SuppressWarnings("serial") public static Map loadPropertiesMap(InputStream s) throws IOException { final Map ordered = new LinkedHashMap(); //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 resolved = new LinkedHashMap(ordered.size()); StrSubstitutor sub = new StrSubstitutor(new StrLookup() { @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; } 

Input :

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

Uscita :

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

Ovviamente è ansible convertire Map in un object Properties se ne hai bisogno. Risolvi in ​​base alle proprietà e alle proprietà di sistema precedentemente dichiarate, ma potresti ovviamente modificarle in StrSubstitutor.lookup .

In questo caso particolare (e anche in altri ), è meglio risolvere la duplicazione definendo proprietà differenti:

  1. change: dir.proj1=dir.default /p1 in dir.proj1_extension=/p1
  2. dir.default : dir.default a dir.proj1_extension per ottenere la posizione completa di proj1 nel codice dell’applicazione.

Fai lo stesso per gli altri progetti.

Di seguito è riportato uno snippet di codice in Java per la lettura di proprietà che fanno riferimento ad altre proprietà. In particolare, si tratta di query riutilizzabili, ma possono essere anche altre cose.

 LinkedHashMap sqlsRaw = loadPropertiesFromFile(); LinkedHashMap sqls = new LinkedHashMap<>(); StrSubstitutor substitutor = new StrSubstitutor(sqls); for (Map.Entry 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); } 

Proprietà di esempio:

 key1=value1 key21=value2 ${key1} 

Dopo aver eseguito ciò, la key21 avrà il valore value2 value1 .

* Utilizzo di StrSubstitutor di StrSubstitutor .

Il file di configurazione è costituito da istruzioni nel formato key=value o key:value . Sono possibili in cui un valore chiave può riferirsi a un altro valore chiave. La stringa tra un’apertura “$ {“ e la chiusura “}” è interpretata come una chiave. Il valore della variabile sostituita può essere definito come una proprietà di sistema o nel file di configurazione stesso.

Poiché le Properties ereditano da Hashtable , i metodi put e putAll possono essere applicati a un Properties object .

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

elaborando il post di @Adam Gent in-dettaglio. 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 loadPropertiesMap = loadPropertiesMap( resourceAsStream ); Set 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 loadPropertiesMap( InputStream inputStream ) throws IOException { final Map unResolvedProps = new LinkedHashMap(); /*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 resolvedProps = new LinkedHashMap( unResolvedProps.size() ); // Substitutes variables within a string by values. StrSubstitutor sub = new StrSubstitutor( new StrLookup() { @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; } } 

File di configurazione «Se vuoi che il riferimento sia ignorato e non venga sostituito, puoi usare il formato seguente.

  $${${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}} 

Esempio di formato di proprietà Java (chiave = valore) log4j.properties