Using Apache Commons Configuration to do variable interpolation, i.e. ${variable}, with a list of values in a properties file

rodrigo.garcia picture rodrigo.garcia · Feb 22, 2012 · Viewed 7.3k times · Source

I am using Apache Commons Configuration to read a properties file, and I am perfectly able to do variable interpolation, and also to retrieve multi-valued properties as a list. However, I haven't been able to correctly load a property which has several values, where one of them is a reference (variable interpolation) to another multi-valued property.

Here's an example of my properties file (I have 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 how I read from it:

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 I get with either method (getStringArray and getList):

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

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

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

Answer

Arend v. Reinersdorff picture Arend v. Reinersdorff · Feb 23, 2012

What Commons Configuration does

As you found out: When interpolating a multi-valued property Commons Configuration will only resolve the first value of that property. See the code at AbstractConfiguration#resolveContainerStore() line 1177.

I found some related issues:

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 discussion about interpolation of multi-valued properties:

there is probably no correct solution to this problem because the expected results strongly depend on a concrete use case

Workaround: Combine the two lists in code

Definitely easier than customizing interpolation:

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

Raise this issue with the Commons Configuration project

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