📜 ⬆️ ⬇️

Groovy Validation DSL

One of the common problems of imperative programming languages ​​is the lack of expressions for declarative structures, such as, for example, tree markup or a set of rules for data processing. In Groovy, this problem is solved using classes like Builder and meta-programming at the level of an abstract syntax tree.

In turn, the processing of input data is one of the essential steps in the work of client-server applications. This process is often described by a sequence of if-ob and corresponding exceptions. With a large number of parameters, such code becomes poorly readable and makes its analysis for correctness a non-trivial task. Thus, often the logic of data preprocessing is “smeared” across several methods and classes. In addition, when a new parameter appears, it is easy to forget about checking and normalizing it (formatting, shielding characters, etc.). As a solution to this problem, a library was written by Groovy that allows you to describe these rules in a declarative style using DSL. For example, the following script processes six incoming parameters: mail address, login, gender, checkbox status “I agree with the rules”, weight and date.

import org.grules.console.Gender // isEmail   Java/Groovy ,    — email.            import static. email isEmail ["Invalid email"] //  >>     — isAlpha  isUnique. invalidLoginssage  dupLoginssage     . login isAlpha [invalidLoginssage] >> isUnique [dupLoginssage] // Gender  Java enum.    gender  ,     "MALE".         Groovy . gender["MALE"] toEnum(Gender) // m   ResourceBundle,  m.agreeToTerms —  . termsCondition[""] !isEmpty [m.agreeToTerms] //  o     .          it. weight toPositiveBigDecimal [decimalErr] >> {round it / 1000} //    &&, ||  !.              . endDate isAfterNow && isBefore(deadline) && {it.day != 1} 

The result of the script execution is a report in the form of a Java object with parameters divided into five groups:

In the case of DSL, the course of validation is under the control of the library, which accordingly makes it possible to perform operations at the meta level, for example, to collect statistics for each parameter or to generate client code in Javascript. In Java, similar functionality is available through annotations, but the lack of access to AST and the support of non-primitive data types limits their scope.

All that is needed from the developer to start using DSL is to include the library in the project's classpath (for example, through Maven ) and create a Groovy script with the Grules suffix and description of processing rules for all or some parameters.
')
The “HelloWorld” project consists of three files :

HelloGrules.groovy

 package test email isEmail ["Invalid email"] age toPositiveInt ["Invalid age"] >> {it > 18} ["You must be adult"] 

Test.groovy

 package test import org.grules.Grules class Test { public static void main(String[] s) { def grules = new Grules() def result = grules.applyRules(HelloGrules, [email: "megmail.com", age: "35"]) assert result.cleanParameters.age == 35 assert "email" in result.invalidParameters assert result.invalidParameters.email.errorId == "Invalid email" println result } } 

build.gradle

 apply plugin: 'application' apply plugin: 'groovy' apply plugin: 'maven' repositories { mavenCentral() } mainClassName = "test.Test" dependencies { groovy 'org.codehaus.groovy:groovy:2.0.5' exclude group: 'asm', module: 'asm' compile 'org.grules:grules:0.2.0.8' exclude group: 'asm', module: 'asm' } 

To start, run the gradle run command in the root directory.

More information about the project can be found on the following resources: wiki , online console , github , publication (English).

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


All Articles