Groovy « Intelligrape Groovy & Grails Blogs

Archive for the ‘ Groovy ’ Category

Groovy annotations for ToString and EqualsAndHashCode

Posted by Uday Pratap Singh on January 29th, 2012

As I am a lazy programmer most of the time I dont implement toString and equals methods on my grails domain classes. I would like to say thanks to Groovy for helping me out and giving me a ready made recipe for this. Now I just need to annotate my class with ToString and EqualAndHashCode annotation it adds appropriate implementation of these methods for me. Now My domain class looks something like this.

@ToString(includeNames = true, includeFields = true, excludes = 'dateCreated,lastUpdated,metaClass')
@EqualsAndHashCode
class Item {
    String name
    Float price
    boolean active = true
    Date dateCreated
    Date lastUpdated
}

Before adding this annotation my domain class toString looks like this

Item item = new Item(name: "Chips", active: false, price: 15)
println "To String output -: " + item //To String output -: com.intelligrape.myapp.Item : null

Now I get the following output for Item object toString

Item item = new Item(name: "Chips", active: false, price: 15)
println "To String output -: " + item //To String output -: com.intelligrape.myapp.Item(name:Chips, price:15.0, active:false)

To get this annotation on all my domain classed I updated the template of grails domain classes so that whenever I do create-domain-class it give me the annotated domain classes

@artifact.package@
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@ToString(includeNames = true, includeFields = true, excludes = 'dateCreated,lastUpdated,metaClass')
@EqualsAndHashCode
class @artifact.name@ {

    Date dateCreated
    Date lastUpdated
}

Hope it helps



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

  • Share/Bookmark

Closure Caching For Increased Performance (.memoize())

Posted by Kushal Likhi on December 29th, 2011

Well This is something awesome and can increase the performance of the project when used wisely. using the groovy .memoize() we can ask closures to perform kind of caching. This can boost up the performance of the system.

 

_

Note: This feature is available in groovy 1.8+

Well Let me Explain this Using Examples

Now suppose i have a function “distance” which calculates distance between two points.
Hence for it instead of writing a function(Method) lets write a closure for it.

        def distance = {x1, y1, x2, y2 ->
            sleep(200)  //just to add a delay for demo purposes
            Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        }

       //To Call It 5 Times
       5.times {
            def t1 = System.currentTimeMillis()
            println distance(100, 20, 400, 10)
            println "took: ${System.currentTimeMillis() - t1} milliseconds to execute"
        }

Now if we will Run this the Output will be as follows:

300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 200 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute

Each time this closure is called all statements are executed again and hence re-computation. But if set of inputs are same then technically output should be same. hence a type of caching will help.
Also if several users are acessing the app then for each user if something is done again and again though the inputs are same then that is again a overhead, this issue can also be solved by memoizeing. :)

Now lets Do it with .memoize()

        def distance = {x1, y1, x2, y2 ->
            sleep(200)  //just to add a delay for demo purposes
            Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        }.memoize() //Note now closure is memoized 

       //To Call It 5 Times
       5.times {
            def t1 = System.currentTimeMillis()
            println distance(100, 20, 400, 10)
            println "took: ${System.currentTimeMillis() - t1}"
        }

Now the result is:

300.1666203960727
took: 202 milliseconds to execute
300.1666203960727
took: 1 milliseconds to execute
300.1666203960727
took: 1 milliseconds to execute
300.1666203960727
took: 0 milliseconds to execute
300.1666203960727
took: 0 milliseconds to execute

We can definitely see the difference between time taken to execute.
AND HURRAY, ALL REPETITIVE CALLS WITH SAME INPUT DATA ARE NOW CACHED AND HENCE INCREASED PERFORMANCE.

 

Hope it helped
Regards
Kushal Likhi

  • Share/Bookmark
Posted in Grails, Groovy

Install Apps on Facebook Fan page using API

Posted by Vishal Sahu on December 18th, 2011

Hi,
In my current grails project, we are using Facebooks Apps for our application so that any user who wish to use that app, can attach it with his/her Facebook Fan Page manually by visiting the App Profile Page and then adding it to the Fan Page. Then the attached facebook app can fetch data from our project.


But few days ago, Facebook announced that it is Removing App Profile Pages.
Now for adding facebook apps to fan page, we can either Create an Profile page for app or Add the app to Fan page using API.


I implemented the feature to attach any Facebook App to Facebook Fan page using API and thought it worth sharing.


I am assuming that you already have the Facebook Page Access Token with you, if not you can see how to Integrate facebook with web application and get access token here.


Get App Id from Facebook App page:-


To attach any Facebook Fan page, we need to issue an HTTP POST request to the facebook URL.
URL for POST request

URL :  https://graph.facebook.com/${FACEBOOK_PAGE_ID}/tabs

Values we will be requiring :


String FAN_PAGE_ACCESS_TOKEN = fan page access token.
String APP_ID = app id from the registered app.
String FACEBOOK_PAGE_ID = id of the facebook page to which app is to be attached.

Code to issue post request at the given URL:


        StringBuilder sb = new StringBuilder("access_token=");
        sb.append(URLEncoder.encode(FAN_PAGE_ACCESS_TOKEN, "UTF-8"));
        sb.append("&app_id=");
        sb.append(URLEncoder.encode(APP_ID, "UTF-8"));

        URL url = new URL("https://graph.facebook.com/${FACEBOOK_PAGE_ID}/tabs");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        String publishedPostId
        try {
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Content-Length", "" + sb.toString().length());
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream());
            outputStreamWriter.write(sb.toString());
            outputStreamWriter.flush();
            log.debug("Response code ${connection.responseCode} , Message : ${connection.responseMessage}")
            if (connection.responseCode != 200) {
                log.debug("Unable to attach app to facebook fan page")
            }
        } finally {
            connection?.disconnect()
        }

So, we can attach any Facebook App to the Facebook Fan Page using the above code.


This worked for me.
Hope it helps.


Cheers !!!
Vishal Sahu
vishal@intelligrape.com
http://www.linkedin.com/in/vishalsahu
http://www.intelligrape.com

  • Share/Bookmark
Posted in Grails, Groovy

Integrating Google plus in grails application

Posted by Vishal Sahu on December 6th, 2011

In my current project, i needed to integrate Google+ in the application using server-side API. Google uses OAuth2.0 protocol for authorization when our application tries to access the data. All we require is an access token to fetch data from Google using REST calls which serves data in JSON format.

I implemented it using Web Server Applications API and thought it worth sharing.


There are basically 3 steps to fetch data from Google.


1. Register an application.

We need to register an application at Google API Console. Go to the Google console page using the link provided and create an aplication.


Steps involve in registering an application are:-


a.) Create project by providing name to the project.



b.) Turn ON the service required, in our case it is Google Plus API.



c.) Create a Oauth 2.0 Client ID.



d.) Create the OAuth 2.0 ClientId and provide the callback URL where google will send the authorization token.



e.) Note down Client ID and Client Secret as generated in the above step.



2. Obtain an Access Token from the Google Authorization Server.


Obtaining an access token involves 2 steps.


a.) Request for Authorization Code.


In this step, we will request the Google server for authorization code by providing registered application client ID in the URL to Google server.

I created an action to redirect to Goolge, when someone want to connect to google plus.

String CLIENT_ID =client_id_obtained from registered app
String CALLBACK_URL = callback_url_as_mentioned in the registered app.
String GOOGLE_PLUS_SCOPE='https://www.googleapis.com/auth/plus.me'    // scope is the permissions we are requesting.

Action code is as:

def registerOnGooglePlus = {
String authorizeUrl = "https://accounts.google.com/o/oauth2/auth?scope=${GOOGLE_PLUS_SCOPE}&
redirect_uri=${CALLBACK_URL}&response_type=code&client_id=${CLIENT_ID}&access_type=offline"
URL urlForGooglePlus = new URL(authorizeUrl)
redirect(url: urlForGooglePlus)
}

The Redirect will take user to permissions page, if the user is already logged-in or will take to login page and then permissions page.

After approving the required permissions, user will redirect back to the application’s registered Callback URL with the authorization code.



b.) Request for Access Token with the authorization code obtained from the above action.


Access Token can be received by a POST request using the Client Secret and authorization code received.

The POST call requires 5 properties to be send in the body of the request in the encoded form.


	code : The authorization code returned from the initial request
	client_id : The client_id obtained during application registration
	client_secret : The client secret obtained during application registration
	redirect_uri : The URI registered with the application
	grant_type : authorization_code

