This is a small guide for everybody involved in converting the Mini Language into Groovy.
Content
Groovy DSL
Services
Getting started
Checking Fields
Setting Fields
Starting Services
Anchor | ||||
---|---|---|---|---|
|
Section | |||||||
---|---|---|---|---|---|---|---|
|
Section | |||||||
---|---|---|---|---|---|---|---|
|
Section | |||||||
---|---|---|---|---|---|---|---|
|
Section |
---|
|
Anchor | ||||
---|---|---|---|---|
|
From MiniLang to Groovy
To see additional examples and finished conversions, which may help with occurring questions, click:
Jira | ||||||
---|---|---|---|---|---|---|
|
There is a chance that a similar case has already been converted.
IMPORTANT: When a simple-method ends, it will automatically at least return a success-map.
All the Groovy Services have to return success
at least, too.
Code Block | ||
---|---|---|
| ||
return success() |
Anchor | ||||
---|---|---|---|---|
|
MiniLang files consist of services, which, in most cases, implement services.
The get converted to Groovy like the following:
Code Block |
---|
<!-- This is MiniLang --> <simple-method method-name="createProductCategory" short-description="Create an ProductCategory"> <!-- Code --> </simple-method> // This is the converted Groovy equivalent /** * Create an ProductCategory */ def createProductCategory() { // Code } |
It will be useful for future developers, and everybody who has to check something in the code, to put at least the short-description
as the new Groovydoc. This will hopefully more or less explain, what the method should or shouldn't do.
If the short-description
isn't helpful enough, feel free complete it.
The structure of if
and else
in MiniLang is a little different than the one from Groovy or Java and can be a bit confusing when first seen, so here is an example:
Code Block |
---|
<if-empty field="parameters.productCategoryId"> <sequenced-id sequence-name="ProductCategory" field="newEntity.productCategoryId"/> <else> <set field="newEntity.productCategoryId" from-field="parameters.productCategoryId"/> <check-id field="newEntity.productCategoryId"/> <check-errors/> </else> </if-empty> |
Notice, that the else
always starts before the if
-tag is closed, but sometimes isn't indented as one would expect it.
When navigating through bigger if
-phrases, the navigation itself will be much easier through just clicking in the opening or closing if
-tag; Eclipse will automatically mark the matching opening or closing if
-tag for you.
There are two possibilities to initialize a field/variable in Groovy.
To define a field/variable with its correct typing:
Code Block String fieldName = "value"
To just "define" a field/variable. The IDE you are working with may not recognize the typing, but OFBiz can work with it:
Code Block def fieldName = "value"
Anchor | ||||
---|---|---|---|---|
|
Code Block |
---|
<if-empty field="fieldName"></if-empty> // checks if fieldName is existent and/or empty if (!fieldName) {} |
Code Block |
---|
<if-empty field="fieldName.property"></if-empty> // fieldName has to be existent, property doesn't need to // if known, that property does exist, the ? can be left out if (!fieldName?.property) {} // CAUTION: every query like this in Groovy evaluates to a Boolean type // everything that is empty or false will turn into false: // null, [], [:], "", false -> false // if you want to check if the field really is empty if (UtilValidate.isEmpty(fieldName)) {} |
Code Block |
---|
<if> <condition> <or> <if-empty field="field1"/> <if-empty field="field2"/> </or> </condition> <then> <!-- Code in if --> </then> <else> <!-- Code in else --> </else> </if> if (!field1 || !field2) { // Code in if } else { // Code in else } |
Code Block |
---|
<if-compare-field field="product.primaryProductCategoryId" to-field="parameters.productCategoryId" operator="equals"> <!-- Code --> </if-compare-field> // this will even work, if product is not existent or null if (UtilValidate.areEqual(product?.primaryProductCategoryId, parameters.productCategoryId)) { // Code } |
Code Block |
---|
<if-instance-of field="parameters.categories" class="java.util.List"></if-instance-of> if (parameters.categories instanceof java.util.List) {} |
Anchor | ||||
---|---|---|---|---|
|
Code Block |
---|
<set field="fieldName" value="value"/> // if fieldName is not initialized String fieldName = "value" // if fieldName is initialized fieldName = "value" |
Code Block |
---|
<set field="otherFieldName.property" value="value"/> <set field="otherFieldName.otherProperty" value="true" type="Boolean"/> <set field="otherFieldName.otherProperty" from-field="parameters.property/> // if otherFieldName is not yet initialized, you have to do it first // MiniLang does that automatically Map otherFieldName = [:] // empty Map // now put the values in otherFieldName = [ property: "value", otherProperty: true ] // or the less efficient way otherFieldName.property = "value" otherFieldName.otherProperty = true // it is possible to put different values in later: otherFieldName.property = parameters.property |
Code Block |
---|
<set field="thisFieldName" value="${groovy: []}" type="List"/> // this is easier in Groovy List thisFieldName = [] |
Code Block |
---|
<property-to-field resource="CommonUiLabels" property="CommonGenericPermissionError" field="failMessage"/> <!-- there are different cases of this, which are not distinguished in MiniLang --> <property-to-field resource="general.properties" property="currency.uom.id.default" field="parameters.rateCurrencyUomId"/> String failMessage = UtilProperties.getMessage("CommonUiLabels", "CommonGenericPermissionError", parameters.locale) // in Groovy there can is a difference for the second case parameters.rateCurrencyUomId = UtilProperties.getPropertyValue('general.properties', 'currency.uom.id.default') |
Code Block |
---|
<clear-field field="product.primaryProductCategoryId"/> product.primaryProductCategoryId = null |
Anchor | ||||
---|---|---|---|---|
|
Code Block |
---|
<set field="relatedCategoryContext.parentProductCategoryId" from-field="defaultTopCategoryId"/> <call-service service-name="getRelatedCategories" in-map-name="relatedCategoryContext"> <result-to-field result-name="categories" field="resCategories"/> </call-service> def relatedCategoryContext = [parentProductCategoryId: defaultTopCategoryId] def serviceResult = run service: "getRelatedCategoryies", with: relatedCategoryContext def resCategories = serviceResult.categories // if it is not too confusing you can leave out the extra variable run service: "getRelatedCategoryies", with: [parentProductCategoryId: defaultTopCategoryId] |
Code Block |
---|
<set-service-fields service-name="productCategoryGenericPermission" map="parameters" to-map="productCategoryGenericPermissionMap"/> <call-service service-name="productCategoryGenericPermission" in-map-name="productCategoryGenericPermissionMap"> <results-to-map map-name="genericResult"/> </call-service> // instead of setting the service fields from parameters, it is possible to run the service with the parameters map Map genericResult = run service: "productCategoryGenericPermission", with: parameters |
Related articles
Content by Label | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Page properties | ||
---|---|---|
| ||
|