Groovy « Intelligrape Groovy & Grails Blogs

Archive for the ‘ Groovy ’ Category

Groovy : Find Index of Element in Map

Posted by Hitesh Bhatia on November 10th, 2011

Groovier way of finding index of element from Map. It can be obtained with findIndexOf Method, which accepts closure as argument.


Map map=["groovy":1,"grails":2,"index":3,"element":4]
assert 3 == map.findIndexOf{it.key=="element"}
assert 0 == map.findIndexOf{it.value==1}
  • Share/Bookmark
Posted in Groovy

Log Sql in grails for a piece of code

Posted by Uday Pratap Singh on October 21st, 2011

There are time when we need to see the sql logging statement just for a method of for a particular code. Although we already have logSql property in DataSource to do it for us but it sometimes makes difficult if we need to see the log for a small piece of code rather than for whole project.
So I need something that will execute my code withing a block which automatically starts sql logging and switch it off when code is finished. Groovy closures are the solution for this problem. For doing it I created a class LogSql which have a static execute method that takes the closure as parameter.

import org.apache.log4j.Level
import org.apache.log4j.Logger

public static def execute(Closure closure) {
        Logger sqlLogger = Logger.getLogger("org.hibernate.SQL");
        Level currentLevel = sqlLogger.level
        sqlLogger.setLevel(Level.TRACE)
        def result = closure.call()
        sqlLogger.setLevel(currentLevel)
        result
}

Now when I want to see the logs I do something like following.

String name = "Uday"
Person person
LogSql.execute {
       person = Person.findByName(name)
}

This prints the sql statement for all the sql fired in the given piece of code block.

Hope it helps



## Uday Pratap Singh ##
uday@intelligrape.com
http://www.IntelliGrape.com/
http://in.linkedin.com/in/meudaypratap

  • Share/Bookmark

Closure as an implementation to interface

Posted by Mohd Farid on October 4th, 2011

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
Posted in Grails, Groovy

How to get Google Indexed Pages Count, and/or do Google searches through AJAX/programmatically

Posted by Kushal Likhi on September 27th, 2011

Hi,
Recently i had to get the count of the Pages Google has Indexed for a perticular web Site progmatically.
In the process i found that Google offers an AJAX Search API to perform Google Searches.
.
Hence i Implemented a Class which does the same for me easily(Ajax Search in Google).
And this Solution Does Google Searches programmatically and Also Give us the Indexed Pages Count.
Note: Its Groovy Implementation, Similar can be done in JavaScript using Ajax though intent will remain the same.
The class has been named GoogleAjaxSearch because it uses the Google AJAX Search API ;)

Use Cases Are As Follows:

//Case 1 Simple Search
String searchQuery = "my search Query"
GoogleAjaxSearch googleAjaxSearch = new GoogleAjaxSearch(searchQuery)
println googleAjaxSearch.results //Type List<Expando>, Just print it to see available properties

//Case 2: Get Number Of Indexed Pages in Google
String searchQuery = "site:intelligrape.com"
GoogleAjaxSearch googleAjaxSearch = new GoogleAjaxSearch(searchQuery)
println googleAjaxSearch.estimatedResultCount

//Case 3: Redo a search with same SearchQuery or a different Search Query
String searchQuery = "search string"
GoogleAjaxSearch googleAjaxSearch = new GoogleAjaxSearch(searchQuery)
googleAjaxSearch.redo() //Re-Search with same query
googleAjaxSearch.redo("New Query") // Re-Search With New Query

//Case 4: All Details Available
String searchQuery = "site:intelligrape.com"
GoogleAjaxSearch googleAjaxSearch = new GoogleAjaxSearch(searchQuery)
println googleAjaxSearch.estimatedResultCount //Gives the result count, indexed pages count
println googleAjaxSearch.currentPageIndex    //Search result server side pagination - current page
println googleAjaxSearch.results  //List<Expando> containing results
println googleAjaxSearch.responseStatus //HTTP Status Code
println googleAjaxSearch.responseDetails //Details for response, if any
println googleAjaxSearch.searchQuery     //Search Query
println googleAjaxSearch.moreResultsUrl // Url to hit for next Page of results
println googleAjaxSearch.jsonResult // Complete raw JSON Result from google
println googleAjaxSearch.pages  // Pagination Pages Details

