Using the Apache Commons configuration to interpolate variables, that is $ {variable}, with a list of values ​​in the properties file

I use the Apache Commons configuration to read the properties file, and I am good at interpolating variables as well as extracting multi-valued properties as a list. However, I could not correctly load a property that has several values, where one of them is a link (variable interpolation) to another multivalued property.

Here is an example of my properties file (I also tried using comma-separated syntax):

doc.mime=application/msword doc.mime=application/vnd.openxmlformats-officedocument.wordprocessingml.document doc.mime=${office.mime} office.mime=application/x-tika-msoffice office.mime=application/x-tika-ooxml 

And as I read from him:

 Configuration config = new PropertiesConfiguration("myFile"); final String[] mimesArray = config.getStringArray("doc.mime"); for(String mime : mimesArray) System.out.println(mime); final List<Object> mimesList = config.getList("doc.mime"); System.out.println(mimesList); 

This is the content that I get using any method ( getStringArray and getList ):

[application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/x-tika-msoffice]

This is different from what I expected: the full contents of both doc.mime and office.mime

Does anyone know if it is possible to interpolate the entire list of values ​​in my other list? And if so, how is this done?

+4
source share
2 answers

Commons Configuration

As you know, when interpolating a multi-valued property, Commons Configuration will only allow the first value of this property. See AbstractConfiguration # resolveContainerStore () code line 1177 .

I found some related problems:

CONFIGURATION-28 : Someone wants (and gets) the exact opposite of what you want: only the first value in a multi-valued property.

CONFIGURATION-55 : More discussions about interpolating ambiguous properties:

there is probably no right solution to this problem, as the expected results are highly dependent on the specific use case.

Workaround: merge two lists in code

Definitely simpler than setting interpolation :

 List<Object> mimesList = config.getList("doc.mime"); List<Object> officeList = config.getList("office.mime"); mimesList.addAll(officeList); System.out.println(mimesList); 

Address this issue with Commons configuration project

Changing the entire system interpolation variable is probably difficult. But they could at least clarify the documentation.

+3
source

Well, I need this function in order to: bind the values ​​of individual values ​​with properties and be able to extract them all even by interpolation.

So, I wrote my own interpolation class and custom property configuration. Works well even with backslash and default delimiter values.

So the custom interpolation class:

Class CustomInterPolation

 public class CustomInterpolation extends StrLookup { /* * (non-Javadoc) * * @see org.apache.commons.lang.text.StrLookup#lookup(java.lang.String) */ @Override public String lookup(String arg0) { String result = null; // Get the default delimiter. String delimiter = "" + PropertiesConfiguration.getDefaultListDelimiter(); try { // Load the properties file. Configuration config = new PropertiesConfiguration( "ressources/macro.properties"); if (config.containsKey(arg0)) { // Get all values associated with the propertie. ArrayList<Object> values = (ArrayList<Object>) config .getList(arg0); StringBuilder strBuild = new StringBuilder(); Iterator<Object> itr = values.iterator(); while (itr.hasNext()) { // Append the property to the string. strBuild.append((String) itr.next()); if (itr.hasNext()) { // Adds the delimiter and backslash in order to retrieve // all properties later. strBuild.append("\\" + delimiter); } } result = strBuild.toString(); } } catch (ConfigurationException e) { // Nothing to do here... } // return null or all values concatenated return result; } } 

Now, to properly use this customInterpolation class, we need to use a custom property configuration:

CustomPropertiesConfiguration class

 /** * The Class CustomPropertiesConfiguration. */ public class CustomPropertiesConfiguration extends PropertiesConfiguration { private String delimiter; /** * Instantiates a new custom properties configuration. */ public CustomPropertiesConfiguration() { super(); delimiter = PropertiesConfiguration.getDefaultListDelimiter() + ""; } /** * Instantiates a new custom properties configuration. * * @param file the file * @throws ConfigurationException the configuration exception */ public CustomPropertiesConfiguration (File file) throws ConfigurationException{ super(file); delimiter = PropertiesConfiguration.getDefaultListDelimiter() + ""; } /** * Instantiates a new custom properties configuration. * * @param fileName the file name * @throws ConfigurationException the configuration exception */ public CustomPropertiesConfiguration(String fileName) throws ConfigurationException { super(fileName); delimiter = PropertiesConfiguration.getDefaultListDelimiter() + ""; } /** * Instantiates a new custom properties configuration. * * @param url the url * @throws ConfigurationException the configuration exception */ public CustomPropertiesConfiguration(URL url) throws ConfigurationException{ super(url); delimiter = PropertiesConfiguration.getDefaultListDelimiter() + ""; } /* (non-Javadoc) * @see org.apache.commons.configuration.AbstractConfiguration#getList(java.lang.String) */ @Override public List<Object> getList(String key) { // Get the list of values associated with the property // Implicit call to the custom interpolation class List<Object> properties = super.getList(key); ArrayList<Object> extendedProperties = new ArrayList<Object>(); Iterator<Object> itrProperties = properties.iterator(); // Go through all properties and retrieve values concatenated by the custom interpolation while (itrProperties.hasNext()) { String propertie = (String) itrProperties.next(); if (propertie.contains(delimiter)) { //Split concatenated values. String[] extendedPropertiesTab = propertie.split("\\\\"+delimiter); // Add the retrieved values to the list of values. for (int i = 0; i< extendedPropertiesTab.length; ++i){ extendedProperties.add(extendedPropertiesTab[i]); } } else { extendedProperties.add(propertie); } } return extendedProperties; } } 

And here is a small main class:

 public class TestMacro { /** * @param args */ public static void main(String[] args) { // Load properties file : try { // Add an interpolation to the configuration. // The string "custom" will be used to find value to interpolate // with the custom interpolation ConfigurationInterpolator.registerGlobalLookup("custom", new CustomInterpolation()); // Set the properties configuration. Configuration config = new CustomPropertiesConfiguration( "ressources/macro.properties"); String baseProp = "base.prop"; String firstProp = "first.prop"; String secondProp = "second.prop"; ArrayList<Object> values = (ArrayList<Object>) config .getList(baseProp); System.out.println(baseProp + "=>"); for (int i = 0; i < values.size(); ++i) { System.out.println("[" + i + "]" + values.get(i)); } System.out.println(); values = (ArrayList<Object>) config.getList(firstProp); System.out.println(firstProp + "=>"); for (int i = 0; i < values.size(); ++i) { System.out.println("[" + i + "]" + values.get(i)); } System.out.println(); values = (ArrayList<Object>) config.getList(secondProp); System.out.println(secondProp + "=>"); for (int i = 0; i < values.size(); ++i) { System.out.println("[" + i + "]" + values.get(i)); } } catch (ConfigurationException e) { e.printStackTrace(); } } } 

For tests, I used the following properties file:

 base.prop = /base, /root\\\\\\\\, t\\,t\\,t\\,t\\, first.prop = ${custom:base.prop}, /first\\,/base second.prop = ${custom:first.prop}, /second 

And I get the following output:

 base.prop=> [0]/base [1]/root\\ [2]t,t,t,t, first.prop=> [0]/base [1]/root\\ [2]t,t,t,t, [3]/first,/base second.prop=> [0]/base [1]/root\\ [2]t,t,t,t, [3]/first,/base [4]/second 

As you can see, the solution can handle property values ​​with a backslash and default separator ','. Some templates containing these two elements may not be processed correctly, but this solution should handle the basic values.

0
source

Source: https://habr.com/ru/post/1397888/


All Articles