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

Grails, sky is the limit

Yesterday during my research about fronted (Flex) <-> backend (anything) communication solutions, I hit in Grails Red5 plugin. It take only a few minutes to setup fully accessible RTMP server, that will allow you to build, e.g. video chat. Only several commands change Grails into something totally different. And I like it.

Burning Image 0.3 released

New version of Grails plugin for image manipulation released. Current version allows to:

  • scale image with approximate width and height
  • scale image with accurate width and height
  • add image watermark
  • crop image
  • write text on image
  • mark domain class as image container by using @FileImageContainer annotation
  • save image binded to domain class by using ImageUpladService
  • validate uploaded image

To read more go to project home page.

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".

Grails url mapping localization

This is simple "hack" that allows you to internationalize your url in your Grails (1.2.x) application. Lets say that we have application that is provided in two languages: Polish and English. Create ours controller:

  1.  
  2. FooController {
  3. def bar {
  4. }
  5. }
  6.  

In ours locale files (message_pl.properties and message_en.properties) add "locale" param (because grails bug) with code specified for this file (pl, en).

Next step is to create new taglib that will generate internationalized link:

  1.  
  2. class BaseTagLib {
  3. def localizedLink = { attrs, body ->
  4. attrs.mapping = message(code:'locale') + StringUtils.toUpperCaseFristLetter(attrs.mapping)
  5. out << link(attrs, body)
  6. }
  7. }
  8.  

This Taglib doing nothing than add prefix for name of the route. It use util method StringUtils.toUpperCaseFristLetter, that capitalize first letter of provided string:

  1.  
  2. class StringUtils {
  3. static def toUpperCaseFristLetter(String text){
  4. text[0].toUpperCase() + text[1..-1]
  5. }
  6. }
  7.  

Now we can provide url mappings as:

  1.  
  2. class UrlMappings {
  3. static mappings = {
  4. name enGoToFooBar:'/go/to/foo/Bar' {
  5. controller = 'foo'
  6. action = 'bar'
  7. }
  8.  
  9. name plGoToFooBar:'/idz/do/foo/Bar' {
  10. controller = 'foo'
  11. action = 'bar'
  12. }
  13. }
  14. }
  15.  

In ours gsp files we can use it like:

  1.  
  2. <g:localizedLink mapping="goToFooBar"><g:message code="text.goToFooBar" /></g:localizedLink>
  3.  

Setting default locale

If you want to set default locale for application, add this definition of LocaleResolver to spring context configuration:

  1.  
  2. localeResolver(SessionLocaleResolver) {
  3. defaultLocale = new Locale('pl')
  4. Locale.setDefault (defaultLocale)
  5. }
  6.  

Request.locale Grails bug

If you want to use request.locale to determine current locale - forget abut that. Even in Grails 1.2, if you pass lang parameter there will be no change of this object and it will stay as a default (even if i18n properties file will be changed). Quick fix is to add locale entry in message bundles (maybe, hmmm locale) and use it.

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.  

Rendering templates in services

If you want to render gsp template on level of service (or in any other bean), just get org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib bean from spring context, and call method render on it:

  1.  
  2. class FooService {
  3.  
  4. boolean transactional = false
  5.  
  6. def grailsApplication
  7.  
  8. def bar(view, model) {
  9. render(template:"/templates/emails/${view}", model:model)
  10. }
  11.  
  12. private def render(args){
  13. grailsApplication.mainContext.getBean('org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib').render(args)
  14. }
  15. }
  16.  

Grails 1.1.2 released

Today was released Grails 1.1.2 . There are some bug fixes and new functionalities (changelog). Rely on Robert Fletcher, version 1.2 will not appear, until Spring 3.0 goes final.

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