The Class Code Is As Follows:


package myPackage.googleSearch

import grails.converters.JSON

class GoogleAjaxSearch {

    public String searchQuery
    public String responseDetails
    public String moreResultsUrl
    public String jsonResult

    public Integer responseStatus
    public Integer currentPageIndex
    public Integer estimatedResultCount

    public def pages

    public List<Expando> results = []

    private static final String ajaxSearchTarget = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=###SEARCHQUERY###&filter=0"

    public GoogleAjaxSearch(String searchQuery) {
        this.searchQuery = searchQuery
        search()
    }

    public GoogleAjaxSearch() {
        this(null)
    }

    public void redo() {
        search()
    }

    public void redo(String newSearchQuery) {
        this.searchQuery = newSearchQuery
        search()
    }

    private void search() {
        if (searchQuery) {
            URL url = new URL(ajaxSearchTarget.replace('###SEARCHQUERY###', searchQuery))
            URLConnection connection = url.openConnection()
            connection.setDoInput(true)
            InputStream inStream = connection.getInputStream()
            BufferedReader searchResultContent = new BufferedReader(new InputStreamReader(inStream))
            jsonResult = searchResultContent.getText()
            parseJsonAndPopulateObject()
        }
    }

    private void parseJsonAndPopulateObject() {
        def jsonArray = JSON.parse(jsonResult)
        this.responseStatus = Integer.parseInt(jsonArray.responseStatus as String, 10)
        this.responseDetails = jsonArray.responseDetails
        this.moreResultsUrl = jsonArray.responseData.cursor.moreResultsUrl
        this.currentPageIndex = Integer.parseInt(jsonArray.responseData.cursor.currentPageIndex as String, 10)
        this.pages = jsonArray.responseData.cursor.pages
        this.estimatedResultCount = Integer.parseInt(jsonArray.responseData.cursor.estimatedResultCount as String, 10)
        results = jsonArray.responseData.results.collect {
            new Expando(
                    content: it.content,
                    GsearchResultClass: it.GsearchResultClass,
                    titleNoFormatting: it.titleNoFormatting,
                    title: it.title,
                    cacheUrl: it.cacheUrl,
                    unescapedUrl: it.unescapedUrl,
                    url: it.url,
                    visibleUrl: it.visibleUrl
            )
        }
    }
}

Hope That Helps :)
Regards
Kushal Likhi

  • Share/Bookmark

Annotation for checking required session fields

Posted by Uday Pratap Singh on September 21st, 2011

Recently I worked on a project where I used spring security plugin. Its a very wonderful plugin for making your application secured from unauthorized users. It gives you a simple annotation @Secured to add security to your action and controller. Thats the first time I got to know the real use case of annotation. So I started reading about annotation and few days later I found the use case to implement my own annotation.

All the projects I have worked on had login functionality where we put the userId and projectId into the session. Then in my code I use to get the user from session.userId. Something like

def books = {
   User user = User.get(session.userId)
   Project project = Project.get(session.projectId)
   ......
   .....
}

The above code fails when user directly hits this action because there is no check to verify the user is not null. The simple answer for this problem is either use beforeInterceptor or filters. So we started checking the session.userId in filters. But again there are cases where you dont want to check this session value or you can say there are public urls as well. Now we have to put few if else statements in filter.

Here I got my use case to implement an annotation for controllers and actions which checks for the required fields in the session before getting into the action. So I created an annotation in src/groovy folder

import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

@Target([ElementType.FIELD, ElementType.TYPE]) // Annotation is for actions as well as controller so target is field and for class
@Retention(RetentionPolicy.RUNTIME) // We need it at run time to identify the annotated controller and action
@interface RequiredSession {
    String[] exclude() default [] // To exclude some of the actions of controller

    String[] fields() default ["userId","projectId"] // The default value is set to userId and projectId that can be overridden while using the   annotation on controller or action.

    String onFailController() default "home" // Default controller when the field not in session is set to index page

