Thursday, 16 October 2008

Beginning Groovy and Grails - Part2

Couple of Days back i started reading Beginning Groovy and Grails Christopher M. Judd,Joseph Faisal Nusairat,Jim Shingler.

I wanted to share few quotations found from this book from next 2 chapters (3-4).

1) Unit testing is so fundamental to Groovy that it’s built right in. You don’t need to download a separate framework. Groovy already includes and extends JUnit, which is a popular Java unit-testing framework. The primary extension is groovy.util.GroovyTestCase, which inherits from junit.framework.TestCase.

2) Generating a simple XML document in Java is difficult,time consuming, and a challenge to read and maintain.

Example:


import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;

/**
* Example of generating simple XML in Java.
*/

public class GenerateXML {
public static void main (String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.newDocument();

Element todos = doc.createElement("todos");
doc.appendChild(todos);

Element task = doc.createElement("todo");
task.setAttribute("id", "1");
todos.appendChild(task);

Element name = doc.createElement("name");
name.setTextContent("Buy Beginning Groovy and Grails");
task.appendChild(name);

Element note = doc.createElement("note");
note.setTextContent("Purchase book from Amazon.com for all co-workers.");
task.appendChild(note);

// generate pretty printed XML document
TransformerFactory tranFactory = TransformerFactory.newInstance();
Transformer aTransformer = tranFactory.newTransformer();
aTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
aTransformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

Source src = new DOMSource(doc);
Result dest = new StreamResult(System.out);
aTransformer.transform(src, dest);
}
}



Groovy Builders

Groovy simplifies generating XML by using the concept of builders, based on the Builder design pattern from the Gang of Four.Groovy builders implement a concept of Groovy-Markup, which is a combination of Groovy language features, closures, and the simplified map syntax to create nested tree-like structures. Groovy includes five major builder implementations, as defined in below table. They all use the same format and idioms, so knowing one builder pretty much means we’ll be able to use them all.








NameDescription
AntBuilderEnables the script and execution of Apache Ant tasks
DOMBuilderGeneratesW3C DOMs
MarkupBuilderGenerates XML and HTML
NodeBuilderCreates nested trees of objects for handling arbitrary data
SwingBuilderCreates Java Swing UIs


Writing XML with Groovy MarkupBuilder

As noted above, we use MarkupBuilder to create XML and HTML.

Example:


/*
* Example of generating simple XML using Groovy.
*/


def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.setDoubleQuotes(true)
builder.todos {
todo (id:"1") {
name "Buy Beginning Groovy and Grails"
note "Purchase book from Amazon.com for all co-workers."
}
}

println writer.toString()


By default, MarkupBuilder uses single quotes for attribute values.

3) Reading XML with XmlSlurper

Groovy makes reading XML documents equally as easy as writing XML documents. Groovy includes the XmlSlurper class, which you can use to parse an XML document or String and provide access to a GPathResult. With the GPathResult reference, you can use XPath-like syntax to access different elements in the document.


/*
* Example of using Groovy's XmlSlurper and XPath notation
* to read and proces XML.
*/


def todos = new XmlSlurper().parse('todos.xml')
assert 3 == todos.todo.size()
assert "Buy Beginning Groovy and Grails" == todos.todo[0].name.text()
assert "1" == todos.todo[0].@id.text()


4) Generating Text with Templates

Many web applications generate text for e-mails, reports, XML, and even HTML. Embedding this text in code can make it difficult for a designer or business person to maintain or manage. A better method is to store the static portion externally as a template file and process the template when the dynamic portions of the template are known. As shown in below table, Groovy includes three template engines to make generating
text easier.






NameDescription
SimpleTemplateEngineBasic templating that uses Groovy expressions as well as JavaServer Pages (JSP) <% %> script and <%= %> expression syntax
GStringTemplateEngineBasically the same as SimpleTemplateEngine, except the template is
stored internally as a writable closure
XmlTemplateEngineOptimized for generating XML by using an internal DOM



/**
* Script used to generate a template based email.
*/

import groovy.text.SimpleTemplateEngine

/**
* Simple User Groovy Bean.
*/

class User {
String firstName;
String lastName;
}

def emailTemplate = this.class.getResource("nightlyReportsEmail.gtpl")
def binding = ["user": new User(firstName: "Christopher", lastName: "Judd"), "date": new Date()]
def engine = new SimpleTemplateEngine()
def email = engine.createTemplate(emailTemplate).make(binding)
def body = email.toString()

println body





nightlyReportsEmail.gtpl


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title>Collab-Todo Nightly Report for ${String.format('%tA %<tB %<te %<tY', date)}</title>
</head>

<body bgcolor="#FFFFFF" style="margin:0;padding:0;">
<div style="padding: 22px 20px 40px 20px;background-color:#FFFFFF;">
<table width="568" border="0" cellspacing="0" cellpadding="1" bgcolor="#FFFFFF" align="center">
<tr>
<td>
Dear ${user?.firstName} ${user?.lastName},
<p />
Please find your attached nightly report for ${String.format('%tA %<tB %<te %<tY', date)}.
</td>

</tr>
</table>

<table width="560" border="0" cellspacing="0" cellpadding="0" align="center">
<tr valign="top">
<td width="560" style="padding:15px 23px 10px 23px;">
<p style="font-family: Geneva, Verdana, Arial, Helvetica, sans-serif; font-size:9px; color:#999;">
&copy; 2008 Beginning Groovy and Grails by Christopher Judd, Joseph Faisal Nusairat, and James Shingler
</p>
</td>
</tr>
</table>
</div>
</body>
</html>


