Andrey Redko

About Andrey Redko

Andriy is a well-grounded software developer with more then 12 years of practical experience using Java/EE, C#/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).

Simple but powerful DSL using Groovy

In one of my projects we had very complicated domain model, which included more than hundred of different domain object types. It was a pure Java project and, honestly, Java is very verbose with respect to object instantiation, initialization and setting properties. Suddenly, the new requirement to allow users define and use own object models came up. So … the journey begun.

We ended up with the idea that some kind of domain language for describing all those object types and relations is required. Here Groovy came on rescue. In this post I would like to demonstrate how powerful and expressive could be simple DSL written using Groovy builders.
As always, let’s start with POM file for our sample project:

 4.0.0

 com.example
 dsl
 0.0.1-SNAPSHOT
 jar

 
  UTF-8
 

 
  
   junit
   junit
   4.10
  
  
   org.codehaus.groovy
   groovy-all
   1.8.4
  
 

 
  
   
    org.codehaus.gmaven
    gmaven-plugin
    1.4
    
     
      
       1.8
       
      
      
       compile
       testCompile
      
     
    
   

   
    org.apache.maven.plugins
    maven-compiler-plugin
    2.3.1
    
     1.6
     1.6
    
   

    
 

I will use the latest Groovy version, 1.8.4. Our domain model will include three classes: Organization, User and Group. Each Organization has a mandatory name, some users and some groups. Each group can have some users as members. Pretty simple, so here are our Java classes.
Organization.java

package com.example;

import java.util.Collection;

public class Organization {
 private String name;
 private Collection< User > users = new ArrayList< User >();
 private Collection< Group > groups = new ArrayList< Group >();
 
   public String getName() {
  return name;
 }

 public void setName( final String name ) {
  this.name = name;
 }

 public Collection< Group > getGroups() {
  return groups;
 }

 public void setGroups( final Collection< Group > groups ) {
  this.groups = groups;
 }

 public Collection< User > getUsers() {
  return users;
 }

 public void setUsers( final Collection< User > users ) {
  this.users = users;
 }
}

User.java

package com.example;

public class User {
 private String name;

 public String getName() {
  return name;
 }

 public void setName( final String name ) {
  this.name = name;
 }
}

Group .java

package com.example;

import java.util.Collection;

public class Group {
 private String name;
 private Collection< User > users = new ArrayList< User >();

 public void setName( final String name ) {
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public Collection< User > getUsers() {
  return users;
 }

 public void setUsers( final Collection< User > users ) {
  this.users = users;
 }
}

Now, we have our domain model. Let think about the way regular user can describe own organization with users, groups and relations between all these objects. Primarily, we taking about some kind of human readable language simple enough for regular user to understand. Meet Groovy builders.

package com.example.dsl.samples

class SampleOrganization {
 def build() {
  def builder = new ObjectGraphBuilder(
   classLoader: SampleOrganization.class.classLoader,
   classNameResolver: "com.example"
  )

  return builder.organization(
   name: "Sample Organization"
  ) {
   users = [
    user(
     id: "john",
     name: "John"
    ),

    user(
     id: "samanta",
     name: "Samanta"
    ),

    user(
     id: "tom",
     name: "Tom"
    )
   ]

   groups = [
    group(
     id: "administrators",
     name: "administrators",
     users: [ john, tom ]
    ),
    group(
     id: "managers",
     name: "managers",
     users: [ samanta ]
    )
   ]
  }
 }
}

And here is small test case which verifies that our domain model is as expected:

package com.example.dsl

import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNotNull

import org.junit.Test

import com.example.dsl.samples.SampleOrganization

class BuilderTestCase {
 @Test
 void 'build organization and verify users, groups' () {
  def organization = new SampleOrganization().build()

  assertEquals 3, organization.users.size()
  assertEquals 2, organization.groups.size()
  assertEquals "Sample Organization", organization.name
 }
}

I am using this simple DSL again and again across many projects. It’s really simplifies a lot complex object models creation.

Reference: Simple but powerful DSL using Groovy from our JCG partner Andrey Redko at the Andriy Redko {devmind} blog

Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Leave a Reply


five × 7 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books