    String onFailAction() default "index" // Default action when the field not in session is set to index page
}

Now I created a ApplicationFilters and before redirected the request to any action I check for the condition of session fields if the requested action or controller is annotated. The code in the filter is something like

class ApplicationFilters {
    def filters = {
        validateSession(controller: '*', action: '*') {
            before = {
                if (controllerName) {

//Get the instance of controller class from string value i.e; controllerName
                    def controllerClass = grailsApplication.controllerClasses.find {it.logicalPropertyName == controllerName}

//Read the RequiredSession annotation from controller class
                    def annotation = controllerClass.clazz.getAnnotation(RequiredSession)

//Get the current action from actionName otherwise read default action of controller
                    String currentAction = actionName ?: controllerClass.defaultActionName

//Look for the annotation on action if controller is not annotated or the action name is excluded
                    if (!annotation || currentAction in annotation.exclude()) {

//Get the action field from string value i.e; currentAction
                        def action = applicationContext.getBean(controllerClass.fullName).class.declaredFields.find { field -> field.name == currentAction }
//If action is found get the annotation else set it to null
                        annotation = action ? action.getAnnotation(RequiredSession) : null
                    }

//Check for the field in session whether the are null or not if any of the field is null loginFailed is true
                    boolean loginFailed = annotation ? (annotation.fields().any {session[it] == null}) : false

                    if (loginFailed) {

// If login is failed user redirected to on fail action and controller
                        redirect(action: annotation.onFailAction() , controller: annotation.onFailController())
                        return false;
                    }
                }
            }

        }
    }
}


And its all done. Now we just annotate our controller and actions accordingly.

@RequiredSession(exclude = ["registration", "joinProject"])
class UserController {
      def edit ={}
      def update = {}
      def list ={}
      def save ={}

      def registration ={}
      def joinProject = {}
}

In above example registration and joinProject action will bypass the session fields check.

@RequiredSession
class ItemController {
        def index={}
        def buy ={}
        def save ={}
}

All the action of above examples can be accessed only when user is logged in.

class HomeController {
      def index ={}
      def aboutUs={}
      @RequiredSession
      def dashboard = {}
}

Actions other than dashboard are public actions which can be accessed without login.

class UserController {
  @RequiredSession(fields = ["loggedInUserId"])
   def updatePassword = {

   }
}

For updating password user dont need to have some project into session so we specified the fields to be checked in session.

Hope it helps



## Uday Pratap Singh ##
uday@intelligrape.com
http://www.IntelliGrape.com/
http://in.linkedin.com/in/meudaypratap

  • Share/Bookmark

Playing with call() using Groovy Metaprogramming

Posted by Bhagwat Kumar on September 15th, 2011

In groovy you can use "()" with any groovy object which in turn evaluates to invocation of call() method on that object.
For example, the following are valid Groovy statements :

List myList=["one", "two"]
myList()
10()
500 6+5
[name:"Bhagwat", profession:"Software engineer"] name

Obviously they will throw Runtime exception (MissingMethod/MissingProperty) instead of compilation error. Using meta programming support you can make them happen even though they are Java objects.

Think of this sample groovy code :

List myList=["Apple", "Banana", "Orange"]
myList()

After executing the above code you will get an exception : “No signature of method: java.util.ArrayList.call() is applicable for argument types: () values: []“.

Here myList() statement is equivalent to myList.call(). This gives us a clue that we can catch method calls like above. Lets inject the call method using groovy metaprogramming in List interface :

List.metaClass.call={index->
 delegate.getAt(index) 	//delegate[index]
}

/* Now the following statements work : */
List myList=["Apple", "Banana", "Orange"]

myList[1]		// Using the overloaded operator [] bygroovy

myList.call(1) 	// index will be 1 ; will return "Banana"
myList(1)		//  recall the syntax used in Microsoft VB.net to access Array
myList 1		// you can omit parenthesis if there is at least one argument

We can move one step ahead by passing a Map to the closure to make the method having named parameters :

List.metaClass.call={Map namedArgs->
    namedArgs.each{
	delegate[it.key]=it.value
    }
}

List demo=[]
demo(0:"Java", 1: "Groovy", 2: "Scala")

