I don't understand how I've ever been without Spring framework. It is so tasty. I will use it whenever I can. Do you think a step from EJB 2.1 to EJB 3.0 is a revolution? Then step from EJB 3.0 to Spring 2.0 is a revolution no less: flexible IoC, nasty testing out of box, standalone or web or whatever execution, annotations, if you prefer your app knows nothing about spring (no direct dependencies on spring classes) and so on. But that is not an issue of this post. As an example of spring ideas I am going to show you how spring can be easily extended for your needs. In my case I wanted to use measured values right in a bean property definition. I.e. instead of using a value 120013 calculated behind the scene (60*2*1000 + 13) I wanted a human suitable representation like a "2min 13ms". And to achive it I've created a small project.
Download
the archive.
Uncompress it.
Do
mvn install from command line inside the archive's folder.
Now you can use springmeasure as the dependency in your own project (artifactId: springmeasure, groupId: ru.toril.springmeasure, verision: 1.0).
In your application context xml add the following line:
<bean class="ru.toril.springmeasure.MeasureConfigurer" />
From now you can write following (as an example):
<bean class="some class you want"
p:value1="{${test.length}}m"
p:value2="{4GiB 200MiB}MiB"
p:value3="{400ms}s." />
The property value1 is configured with PropertyPlaceholderConfigurer in addition to MeasureConfigurer, whereas test.length property is set to "8km".
As you already noticed springmeasure is written to support symbols of Si. A format of value is as following:
{sequence of space-separated values with symbol suffix joined to value}outputSymbol
An output symbol may be followed by the dot marking that an output value is not to be rounded.
You may find out more about format looking at the following test lines:
// IT symbols (bits, bytes)
assertEquals ("2048", convert ("{2KiB}B"));
assertEquals ("16384", convert ("{2KiB}b"));
assertEquals ("11", convert ("{1B 3b}b"));
assertEquals ("10000000", convert ("{ 10MB }B"));
assertEquals ("500", convert ("{ 0.5kB }B"));
assertEquals ("2", convert (" { 2048B 100B 3b }KiB "));
assertEquals ("2.098", convert (" { 2048B 100B 3b }KiB. ").substring (0, 5));
// Time (minutes, seconds, hours, days)
assertEquals ("600", convert ("{10min}s"));
assertEquals ("615", convert ("{10min 15s}s"));
assertEquals ("615000", convert ("{10min 15s}ms"));
assertEquals ("615001000000003", convert ("{10min 15s 1ms 3ps}ps"));
assertEquals ("70", convert ("{1h 10min}min"));
// Length (meters)
assertEquals ("0.5", convert ("{5mm}cm."));
assertEquals ("2", convert ("{2000mm}m"));
// Any other Si value
assertEquals ("0.5", convert ("{5m*}c*."));
assertEquals ("2", convert ("{2000m*}*"));
Here is a real life usage examples:
<bean id="monitorTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"
p:period="{30s}ms" ... />
<bean id="monitor"
class="ru.toril.....model.Monitor"
p:maxAllowedIdle="{2h}ms"
p:maxAllowedSize="{2MiB}B"
p:minFreeSize="{2GiB}B"
p:maxSleepTime="{1min}ms" ... />