#Builder groovy AST transformation - groovy

I am looking for Groovy AST transformation that would generate builder pattern code inside my class.
I know there are something like #Canonnical or #ToString or #EqualsAndHashCode enhancers that automatically generate useful methods and hoped if there would be #GenerateBuilder. I want to use it something like this:
//Groovy code:
#GenerateBuilder
#CompileStatic
class Person {
String name
int age
Long id
String createdBy
}
//then in Java code:
Person p = Person.newBuilder()
.withName("pawel")
.withAge(19)
.withId(11123)
.withCreatedBy("system")
.build();

There's nothing prior to 2.3 that will do this
But groovy 2.3 has a new #Builder annotation
https://github.com/groovy/groovy-core/blob/master/src/main/groovy/transform/builder/Builder.java

Related

IntelliJ Live Template for dart named constructor: lists class' fields

I want to generate a custom named constructor in Dart.
I have many dto class to implement and each should provide a named constructor like: ClassName.fromMap().
For example for this class:
class Student {
final String name;
final int age;
}
The generated constructor should be:
Student.fromMap(Map<String, dynamic> map) :
name = map['name'],
age = map['age'];
How can I retrieve the list of the field of my current class as strings? Is that even possibile?
Of course I can have a variable number of fields.
My template looks like:
$CLASS$.fromMap(Map<String, dynamic> map) :
$INITIALIZATION_LIST$
binding $CLASS$ to dartClassName().
Now I'd like to bind $INITIALIZATION_LIST$ to something like:
getClassFieldList().forEach((fieldName) => "$fieldName = map['$fieldName']")
Can I achieve something like that?
There is no way to retrieve a list of Dart class fields using predefined live template functions. You can try developing your own template macro for this. See https://intellij-support.jetbrains.com/hc/en-us/community/posts/206201699-create-a-new-expression-for-a-live-template-for-actionscript for some hints.
Existing live template functions implementations can be found at https://github.com/JetBrains/intellij-community/tree/master/platform/lang-impl/src/com/intellij/codeInsight/template/macro.
You can also try using Structural Search and Replace instead of live template

Xtext DSL editor referring to the Java classes defined in my model

I have set of java classes and I want to refer them in the DSL which I am trying to edit using Xtext grammar. e.g. There is a class Employee :
class Employee{
String name;
double salary;
String organisation;
String status;
}
Now in my DSL I wish to use them. Hence when user is trying the name he should get these tree attributes as help. e.g. DSL i will like to trite like this:
employee.salary > 100000 then employee.status='GOLD'
My question is when i am typing the name such as employee than all the three attributes should be available to user as context help.

Groovy - How to serialize an object into a string

How to serialize an object into a string
below is the .net code for serializing an object into a string
String sampleEntity= JsonConvert.SerializeObject(entity))
same I need it in groovy? please suggest
Assuming entity is some object or list of objects, the easiest way IMO is:
import groovy.json.*
class Person { // this is a sample object, like entity in your example
String name
}
def json = JsonOutput.toJson([ new Person(name: 'John'), new Person(name: 'Max') ])
println json​
// output (string): [{"name":"John"},{"name":"Max"}]
If you need to customize the output (like fiddle with exact format of dates or something), you should use JsonGenerator Instead. It has a builder that will allow to do this fine grained setup. Since its a kind of beyond the scope of the question, I'll just provide a link to the relevant chapter of documentation

Can I do this with ExpandoMetaClasses in Groovy?

When upgrading from Groovy 1.8.4 to 1.8.5 the JsonSlurper returns a BigDecimal instead of a float or double for numbers in Json. For example consider the following JSON document:
{"person":{"name":"Guillaume","age":33.4,"pets":["dog","cat"]}}
In Groovy 1.8.4 "age" would be represented as a float whereas in Groovy 1.8.5+ it's represented as a BigDecimal. I've created a Java framework that uses the Groovy JsonSlurper under the hood so in order to maintain backward-compatibility I'd like to convert JSON numbers (such as 33.4) to float or double transparently. Having looked at the groovy-json source code I see that JsonSluper uses a JsonToken which is the one that creates a BigDecimal out of 33.4 in its "getValue()" method. This method is called by the JsonSlurper instance.
So what (I think) I want to do is to override the getValue() method in the JsonToken class to have it return a float or double instead. This is what I've tried:
def original = JsonToken.metaClass.getMetaMethod("getValue")
JsonToken.metaClass.getValue = {->
def result = original.invoke(delegate)
// Convert big decimal to float or double
if (result instanceof BigDecimal) {
if (result > Float.MAX_VALUE) {
result = result.doubleValue();
} else {
result = result.floatValue();
}
}
result
}
The problem is that even though the code stated above is executed before new JsonSluper().parseText(..) the overridden "getValue()" in JsonToken is not called (the original getValue() method is called instead). But if I copy all code from the JsonSlurper class into my own class, let's call it JsonSlurper2, and do new JsonSluper2().parseText(..) the overridden method of "getValue()" is called and everything works as expected. Why is this? What would I have to do to avoid copying JsonSlurper to my own class?
JsonSlurper is a Java class and therefore you are unable to override its methods via metaClass. See this mailing list thread.
This question looks like it might have a way for you to do this.

Groovy closure not work with static final field from super class

class Parent {
final static String newLine = "*"
}
class Child extends Parent{
List body = [3, 4, 5]
String toString() {
def str = new StringBuilder()
body.each { str.append(it + newLine) }
str
}
}
def c = new Child()
println c
The above is one trivial sample to illustrate the problem. It couldn't be compiled using Groovy plugin on Eclipse. Remove either final or static in the field of super class solves the problem. However, I have no idea why it's the case.
http://groovy.codehaus.org/Groovy+Beans
In this link it mentions the rules for property and fields used in Groovy. I suppose the one applied should be the last one, i.e. meta class. Unfortunately, I still couldn't understand the behavior.
The behavior is reproduced consistently in all versions of Groovy. Maybe someone could report one bug to Groovy team. I have never done this before. It would be more efficient if someone experienced could do that.
This is most probably https://issues.apache.org/jira/browse/GROOVY-5776 which is more difficult to fix than it looks like
As blackdrag already pointed out: it's a bug.
But another workaround is to add the protected keyword:
protected final static String newLine = "*"

Resources