demo(0) // "Java"
demo(1) // "Groovy"

When I was learning computer science, I used to write statements like :

x=5
println 5+2(5+x(4)/2)  // should be 35

But that always threw an exception, can you make this work as expected? Give it a try if you really think this blog taught you something. Compare your solution here http://groovyconsole.appspot.com/script/557002.

Hope this let you think in groovy way.

Bhagwat Kumar
bhagwat@intelligrape.com

  • Share/Bookmark
Posted in Groovy

Groovy Category Annotation

Posted by Uday Pratap Singh on July 31st, 2011

Annotations really provides a whole new view of programming things. Groovy also provides some of its own annotations one of them is Category. Lets take an example of using it. We create a IntegerUtil class and annotate it with Category.

@Category(Integer)
class IntegerUtil {
    List<Integer> multiples(Integer upto) {
        (1..upto).collect {this * it}
    }
}

Now the above code made your class any other groovy category class for example Time Category. Now you can use these methods as follows -:

List<Integer> multiples
use(IntegerUtil) {
    multiples = 2.multiples(10)
}
println multiples  // Output -: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

It really helps when you want some more helper methods on already existing classes.


Hope it helps


## Uday Pratap Singh ##
uday@intelligrape.com
http://www.IntelliGrape.com/
http://in.linkedin.com/in/meudaypratap

  • Share/Bookmark
Posted in Groovy

Batch update performance enhancements using SQL withBatch()

Posted by roni on July 5th, 2011

Hi guys,

Recently as part of a project, I had to populate a SQLite database with large amounts of data pertaining to a number of classes requiring more than 5000 inserts and updates per class. I created a new SQLite database using Groovy’s Sql class. The initial strategy involved creating prepared statements and executing individual insert/update statements for each record that needed to be inserted/updated in the new SQLite database.

However the process was taking longer than expected, and the cumulative time taken for the whole application to sync less than 30 classes was coming to be more than 2 minutes. This time taken was extremely high regarding the context of the application and was a real performance bottleneck. What I did notice was that the insert statements were identical for a particular class, disregarding the values that needed to be inserted. The same was the case with the update statements.

After looking through the Sql GDK, I found a method named Sql.withBatch() that performs batch manipulation of records in a database. See the following code for illustration:

Sql sql = Sql.newInstance("jdbc:sqlite:/home/ron/Desktop/test.db", "org.sqlite.JDBC")
sql.execute("create table dummyTable(number)")
Long startTime = System.currentTimeMillis()
100.times {
     sql.execute("insert into dummyTable(number) values(${it})")
}
Long endTime = System.currentTimeMillis()

println "Time taken: " + ((endTime - startTime)/1000)

The output of the above code comes out to be 14.313 seconds. That is to execute 100 insert statements with only a single attribute, it would take around 15 seconds. The time taken to insert records is dependent on the number of records being inserted and increases exponentially. Clearly a performance bottleneck in any application involving batch inserts and updates.

Let us consider the same code and the performance with the withBatch() closure.

Sql sql = Sql.newInstance("jdbc:sqlite:/home/ron/Desktop/test.db", "org.sqlite.JDBC")
sql.execute("create table dummyTable(number)")
Long startTime = System.currentTimeMillis()
sql.withBatch {stmt->
    100.times {
      stmt.addBatch("insert into dummyTable(number) values(${it})")
    }
    stmt.executeBatch()
}
Long endTime = System.currentTimeMillis()
println "Time taken: " + ((endTime - startTime)/1000)

The time taken with the above code comes out to be 0.103 seconds! A remarkable performance improvement over the conventional method of inserting records using the execute() method.

The only drawback with using the withBatch() closure is that it does not allow prepared statements to be added to the batch. This limits the use of batch statements as we have to manually create insert or update statements.

Cheers
Ron
roni[at]intelligrape[at]com

  • Share/Bookmark
Posted in Database, Grails, Groovy

Grails Data Binding & criteria reuse

Posted by Uday Pratap Singh on July 1st, 2011