5) The Expando class is found in the groovy.util package and is a dynamically expandable bean, meaning you can add properties or closures to it at runtime. Combine this with Groovy’s duck typing, and Expandos are also a great way to implement mock objects during unit testing.

6) Meta Object Protocol

Another important concept to Groovy and Grails is Meta Object Protocol (MOP). This protocol enables you to add properties and behaviors to existing classes, much like the Expando class. The capability of MOP to extend classes doesn’t just exist for classes you write or Groovy classes. MOP enables you to add functionality to the Java API, including classes such as java.lang.String, which is marked as final to prevent standard Java classes from extending it and adding functionality. This is
how the Groovy JDK provides more Groovy idiomatic behavior to the standard Java classes.

In Groovy, all classes—including all Java classes—have a property of metaClass of type groovy.lang.MetaClass, similar to how all Java classes have a property of class of type java.lang.Class. The groovy.lang.MetaClass interface is similar to the Expando object in that you can add behavior at runtime. During the dispatching of a message to an object, the MetaClass helps to determine which behavior should be invoked. In addition, you can use the MetaClass to provide behavior if the class doesn’t implement the specific behavior requested. When you add closures to the builder, MetaClass interprets this as a call to amissing method and provides the specific builder functionality. For example, it might add an XML element to the enclosing parent element.


/*
* Meta Object Programming example that shows alternative ways
* to load a files.
*/


println this.class.getResourceAsStream("nightlyReportsEmail.gtpl").getText()

String.metaClass.fileAsString = {
this.class.getResourceAsStream(delegate).getText()
}

println 'nightlyReportsEmail.gtpl'.fileAsString()

println '------------------------'

Class.metaClass.getResourceAsText = { resource ->
this.class.getResourceAsStream(resource).getText()
}

println this.class.getResourceAsText('nightlyReportsEmail.gtpl')




7) Grails is not only an open source web framework for the Java platform, but a complete development platform as well. Like most web frameworks, Grails is an MVC framework.

In addition, Grails controllers are request-scoped, which means a new instance is created for each request.

Finally, the default view for Grails is Groovy Server Pages (GSP) and typically renders HTML.

8) Grails is also a complete development platform, including a web container, database,build system, and test harness out of the box. This combination can reduce project startup time and developer setup time to minutes rather than hours or days. With Grails, you typically don’t have to go find and download a bunch of server software or frameworks to get started.

9) I faced some problems running grails and this link helped me.

10) To create a grails application use this command grails create-app collab-todo

11) To run a Grails application, execute the run-app target from your project root directory as shown here:

grails run-app

12) To create a domain class,use the Grails create-domain-class target. This creates a new Grails domain class in the grails-app/domain directory, as well as an integration test for the domain class in test/
integration.

Ex: grails create-domain-class todo

13) Running the Test Harness

To run the test harness, simply execute the Grails test-app target. This executes all the unit and integration tests and displays the results of each test. In addition, it creates several reports for diagnosing any test errors or failures:

>grails test-app

14) Creating the Controller

The controller is responsible for the interaction between the view and the domain classes. Fortunately, the Grails scaffolding makes this simple. The controller consists of only a single line of code that instructs the scaffolding to do its magic and generate the basic CRUD UI.

To create a controller class, use the Grails create-controller target. This creates a new Grails controller class in the grails-app/controllers directory, as well as an integration test for the controller class in test/integration. It also creates a grails-app/views/ directory if it doesn’t exist already.

To create the TodoController class, you need to execute the create-controller target using an optional class name, as shown here:

>grails create-controller todo

If you don’t supply the class name, you will be prompted for one.

Author Information

Christopher Judd is the president and primary consultant for Judd Solutions, LLC, an international speaker, an open source evangelist, the Central Ohio Java Users Group leader, and the coauthor of Enterprise Java Development on a Budget (Apress, 2003). He has spent 12 years architecting and developing software for Fortune 500 companies in various industries, including insurance, retail, government, manufacturing, and transportation. His current focus is consulting, mentoring, and training with Java, Java EE, Java Platform, Micro Edition (Java ME), mobile technologies, and related technologies.

Joseph Faisal Nusairat is a software developer who has been working full time in the Columbus, Ohio, area since 1998, primarily focused on Java development. His career has taken him into a variety of Fortune 500 industries, including military applications, data centers, banking, internet security, pharmaceuticals, and insurance. Throughout this experience, he has worked on all varieties of application development, from design and architecture to development. Joseph, like most Java developers, is particularly fond of open source projects and tries to use as much open source software as possible when working with clients. Joseph is a graduate of Ohio University with dual degrees in computer science and microbiology and a minor in chemistry. While at Ohio University, Joseph also dabbled in student politics and was a research assistant in the virology labs. Currently, Joseph works as a senior partner at Integrallis Software (http://www.integrallis.com). In his off-hours, he enjoys watching bodybuilding competitions and Broadway musicals, specifically anything with Lauren Molina.

Jim Shingler is a senior consulting IT architect for a major midwestern insurance and financial services company. The focus of his career has been using leading-edge technology to develop IT solutions for the insurance, financial services, and manufacturing industries. He has 11 years of large-scale Java experience and significant experience in distributed and relational technologies.

No comments: