Showing posts with label Grails. Show all posts
Showing posts with label Grails. Show all posts

Thursday, February 10, 2011

Wednesday, September 1, 2010

Localization i18n for Grails and App Engine

Getting localization working on Grails on GAE
see below for workaround

checkout this jira:
http://jira.codehaus.org/browse/GRAILSPLUGINS-1905

Tuesday, August 31, 2010

JPA query syntax

Within a controller:

def query = entityManager.createQuery("select from Account a where a.key=:key order by ${params.sort} ${params.order}")
query.setParameter("key",session.key)
query.setMaxResults( params.max )
query.setFirstResult( params.offset )
def accounts = query.resultList;

EntityManager isn't injected in Services but jpaTemplate is so:

private getEntityManager(){
jpaTemplate.execute({EntityManager entityManager->
return entityManager;
} as JpaCallback);
}

Friday, October 23, 2009

XWiki plugin on app engine

Using xwiki plugin in your grails application on app engine?
Then you'll need to delete core.jar from the deployment folder
‹app-name›/target/war/WEB-INF/lib

Wednesday, October 7, 2009

JCache in App Engine and Grails

Caching is a great way to improve performance in any application, the less hits to the db for common tasks the greater the performance gain.

And here's how to do so in Java on Google's App Engine and Grails.

Google exposes their memcache caching system via the JCache interface

first of all you may wanna start with the javadocs here.

Since CacheManager is a singleton you can save some code by exposing it as a bean.
in resources.groovy:
cacheManager(javax.cache.CacheManager){
 it.factoryMethod = "getInstance"
}


Now you will need to initialize the cache, this has to be done only once so i do it in Bootstrap.groovy


class BootStrap {
 def cacheManager;
 def init = { servletContext ->
  CacheFactory cacheFactory = cacheManager.getCacheFactory();
  def cache = cacheFactory.createCache([:]);
  cacheManager.registerCache("cache",cache);
 }
}

See below for a practical example of using the cache:

class ForumController {
 def entityManager;
 def list = {
  def cache = cacheManager.getCache("cache")
  def forums;
  if(cache.get("allForums")){
   forums = cache.get("allForums");
  }
  else{
   forums = //your code to get all forums
   //please note the collect enclosure.
   cache.put("allForums",forums.collect{it});
  }
  ["forums":forums]
 }
}



One small caveat, you can store a collection of objects in the cache but it will need to be a ArrayList, so:
cache.put("allForums",Forum.list())
will not work, you will have to do
cache.put("allForums",Forum.list().collect{it})

Thursday, October 1, 2009

Exposing google UserService as a bean in Grails

Here's a how to expose the google's com.google.appengine.api.users.UserService as a bean in your application.

In resources.groovy

beans = {
 userService(com.google.appengine.api.users.UserServiceFactory){
  it.factoryMethod = "getUserService"
 }
}

I use the service in a taglib to expose some useful methods as tags.


class GoogleUserTagLib {
    def userService;
   
    def isUserAdmin = {attrs, body ->
        try{
            if( userService.isUserAdmin() ){
                out << body();
            }
            else{
                out << "NOT ADMIN"
            }
        }
        catch(e){
            out << "";
        }
    }

    def isUserLoggedIn = {attrs, body ->
        try{
            if( userService.isUserLoggedIn() ){
                out << body();
            }
            else{
                out << "";
            }
        }
        catch(e){
            out << "";
        }
    }

    def isUserNotLoggedIn = {attrs, body ->
        try{
            if( !userService.isUserLoggedIn() ){
                out << body();
            }
            else{
                out << "";
            }
        }
        catch(e){
            out << "";
        }
    }

    def loginURL = {attrs, body ->
        def destinationURL = attrs.url;
        def authDomain = attrs.domain ?: null;
        def url = "";

        if(authDomain){
            url = userService.createLoginURL(destinationURL,authDomain);
        }
        else{
            url = userService.createLoginURL(destinationURL);
        }
        out << url;
    }

    def logoutURL = {attrs, body ->
        def destinationURL = attrs.url;
        def authDomain = attrs.authDomain;
        def url = "";

        if(authDomain){
            url = userService.createLogoutURL(destinationURL,authDomain);
        }
        else{
            url = userService.createLogoutURL(destinationURL);
        }
        out << url;
    }
}

so now you can do ‹g:isUserLoggedIn›YOU ARE LOGGED IN‹/g:isUserLoggedIn›

Saturday, September 26, 2009

Beginning Grails on Google AppEngine

Just a quick writeup on Grails+Gorm-JPA+GAE

What you will need:
At the time of this writeup i'm using
  • Grails 1.1.1
  • GAE 1.2.5
  • appengine plugin 0.8.5
  • gorm-jpa plugin 0.5
Things to note:
  • App engine uses Datanucleus to enhance Domain classes, on Windows there is a character limit on the command line see here one way i found around this problem is to end Domain classes with XXXDomain. e.g. UserDomain.groovy and update %APPENGINE_HOME%/config/user/ant-macros.xml
    from
    ‹fileset dir="@{war}/WEB-INF/classes" includes="**/*.class"›

    to
    ‹fileset dir="@{war}/WEB-INF/classes" includes="**/*Domain.class"›

  • To use google's datatypes in Domains, you have to add the annotation
    @Enumerated
    e.g.
    @Enumerated
    Text longText;
  • Also when bootstrapping do NOT populate the FIRST google datatype in a Domain class,
    this causes the datatype NOT to be mapped.
  • To simplify saving Text datatypes, you can override the default getters and setters on the Domain class like so:
    void setLongText(String text){
    longText = new Text(text);
    }

    String getLongText(){
    return longText?.getValue();
    }