DSL with Groovy

Creating dsl in groovy is easy .For example below dsl is for adding roles and permissions i
DSL :

 roles {
  
   "author" {
      addPermission("read")
      addPermission("write")
  }
  add("admin") {
     addPermission("watch")
     addPermission("figure")
  }
  
  "admin" {
     addPermission("read")
     addPermission("write")
  }
  
  "admin" {
  
     addPermission("delete")
  }
  
  "author" {
     addPermission("chat")
  }
  
  "reader" {
     addPermission("login")
     addPermission("read")
  
  }
  
  "anonymous" {
  
    addPermission("read")
    addPermission("like")
  }
  
 

}

And this is code for this dsl to work :

 def roles(Closure cls) {
   if(!cls) return
   def rm = new RolesManager()
   def rc =  new RolesConfigurer(roleManager:rm,methodFindingStrategy:{clss,name,margs ->          findMetaMethod(clss,name,margs)})

   cls.delegate = rc
   cls()
   System.out.println rm.rolesWithPermissions

}

class RolesManager  {
  
  def rolesWithPermissions=[:]
  
  
  
  def add(String role ){
  
    if(!rolesWithPermissions[role]) {
       rolesWithPermissions[role] = [] 
    }
  }
  
  
  def addPermission(String role,String permission) {
      
      if(!rolesWithPermissions[role]) {
         add(role)
      } 
      
      rolesWithPermissions[role]   <<  permission
  } 

}

public class RolesConfigurer implements GroovyInterceptable {

   def roleManager 
   
   def methodFindingStrategy
   
   
   def add(String role,Closure cls) {
     roleManager.add(role) 
     
     def clsDelegate = new Expando()
     
     clsDelegate.addPermission = {String perm ->
         roleManager.addPermission(role,perm)
     }
     cls.delegate = clsDelegate
     cls.resolveStrategy = Closure.DELEGATE_ONLY
     cls()
   
   }
   
   public Object invokeMethod(String name, Object args) {
   
     def m =  methodFindingStrategy.call ([this,roleManager],name,args)
     
     if(m) m()
     else {
      
        def m2=  metaClass.getMetaMethod("add",([name,args].flatten()) as Object[])
      
        if(m2) m2.invoke(this,([name,args].flatten()) as Object[])
        else System.out.println "method $name not found"
      }
            
   }
   
   
  

}

def findMetaMethod(def clss ,String name ,Object[] margs) {
    for(cls in clss) {
    
       def toRet = cls.metaClass.getMetaMethod(name,margs)
       
        if(toRet) return {toRet.invoke(cls,margs)}
    }

}


Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s