- Blog Xebia France - -
Posted By Guillaume Mathias One on Wednesday, May 7th, 2008 13:21 In Divers 2 Comments
We are going to see how create a mini - DSL to write expressions cron - used to scheduler batch - in a more legible way. Instead of writing "* */5 * * *?" we will grab "every (5.mn)", and right away you understand better that the batch will be thrown all 5mn!
Domain-Specific Language () is a language especially conceived for a definite domain. In opposition, non-specialised languages as the Popular dance allow to treat any types of problems but with a quantity of code often more important and a complexity more l v e.
Of course, for an application web, it is preferable to use of the Popular dance but for some definite problems the use of DSL can avoid you many lines of code or allows you at least to clarify an algorithm (and therefore to make it more maintenable). Ideally, the experts of domain can write themselves code with DSL.
Groovy is a dynamic language based on JVM - that is scripts Groovy generate.class files interpreted by JVM - and DSL takes part well in the creation of internal DSL (who spreads an existent language, Groovy in this case). It allows him to integrate very easily with the Popular dance.
We are going to approach some of this functionality through a case in point: expressions cron. Coming from the world Unix, these expressions serve for scheduler of jobs via expressions of style "* 5/10 * * *?" which are certainly very short to write, but frankly not clear for the non-initiating. They are going to be make more legible...
The continuation of the article requires some bases in Groovy, also if you do not know what is a closure or if the Groovy syntax is you completely foreigner, I invite you to read the tutorial before beginning. Its syntax close to the Popular dance will allow to arrest language fast.
A cron expression allows to describe a temporal complex combination of type "every last Friday from the month till 10 h".
She is composed of 6 fields + 1 optional field:
For every field it is possible to use following characters (example of the field the "hour "):
So only one gives information one of 2 fields days, other one must be in '? '.
There are some more other special characters which we will not approach here.
Some examples:
Let us begin by defining a class representing this type of expression:
We can already create expressions cron with the aid of parametres called:
He does not need there to define with specific constructor, in Groovy it is possible to cross in parametre stocks of properties.
However, the use of a constructor remains rather technical (New), and it is necessary to specify units " mn " and " s " even when they belong to "0 ". We are going to try to make him more legible for an average user: "new cron (h: '8 ', mn: '0 ', s: '0 ')"-> "at (8.h)".
First of all, it is necessary to be able to interpret "8.h ". 8 Integer is, but h is not a property defined with the class Integer.
We are going to intercept the calls of properties on the class Integer with the aid of and return an object TimeUnit which will represent this unity of time:
All objects in Groovy have an attribute metaClass who allows introspection. The class Class also has this attribute but it is a bit particular: it is about ExpandoMetaClass more precisely. This metaClass allows to enrich the behaviour of a class by topping up to him methods, properties or there .
In example above we overloaded getProperty method () to intercept all properties called on Integer.
Delegate variable refers to the authority on which property is called.
And variable it, implicit in any closure, corresponds here in the name of called property.
The method at remains to define which takes in parametre TimeUnit and turns an expression Cron:
The use of parentheses around (Time.unit) is necessary here to point out to Groovy that it is about a variable and about a character string" (Time.unit)".
Let us bring some change a bit in method to be possible cross several TimeUnit, as in "at 8 h, 10 h, and 14 h":
We are going to replace */5 now "* * * *?" by "every (5.mn)", what means "all 5mn"!
Let us try now to combine these 2 criteria: they want to translate "at 2 h, every quarter" by "at (2.h) + every (15.mn)".
Certainly it is not perhaps the most elegant way, but it allows us to see the surcharge of operators.
In Groovy practically all operators are possible be overloaded.
It is enough to overload method with the corresponding name. Here, we are going to overload the operator '+ ', that is to say method more:
We go through the properties of the class cron by using introspection on its metaClass, and for every property, they method is called compute which concat ne 2 stocks with a comma. Zero value is however considered to be space, it is therefore crushed if need. This realisation is far from managing all cases, but it is enough for the present examples.
We can then enrich our DSL to interpret every Friday "(at midnight)", by using constants:
You understood principle, it would be possible to continue enriching DSL, by adding for example the management of time intervals "from 8 h till 12 h". It could be made by overloading the operator Duration.minus () to write "at (8.h-12.h)". In fact main pressure is your imagination!
Let us return on points approached for this mini - DSL:
Other characteristics of Groovy are interesting for DSL:
Builders is particularly powerful because they allow to write or parser every type of tree structure (XML, HTML, Swing, etc) in a very intuitive way. For example, the files of shape XML are often very verbose, it is possible to use a builder to simplify their writing. Steven Devijver shows us one for configurer Architecture rules.
The next stage would be to include code Groovy into an application Popular dance but it will make the object of another ticket...
Article printed from Blog Xebia France:
URL to article: / 2008 / 05 / 07 / introduction-aux-dsl-avec-groovy /
Click here to print.