Mohd Farid « Intelligrape Groovy & Grails Blogs
Subscribe via E-Mail:

Mohd Farid

http://www.intelligrape.com/blog

Posts by Mohd Farid:

  • Discovering grails goodness: Scoped Services

    29 Dec 2011 in Design Pattern& Grails

    Recently, I got to learn about the scoped services in grails and I found it worth sharing. For instance: A Service marked as ’session’ scoped would be instantiated once for a session and remains there throughout the lifetime of the session. This can be used to store user specific data in this service bean class.

    class SessionDataService {
         static scope = 'session'
         Date lastLogin =new Date()
        String getInfo()
        {
            "lastLogin: ${lastLogin.format('HH:mm:ss')}"
        }
    }
    

    So, wherever I intend to use session for storing user data, I would rather use session scoped service.

    Hope that helps.

    Best Regards
    Mohd Farid

    • Share/Bookmark
  • Grails productivity enhancer. The unsung hero ‘grails interactive mode’

    30 Nov 2011 in Grails& Test& Unit Test

    Of late, I have been thinking about the popularity of grails interactive mode amongst developers. I found that though most of us are aware of this mode but we don’t use it as often, as it should be.



    Where should I use grails –interactive mode while developing in grails?
    The answer may vary from person to person and the level of expertise. For me, I found it amazing while running my tests and creating artifacts.


    I shall describe the advantages that I found with interactive mode while running Unit Tests. Let us take an example here:

    I have a class called PersonUtil which needs to be unit tested. I write a PersonUtilTests class for testing its functionality. In order to run this particular unit test, I can use the following command:

    grails test-app unit: PersonUtilTests

    This takes approximately 20 secs on an average to run on my machine with a decent configuration.

    Alternatively, We can run it in interactive mode. What we need to do is

     grails --interactive

    This shall bring the grails infrastructure up and make it just ready to run commands. It takes around 5 seconds.

    Welcome to Grails 1.3.7 - http://grails.org/
    Licensed under Apache Standard License 2.0
    Grails home is set to: /opt/grails
    
    Base Directory: /home/farid/grailsApplications/survey-app/ErServices
    --------------------------------------------------------
    Interactive mode ready. Enter a Grails command or type "exit" to quit interactive mode (hit ENTER to run the last command):
    

    Now, to test the app I can use the following command:

    -------------------------------------------------------
    Command TestApp completed in 2461ms
    --------------------------------------------------------
    Interactive mode ready. Enter a Grails command or type "exit" to quit interactive mode (hit ENTER to run the last command):
    test-app unit: PersonUtilTests
    

    It took 15 seconds to run this for first time.
    For subsequent runs, it took 2-4 seconds. Which is a clear advantage of 16 seconds for every run. These 16 seconds are no less than gem when you are in your “flow-state”( in concentration mode).

    While development, we make frequent changes to our code and therefore we need to run our unit tests multiple times. Every time I make a change and re run my unit test it takes 20 seconds through conventional grails test-app whereas it takes 3-4 seconds through interactive mode.

    Earlier, I used to get frustrated while waiting for test cases to execute. This waiting time is one of the biggest factor that drives us from doing Test Driven Development.


    Just in case you have not tried it. Please give it a shot. Believe me, it’s worth trying, you wont be disappointed!!!


    Mohd Farid
    farid@intelligrape.com

    • Share/Bookmark
  • Grails bindData to collections

    24 Oct 2011 in Grails

    Recently, I was stuck with a scenario where I was trying to bind a list of objects in my controller. While trying the way as suggested in the grails docs I was getting some weird IndexOutOfBoundException. Luckily I found a good solution on the grails mailing list: http://grails.1312388.n4.nabble.com/Databinding-Collection-of-non-domain-objects-tp3260578p3260856.html
    Thanks to mkwhit for asking this and Dana for suggesting this solution.

    There is a Car class in my src/groovy. There is a create.gsp that should create n number of cars at a time. The problem is to bind this data to a List of Car objects.

    Here is how I got it done:

    I ensured in my gsp that the car parameters are passed as car.1.name, car.1.brand, car.2.name, car.2.brand ….. So, when I did a params.car I get a Map like this:

    1: [name:'carA', brand:'brand1']
    2: [name:'carB', brand:'brand2']
    3: [name:'carC', brand:'brand2']
    1.name:'carA'
    1.brand:'brand1'
    2.name:'carB'
    2.brand:'brand2'
    3.name:'carC'
    3.brand:'brand3'
    
    def carParams = params.car.values().findAll {it instanceof GrailsParameterMap}
    List<Car> carList = carParams.collect {
       def car = new Car()
       bindData(car, it)
       car
    }

    So, we have a list of Car objects out from the params.

    Hope this helps.

    -Mohd Farid-

    • Share/Bookmark
  • Closure as an implementation to interface

    04 Oct 2011 in Grails& Groovy

    Recently, I saw some code of grails Hibernate Plugin and noticed an interesting usage of ‘as’ operator. The ‘as’ operator of groovy is typically used to change the types of objects.

    For example:

    int a = "20" as int
    assert a==20
    

    The ‘as’ operator can be used to provide implementation to interface as well. Here is an example of the same:

    interface Eatable{
       void eat()
    }
    
    def x =  {println "It's groovy style" } as Eatable
    x.eat()
    

    Had it been java, this could have been achieved through an annonymous class like this:

    new Eatable(){
      void eat(){
        System.out.println "Its java style"
      }
    }.eat()
    
    • Share/Bookmark
  • A use case of Bitwise AND

    15 Apr 2011 in Database& Grails

    Recently, I used bitwise Anding in my grails project. I am sharing the approach that we followed by means of an example.


    Suppose we have a domain class Person which can have multiple attributes like Smart, Intelligent, Talkative etc.

    What sort of relationship comes to our mind when we see this?
    I believe the obvious answer would be Person hasMany Attributes

    Next, what if we want to optimize our design so that the searches on the Person becomes better.

    Well, this was the question we were facing in our recent project where we finally used the bitwise AND.
    We decided to have one field of type Long in our Person class. We named this as attributes . Soon, I ll be explaining why a long for Attribute…

    We ensured that the Attributes are never going to be more than 20-30 . So, it became a nice candidate which could utilize the benefit of Bitwise ANDing.

    We associated a binary weight to every instance of Attribute domain class.

    The rows in the attribute table of our database looked somewhat like this

    id | attribute      | weight
    1 | Smart          | 1
    2 | Talkative      | 2
    3 | Intelligent     | 4
    4 | Cooperative  | 8
    5 | Ignorant       | 16
    

    So, in order to save a Person who is Smart and Cooperative , we would set his attributes field.
    weight of Smart + weight of Cooperative.
    ie 1+8 = 9.

    Suppose our Person table has some entries as follows:

    id  | name  | attributes
    1   | Tom   |  9
    2   | Fred   |  12
    3   | John   | 18
    

    If we want to search a person who is Intelligent we need to have a final query like this

    Select * from person where attributes&4 = 4
    (4 is the weight of Attribute - Intelligent)
    

    Search a person who is Cooperative and Talkative

    Select * from person where attributes&2=2 and attributes&8=8
    or more optimally,
    Select * from person where attributes&10=10
    (2 is the weight of Talkative and 8 is the weight of Cooperative)
    


    Some points to be kept in mind before taking this approach:

    There is a maximum limit of 64 values for the field on which we plan to do BitwiseANDing.
    Bitwise AND is not directly supported by Hibernate, but we can add a custom function and dialect.



    Hope this helped.

    Thanks & Regards
    Mohd Farid

    • Share/Bookmark
  • Implementing saveOrUpdate() for domain classes

    15 Mar 2011 in GORM& Grails& Plugin

    Some times in our applications, while saving a domain object we may desire to have a save or update behavior on the basis of certain fieldSupp

    Suppose we have a domain class Personwith following definition:

    class Person{
    String name
    String source
    String description
    
    def static saveOrUpdateBy = ['name', 'source']
    
    } 

    Details of a person are coming from multiple sources at multiple intervals of time. We want to maintain the latest records from each source at any given time.

    We want to saveOrUpdate a person if the name and source are same. So, If we happen to execute following three lines of code…

    new Person(name: 'Alex', source: 'source-1', 'Hello').saveOrUpdate();
     new Person(name: 'Alex', source: 'source-1', 'Hi').saveOrUpdate();
     new Person(name: 'Alex', source: 'source-1', 'Wow').saveOrUpdate();

    By the end of last line we would like to have only one row in the table corresponding to Person domain. Because we want to saveOrUpdate() on the basis of name , source combination.

    We can have  a metaclass method injected in all our domain classes to have this method. The properties to be considered while doing saveOrUpdate can be specified through a static field in class.. Some thing like

    def static saveOrUpdateBy = ['name', 'source']

    The following is the piece of code for achieving the same:

    Fetching the static property of the domain class.

    //GrailsDomainClass
     application.domainClasses.each {
     domainClass->
     List saveOrUpdateBy = GrailsClassUtils.getStaticPropertyValue(domainClass.clazz, 'saveOrUpdateBy')
     if(saveOrUpdateBy)
     {
     SaveOrUpdatePlugin.addSOUToDomainClass(domainClass, saveOrUpdateBy)
     }
     }
    

    A method to add a meta-method saveOrUpdate to given domain classes.

    
    class SaveOrUpdatePlugin {
    
     static void addSOUToDomainClass(GrailsDomainClass domainClassObject, List saveOrUpdateBy) {
     println "Adding saveOrUpdate method to $domainClassObject.clazz"
     Class domainClass = domainClassObject.clazz
     domainClass.metaClass.saveOrUpdate = {
     def savedInst
     try {
     log.debug "[SAVE OR UPDATE] Trying to do saveOrUpdate for ${SaveOrUpdatePlugin.getToStringForGivenFields(delegate, saveOrUpdateBy)}"
    
     def inst = domainClass.findWhere(delegate.properties.subMap(saveOrUpdateBy))
    
     if (!inst) {
     synchronized (domainClass) {
     inst = domainClass.findWhere(delegate.properties.subMap(saveOrUpdateBy))
    
     if (!inst) {
     log.info("[SAVE OR UPDATE] Saving a new object ${SaveOrUpdatePlugin.getToStringForGivenFields(delegate, saveOrUpdateBy)}")
     if (!delegate.validate()) {
     delegate.errors.each {
     log.error "Error while saving scrapedMovie  $it"
     }
     }
    
     if (!delegate.save(flush: true)) {
     delegate.errors.each {
     log.error it
     }
     }
     log.debug("[SAVE OR UPDATE] Saved a new object with id ${delegate.id} - ${SaveOrUpdatePlugin.getToStringForGivenFields(delegate, saveOrUpdateBy)}")
     }
     }
     }
     else {
     log.info "[SAVE OR UPDATE] matching object found: ${SaveOrUpdatePlugin.getToStringForGivenFields(inst, saveOrUpdateBy)}"
     long id = inst.id
     //inst.properties = delegate.properties
     SaveOrUpdatePlugin.copyProperties(domainClassObject, delegate, inst)
     log.info "[SAVE OR UPDATE] Updating an existing object ${SaveOrUpdatePlugin.getToStringForGivenFields(inst, saveOrUpdateBy)}"
     if (!inst.save(flush: true)) {
     inst.errors.each {
     log.error it
     }
     }
     log.debug("[SAVE OR UPDATE] Updated existing object with id ${inst.id} - ${SaveOrUpdatePlugin.getToStringForGivenFields(inst, saveOrUpdateBy)}")
     }
    
     savedInst = domainClass.findWhere(delegate.properties.subMap(saveOrUpdateBy))
    
     //returning the saved instance...
    
     } catch (Exception ex) {
     log.error("Failed to saveOrUpdate the object ${delegate} ", ex)
     }
     return savedInst
     }
     }
    
     static String getToStringForGivenFields(def object, List fields) {
     StringBuilder sb = new StringBuilder()
     sb.append(object.toString() + " SaveOrUpdateBy: ")
     fields.each {
     sb.append(", ${it}=")
     sb.append(object."$it")
     }
     sb.toString().replaceFirst(', ', '')
     }
    
     static void copyProperties(GrailsDomainClass domainClassObject, def source, def target) {
     domainClassObject.persistantProperties.each {prop ->
     if (!(prop.name in ['dateCreated', 'lastUpdated', 'id'])) {
     target."${prop.name}" = source."${prop.name}"
     //println "adding property ${prop.name}"
     }
     }
     }
    }
    
    Hope this would help someone in need.

    Any comments / suggestion for improvement of the same are most welcome.

    Thanks & Regards
    Mohd Farid
    farid@intelligrape.com

    • Share/Bookmark
  • Using TagLib to avoid changes due to change in URLMappings

    14 Feb 2011 in Grails

    Recently, I used Taglib to centralize the effect of URL mapping related changes of my grails application.

    def userPageLink = {attrs, body ->
    
    def user = User.read(attrs.id)
    
    out << g.link(controller: 'user', action: 'show', params: [name: user.name]) {body()}
    }
    

    So wherever I need a link to user page, I can use this Taglib instead of g:link.

    <hys:userPageLink id="${user.id}">${user.name}</hys:userPageLink>
    

    Advantage:


    Whenever I change the URL Mappings, there is no need to update all the g:link in all my gsp files. I would just update my taglib to cater to new URL Mapping.

    • Share/Bookmark
  • Using Groovy MOP and Closure to prevent expression evaluation in logger.debug()

    13 Dec 2010 in Groovy& logging

    Generally in our code, we have lots of debug statements that prints the intricate details of the state of the program. Infact, the debug statements are meant for doing this. Sometimes, these debug statements may contain a call to some other method to evaluate what is to be logged.

    //Logging statement calling some function to get what is to be logged
    logger.debug myVeryBigFunc()
    
    def myVeryBigFunc()
    {
       //Do something big...
       // Take lot of time and resources
       //
       return “SUCCESSFUL IN THE BIG TASK”
    }
    

    If the logger level is set to DEBUG. The above code would log "SUCCESSFUL IN THE BIG TASK“.

    Once our application graduates to production we might not really care to see those debug statements. We just need to see something of priority WARN or higher. We would set logger level to WARN. Now, the above code would not print anything. But, still it will execute the myVeryBigFunc()   in order to pass the result as an argument to logger.debug().

    The decision to log the message or not is taken inside the logger.debug() method only after getting its  arguments. This is clearly an overhead to evaluate the arguments which are to be ignored later.

    Can we really do something to avoid this???

    In old java days, we used to fix this by using logger.isDebugEnabled() method.

    if(logger.isDebugEnabled())
    {
    	logger.debug myVeryBigFunc()
    }
    

    Now, the myVeryBigFunc() would not be called at all because our ‘if’ statement is making sure that logger.debug() is called only when the logging level is atleast DEBUG. This seems to be a pretty cool fix at the moment.  But this becomes very dirty as the log statements increase.

    So, how can we achieve this without being at the risk of looking dirty.

    The solution is with the Closure and MOP feature of Groovy which enables us to create an overloaded function for debug which takes a Closure as an argument. This Closure is evaluated only after checking for logging level.

    The following piece of code does just the same.

    We have overloaded the Logger’s debug(), info(), error(),warn() and fatal() methods to accept Closure as an argument.
    In the overloaded versions we first check for logging levels and if the logging level permits the current method to log, only then the closure is evaluated.

    class Log4jEnhancerMOP
    {
       static void addClosureOverloadsToLoggerDynamically()
       {
          ['debug', 'info', 'warn', 'error', 'fatal'].each{ logLevel ->
                println "Defining metaclass method for logging level $logLevel"
                Logger.metaClass."${logLevel}" = {Closure clos ->
                if (delegate.invokeMethod("isEnabledFor", Level."${logLevel.toUpperCase()}"))
                {
                    println "logging is enabled for $logLevel"
                    delegate.invokeMethod("$logLevel", clos.call())
                }
                else
                {
                    println "logging is not enabled for $logLevel"
                }
            }
         }
      }
    
      public static void main(String[] args)
      {
         addClosureOverloadsToLoggerDynamically()
         Logger logger = Logger.getRootLogger()
    
         //setting the logger level to WARN
         logger.level = Level.WARN
         logger.addAppender(new ConsoleAppender(new PatternLayout("%-5p [%t]: %m%n ")))
    
         //calling the regular debug() method myVeryBigFunc() would get called even if the logger level is set to WARN
         logger.debug(myVeryBigFunc("DEBUG MESSAGE"))
    
         //calling the overloaded debug() method. myVeryBigFunc() would not be called as is present in a closure. The closure
         //is executed by the overloaded method only if the logger level has debug enabled.
         logger.debug {myVeryBigFunc("DEBUG MESSAGE")}
    
         logger.error {myVeryBigFunc("ERROR MESSAGE")}
         logger.fatal {myVeryBigFunc("FATAL MESSAGE")}
         logger.info {myVeryBigFunc("INFO MESSAGE")}
    
     }
    
     static String myVeryBigFunc(String msg)
     {
        println "invoked myVeryBigFunc... $msg"
        return 'SUCCESSFUL IN THE BIG TASK'
     }
    }
    

    Hope this helps!!!

    Any suggestions or corrections are most welcome.

    Thanks & Regards
    Mohd Farid
    Intelligrape Software

    • Share/Bookmark