views:

208

answers:

3

What I want to accomplish is a tool that filters my files replacing the occurrences of strings in this format ${some.property} with a value got from a properties file (just like Maven's or Ant's file filtering feature).

My first approach was to use Ant API (copy-task) or Maven Filtering component but both include many unnecessary dependencies and my program should be lightweight. After, I searched a little in Apache Common haven't found anything yet.

Is there an efficient (and elegant) solution to my problem?

+2  A: 

The most efficient solution is using a templating engine. There are few, widely used engines, that comes in a single jar :

dfa
+1  A: 

If this is configuration related, I would recommend Apache Commons Configuration. It will do varaible replacement on the fly.

It has other nice features, like handling XML, properties, Apple's pList formats.

ZZ Coder
A: 

The fastest and least encumbered way to do this will be to write your own. It shouldn't be that tough - probably take a couple of hours to write the tests and put the code together.

A suggested algorithm:

Start by loading the properties file into a Properties object.

Take an input reader (use BufferedReader if you will be reading files from a source with high latency), and grab each character, looking for a {. If the character isn't a {, emit the character to an output stream. If you find a {, start scanning for a }, accumulating the characters in a StringBuilder. If you hit another {, flush the StringBuilder to the output stream and start over. You may want to have some maximum # of characters that you allow the property key to contain. If you hit that limit, flush the StringBuilder to the output stream.

If you find a token surrounded by {}, grab the key name and do a Properties#getProperty() call. If you get a result, emit the result to the output stream. If you don't get a result, do something different.

If you want to get clever, once you get the result, instead of sending the result directly to the output stream, pre-pend it to the input stream (not literally - you'd do some logic to make it work), and continue. That way if any of the properties themselves refer to other properties, the algorithm effectively goes recursive.

If you are really going for performance, you could use a ByteBuffer instead of an input stream/writer

Kevin Day