Groovy magic: asType

Every one who used Grails had to deal (or will have) with XML/JSON converters. They allow to transform object by using syntax like:

  1.  
  2. import grails.converters.*
  3.  
  4. class TestController {
  5. def index = {
  6. [a:1, b:2, c:3] as JSON
  7. }
  8. }
  9.  
  10.  

I like this "as" syntax, is very verbose and clear. How we can implement in our code? Simple, just use asType method:

  1.  
  2. class Foo {
  3. def name
  4.  
  5. String toString(){
  6. "Foo name is ${name}"
  7. }
  8. }
  9.  
  10. class Bar {
  11. def name
  12.  
  13. String toString(){
  14. "Bar name is ${name}"
  15. }
  16. }
  17.  
  18. class Bas {
  19.  
  20. def name
  21.  
  22. String toString(){
  23. "Bas name is ${name}"
  24. }
  25.  
  26. Object asType(Class type){
  27. typeWorker[type](this)
  28. }
  29.  
  30. @Lazy
  31. private def typeWorker = [(Foo):asFoo, (Bar):asBar]
  32.  
  33. private def asFoo = {it ->
  34. new Foo(name:it.name)
  35. }
  36.  
  37. private def asBar = {it ->
  38. new Bar(name:it.name)
  39. }
  40. }
  41.  
  42. def bas = new Bas(name:"Gringo")
  43.  
  44. println bas as Foo
  45. println bas as Bar
  46.  
  47.  

and output will be :

Bas name is Gringo
Foo name is Gringo
Bar name is Gringo

Groovy exercises – text wrapping

This is my groovy solution for simple text wrapping problem:

  1.  
  2. def input = "The quick brown fox jumps over the lazy dog. "
  3.  
  4. String.metaClass.wrap = {token, length ->
  5. def line = token
  6. def elements = delegate.tokenize().reverse()
  7.  
  8. while(elements.size()){
  9. if ((line + elements.last()).size() < length){
  10. line += ' ' + elements.pop()
  11. }
  12. else {
  13. println line
  14. line = token
  15. }
  16. }
  17.  
  18. if (line != token){
  19. println line
  20. }
  21. }
  22.  
  23. (input * 10).wrap('>', 72)
  24.  

Grails and AST transformations – hard start

Recently i tried to use AST transformation in my Burning Image Grails plugin. I want to use them, to mark domain objects that should be extended by some methods and fields that allow to use this object as a container for information about image saved on server.

I follow this "how to" tutorial, but after struggling with code for several hours, its appears (Joshua Burnett was very helpful - thanks) that if you want to use this technique, you should write code as a pure Java classes not Groovy scripts. After that, it run smoothly.

If any one is capable to run AST transformations as groovy scripts (in Grails project), i will be very thankful for "how to".

Mixin is not 100% inheritance

Groovy allows us to simulate multiple inheritance by using @Mixin annotation:

  1.  
  2. class Foo {
  3. def sayFoo(){
  4. "hello from foo"
  5. }
  6. }
  7.  
  8. class Bar {
  9. def sayBar(){
  10. "hello from bar"
  11. }
  12. }
  13.  
  14. @Mixin([Foo, Bar])
  15. class Bas {
  16. }
  17.  
  18. def foo = new Foo()
  19. def bar = new Bar()
  20. def bas = new Bas()
  21.  
  22. assert foo.sayFoo() == bas.sayFoo()
  23. assert bar.sayBar() == bas.sayBar()
  24.  
  25.  

but unfortunately it will only copy methods and properties, and will not provide mixed type, so when you try something like this:

  1.  
  2.  

assertion exception will be throw.

Groovy List.contains / GString fuss

If you want to search for String value in the List using contains method, be careful if the argument is GString type.

  1.  
  2. def foo = 1
  3. assert !['1','2','3'].contains("${foo}")
  4. assert ['1','2','3'].contains("${foo}".toString())
  5.  

Why? Because contains use equals method to match your parameter to each position on the list, and for equals we have:

  1.  
  2. def foo = "groovy"
  3. def bar = "groovy${''}"
  4.  
  5. assert foo.class == java.lang.String
  6. assert bar.class == org.codehaus.groovy.runtime.GStringImpl
  7.  
  8. assert foo == bar
  9. assert bar == foo
  10. assert !foo.equals(bar)
  11. assert !bar.equals(foo)
  12.  

Burning Image Grails plugin

Today I ended my work over my first Grails plug-in: Burning Image. This simple plug-in for images manipulation provides two types of image scaling, and allows to watermark image. In future i want to add crop option and maybe rounding image corner. If you looking for some more informations or you want to try it you could fine it Google code repository.

Groovy closure – will it work?

Lets say we have Groovy class like this:

  1.  
  2. class Foo {
  3.  
  4. def bar(myClosure) {
  5. myClosure(this)
  6. }
  7.  
  8. private def bas(myName) {
  9. println "hello from ${myName}"
  10. }
  11. }
  12.  

and I am wonder what should happen if I execute this line of code:

  1.  
  2. new Foo().bar {
  3. it.bas("Steve Zissou")
  4. }
  5.  

Should it throw exception that I want execute private method? But this method is execute inside Foo object instance. So, should it print

hello from Steve Zissou

Unfortunately question is still open because Groovy private method / field bug. Or maybe is time to start using Scala and Lift?

    Griffon and table data binding

    Recently i have been working on small application in Griffon framewrok. This is MVC framework for desktop applications writed in Groovy  - new cool kid in Java World. My first impression was - WOW. Swing builder is my favorite feature immediately after mvc group.

    But nothing lasts forever and after few days of work I entered into world of pain. There is no documentation, best practices, or any thing like that. All java developers that were coddled by IDE's like Eclipse will suffer lots of pains because there is no rational support for Groovy. Of course you can hack Netbeans Grails (cousin of Griffon for web applications) plug-in, but after one hour of fight I stayed with my project in Eclipse.

    But the hardest thing for me was to menage how to bind data to table. I thinked that there MUST be way to do that by bind statement, but after several hours of searching, I find that there is no such way.

    So,  how to do it? Use Glazed list.

    There is simple example how to use glazed list. This is View from MVC group where we have helper method that create table model. Next we use this method for table creation. In this example model.tableData is instance of ca.odell.glazedlists.BasicEventList.

    1. def createTableModel() {
    2. def columnNames = ['col 1', 'col 2', 'col 3', 'col 4', 'col 5']
    3. def variableNames = ['var1', 'var2', 'var3', 'var4', 'var5']
    4. new EventTableModel(model.tableData,
    5. [getColumnCount: { columnNames.size() },
    6. getColumnName: { index -> columnNames[index] },
    7. getColumnValue: {object, index -> object."${variableNames[index]}"}] as TableFormat)
    8. }
    9.  
    10. panel {
    11. borderLayout()
    12. scrollPane {
    13. table(id:'myTable',
    14. selectionMode: ListSelectionModel.SINGLE_SELECTION,
    15. autoCreateRowSorter:true,
    16. model: createTableModel()) {
    17. current.tableHeader.reorderingAllowed = false
    18. }
    19. }
    20. }

    If you still looking for more info, check this example for more details.

Powered by WordPress with GimpStyle Theme design by Horacio Bella.
Entries and comments feeds. Valid XHTML and CSS.