Data Binding in grails is something that I love alot. In most of the cases we look at the Binding with respect to some domain class but binding can be one of the best candidate for searching and filtration.
In my recent project we had a domain Class Article and the user could filter articles on different criteria. The page looks something like following

We had 3-4 such pages but with some extra states (Enum property) of article. So for doing this we created two CO classes, one for basic search properties like max, offset, order and sort and other for article related fields. So the CO goes like following

class SearchCO {
  Integer max = 10
  Integer offset = 0
  String sort = "id"
  String order = "asc"

  def searchCriteria = {
    order(sort, order)
  }
}

class ArticleSearchCO extends SearchCO {
  List<ArticleType> types  // This is Enum
  List<Long> styleIds
  List<Long> categoryIds
  String topic
  def searchCriteria = {
     and {
      if (topic) {
        ilike("topic", "%${topic}%")
      }

      if (categoryIds) {
        subCategory {
              inList("id", categoryIds)
          }
      }

      if (styleIds) {
        writingStyle {
             inList("id", styleIds)
         }
      }

      if (types) {
            inList("type", types)
        }
    }
    super.searchCriteria
  }
}

In our controller side we got the fully populated object that can be used for searching the different articles based on searching. So our controller side code was something like

def findWork = {ArticleSearchCO co ->
    List<Article> articles = authorService.findWork(co)
    render(template:"articles",model:[articles:articles,totalCount:articles.totalCount])
}

def currentWork = {ArticleSearchCO co ->
    List<Article> articles = authorService.currentWork(co)
    render(template:"articles",model:[articles:articles,totalCount:articles.totalCount])
}

As I already have the searching closures in my CO so the code in my service was something like

public List<Article> findWork(ArticleSearchCO co) {
    def articleCriteria = Article.createCriteria()
    Closure searchCriteria = co.searchCriteria
    searchCriteria.delegate = articleCriteria
    List<Article> articles = articleCriteria.list([max: co.max, offset: co.offset]) {
      eq("status", ArticleStatus.Unassigned)
      searchCriteria()
    }
    return articles
  }

In the same way for currentWork method I just changed the status i.e; ArticleStatus.InProgress. Thats how I handled the searching, filtering, pagination which was all Ajax. I tried to make my code as DRY as possible . There are still few things that I dont like about it one is so many if statements and other is delegating the searching criteria in each method. I think now with the support of namedQuery I can optimize the method.

Hope it helps

## Uday Pratap Singh ##
uday@intelligrape.com
http://www.IntelliGrape.com/
http://in.linkedin.com/in/meudaypratap

  • Share/Bookmark

Initializations in Grails Unit Test Cases

Posted by Imran Mir on June 14th, 2011

Most of us have experienced how important the Unit test cases are for our code base. I feel the other thing that is equally important, is the speed at which we can write the unit test cases. In Unit Testing, initializing different objects in setup of the test case (e.g., while testing a method which queries the database) can become a pain, especially when the objects to be initialized have many attributes and relationships. Grails/Spock have simplified initialization process for us. All we need to is to initialize just the required attributes of the objects, along with the id field,e.g., while testing a method of a class Student :

class Student {
  String name
  String fathersName
  String address
  static belongsTo = [school: School]

 static constraints = {
    name(nullable: false)
    fathersName(nullable: false)
    address(nullable: false)
  }

  // METHOD TO BE TESTED
  List<Student> findMySchoolsStudentsWithNamesLike(String nameLike) {
    List<Student> students = Student.findAllBySchoolAndNameLike(this.school, '%' + nameLike + '%')
    return students
  }

}

To test the method, a Spock test case with the simplified initializations will be like:

 def "My School students are retrieved correctly"() {
    setup:
    School school = new School(id: 1)
    List<Student> students = (1..10).collect {new Student(id: it, name: "name${it}", school: school)}
    mockDomain(Student, students)

    expect:
    students[0].findMySchoolsStudentsWithNamesLike('1').size() == 2
  }

Similar setup can work in Grail Unit test case.
Simplification of the initialization process has made Unit testing simpler and faster, thus allowing us to write more Unit test cases.

Cheers,
Imran Mir
imran@intelligrape.com

  • Share/Bookmark
Posted in Grails, Groovy, Test, Unit Test