// Sample action to receive authorization code

def callBack={
StringBuilder sb = new StringBuilder("code=");
sb.append(URLEncoder.encode(code, "UTF-8"));
sb.append("&client_id=");
sb.append(URLEncoder.encode(clientId, "UTF-8"));
sb.append("&client_secret=");
sb.append(URLEncoder.encode(clientSecret, "UTF-8"));
sb.append("&redirect_uri=");
sb.append(URLEncoder.encode(callbackUrl, "UTF-8"));
sb.append("&grant_type=");
sb.append(URLEncoder.encode('authorization_code', "UTF-8"));

String URL_TO_REQUEST_TOKEN= 'https://accounts.google.com/o/oauth2/token'

URL url = new URL(URL_TO_REQUEST_TOKEN);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" + sb.toString().length());
connection.setRequestProperty("Host", "accounts.google.com");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream());
outputStreamWriter.write(sb.toString());
outputStreamWriter.flush();
log.debug("Response code ${connection.responseCode} , Message : ${connection.responseMessage}")
String resultData = connection.content.text
def responseJson = JSON.parse(resultData)
String ACCESS_TOKEN = responseJson?.access_token
}
catch (Exception e) {
e.printStackTrace()
}
}

3. Calling Google API.

Now, with the help of access token, we can call google API to fetch Data by appending the access token in the GET request.

Example:


To fetch person’s profile data

GET :  https://www.googleapis.com/oauth2/v1/userinfo?access_token=ACCESS_TOKEN

To get list of profile acitivties

 GET :  https://www.googleapis.com/plus/v1/people//activities/public?access_token=ACCESS_TOKEN

References:-
http://code.google.com/apis/accounts/docs/OAuth2WebServer.html

http://code.google.com/apis/accounts/docs/OAuth2.html


Hope this helps..!!!


Vishal Sahu
vishal[at]intelligrape[dot]com
www.intelligrape.com

  • Share/Bookmark

Validating emails, urls and date using Java API

Posted by Bhagwat Kumar on November 14th, 2011

Recently I was looking for a programmatic way for validating data against well known validation e.g. email and date. I have to use them inside custom validator and sometimes in controller/action. Creating Command objects for validating was not suitable in my case(overkilling solution). Writing/looking for regular expression was another solution. I found a special class GenericValidator in org.apache.commons.validator package (commons-validator jar file, bundled with grails jars) . The class has many useful static methods for validating data. e.g. for validating email, url, credit card, date etc. Here is the sample code for validation using GenericValidator class:

import org.apache.commons.validator.GenericValidator

assert GenericValidator.isEmail("bhagwat@intelligrape.com")  //valid email
assert !GenericValidator.isEmail("bhagwatintelligrape.com")  // invalid email

assert GenericValidator.isUrl("http://www.intelligrape.com")  //valid URL
assert !GenericValidator.isUrl("www.intelligrape.com") //invalid URL

assert GenericValidator.isCreditCard("4111111111111111") // valid visa card number
assert !GenericValidator.isCreditCard("4111111111111112") // invalid visa card number

assert GenericValidator.isDate("2011-12-30", "yyyy-MM-dd", true) // valid date(last argument for checking strict)
assert GenericValidator.isDate("2011-02-28", "yyyy-MM-dd", true) // valid date - 28th Feb
assert !GenericValidator.isDate("2011-02-29", "yyyy-MM-dd", false) // invalid date - 29th Feb 2011

For other useful methods and their details follow the link :
http://commons.apache.org/validator/apidocs/org/apache/commons/validator/GenericValidator.html.

In addition to GennericValdator class there are separate classes for validating date, email, credit card, ISBN validator in the org.apache.commons.validator package viz. DateValidator, CreditCardValidator, EmailValidator, ISBNValidator, UrlValidator and so on. Here is the sample code for using DateValidator class.

import org.apache.commons.validator.DateValidator

DateValidator dateValidator=DateValidator.getInstance()
assert dateValidator.isValid("11-02-28", "yy-MM-dd", true)
assert !dateValidator.isValid("11-02-29", "yy-MM-dd", true)

Hope it helps you.

Bhagwat Kumar
bhagwat(at)intelligrape(dot)com

  • Share/Bookmark
Posted in Grails, Groovy

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