CHAPTER 4

image

Introduction to Grails

Let’s face it: developing web applications is hard. This problem has been exacerbated in today’s environment, where applications deemed to fall into the Web 2.0 category involve lots of technologies, such as HyperText Markup Language (HTML), Cascading Style Sheets (CSS), Asynchronous JavaScript and XML (Ajax), XML, web services, Java, and databases. Then on top of the technologies sit lots of open source framework choices like model-view-controller (MVC) frameworks and Ajax frameworks. To make matters worse, while the complexity of building applications continues to grow, expected turnaround times continue to shrink.

In recent years, the Java community has tried solving these issues by building applications using Java Platform, Enterprise Edition (Java EE) and its predecessor, Java 2 Platform, Enterprise Edition (J2EE). While these platforms have proven to be scalable and robust, they don’t allow for rapid, agile development. Java EE has proven over and over again that it was not written with an application level of abstraction but rather with a much lower technical level. These shortcomings led to the development of recent application frameworks and the subsequent popularity of frameworks such as Struts, Spring, and Hibernate. Furthermore, the development cycle of coding, compiling, packaging, deploying, testing, and debugging takes entirely too long for any real productivity and requires developers to switch context too frequently.

Enter Grails. Grails is an open source web development framework that packages best practices (such as convention over configuration and unit testing) with the best-of-the-best open source application frameworks (such as Spring, Hibernate, and SiteMesh). Together with the productivity of the Groovy scripting language, everything runs on top of the robust Java and Java EE platforms.

In this chapter, you will learn about the features and open source frameworks included with Grails. Then you’ll learn how to take advantage of Grails’ powerful scaffolding feature to build your first Grails application.

What Is Grails?

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, but it’s not your average Java MVC framework. Like other Java MVC frameworks, it does have models (referred to in Grails as domain classes) that carry application data for display by the view. However, unlike other MVC models, Grails domain classes are automatically persistable and can even generate the underlying database schema. Like other MVC frameworks, Grails controllers handle the requests and orchestrate services or other behavior.

Unlike most MVC frameworks, though, services and other classes can be automatically injected using dependency injection based on naming conventions. 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 it typically renders HTML. The view layer also includes a flexible layout, a templating feature, and simple tag libraries.

Other Grails advantages include minimal configuration and a more agile development cycle. Grails eliminates most of the standard MVC configuration and deployment descriptors by using initiative conventions. Also, because Grails takes advantage of Groovy’s dynamic language features, it is usually able to shorten the development cycle to just coding, refreshing, testing, and debugging. This saves valuable development time and makes development much more agile than with other Java MVC frameworks or Java EE.

As a complete development platform, Grails includes 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 find and download a bunch of server software or frameworks to get started. You also don’t have to spend time creating or maintaining complicated build scripts. Everything you need to get started comes bundled in one simple-to-install package.

Grails has an impressive list of features and is able to provide so much functionality by integration of proven open source projects.

Grails Features

Most modern web frameworks in the Java space are convoluted, full of twists and turns, and disregard the Don’t Repeat Yourself (DRY) principles. Grails, built on the concepts brought to the fore by dynamic frameworks like Rails, Django, and TurboGears, dramatically reduces the complexity of building web applications on the Java platform, leveraging already established Java technologies like Spring and Hibernate. Grails is a full stack framework and attempts to solve as many pieces of the web development puzzle through the core technology and its associated plugins. Its features include:

  • An easy-to-use Object Relational Mapping (ORM) layer built on Hibernate
  • An expressive view technology called Groovy Server Pages (GSP)
  • A controller layer built on Spring MVC
  • A command line scripting environment built on the Groovy-powered Gant
  • An embedded Tomcat container configured for on-the-fly reloading
  • Dependency injection with the built-in Spring container
  • Support for internationalization (i18n) built on Spring’s core MessageSource concept
  • A transactional service layer built on Spring’s transaction abstraction

All of these are made easy to use through the power of the Groovy language and the extensive use of Domain Specific Languages (DSLs).

Grails really has too many features to mention them all. In this section, we’ll highlight some of the more important ones.

Convention over Configuration

Rather than using lots of XML configuration files, Grails relies on conventions to configure itself, thus making application development easier and more productive. The conventions relate to the directory structure, meaning that the name and location of files is used instead of explicit configuration. This essentially means that instead of wiring in XML configuration files, you can create a class, following the Grails conventions, and Grails will wire it into Spring or treat it as a Hibernate entity thereof. For example, if you create a new domain class called User, Grails will automatically create a table called user in the database. This convention over configuration feature is centered on its directory structure. By using the convention-over-configuration paradigm, Grails can figure out a component’s responsibilities, inspecting its name and its location in the directory structure, and thus enable you to configure a particular aspect of a component only when that configuration deviates from the standard. In this way, adhering to well-known conventions, you can create an application more quickly, because you will spend less time configuring it.

Unit Testing

Unit testing is now recognized as a critical best practice to improving the quality of software deliverables and enabling long-term maintainability of an application. Furthermore, unit testing is even more important for applications written using dynamically typed languages such as Groovy, because identifying the effects of changes without the help of the compiler and unit tests can be difficult. This is why unit testing is a major Grails convention.

Grails separates its unit tests into two categories: unit and integration. Grails unit tests are free standing unit tests with no dependencies other than possibly mock objects. Integration tests, on the other hand, have access to the entire Grails environment, including the database.

Scaffolding

As you’ll see in the second half of this chapter, Grails has a scaffolding framework that generates applications with create, read, update, and delete (CRUD) functionality with very little code, allowing you to focus on defining the Groovy domain by creating classes with properties, behaviors, and constraints. At either runtime or development time, Grails can generate the controller behavior and GSP views associated with the domain classes for CRUD functionality. At the same time, it can even generate a database schema, including tables for each of the domain classes.

Object Relational Mapping

Grails includes a powerful object relational mapping framework called Grails Object Relational Mapping (GORM). Like most object-relational mapping (ORM) frameworks, GORM can map objects to relational databases and represent relationships between those objects, such as one-to-one or one-to-many. But what sets GORM apart from other ORMs is the fact that it is built for a dynamic language like Groovy. It injects the CRUD methods right into the class without having to implement them or inherit from persistent super classes. Once more, it is able to provide an ORM DSL for dynamic finder methods and search criteria. You will learn more about GORM in Chapter 6.

Plugins

Grails does not propose to have all the answers to every web development problem. Instead, it provides a plugin architecture and a community where you can find plugins for things like security, Ajax, testing, searching, reporting, and web services. This plugin architecture makes it easy to add complicated functionality to your application. We will discuss plugins in more detail in “Grails Plugins,” later in this chapter.

Integrated Open Source

Grails does not suffer from the Not Invented Here (NIH) syndrome. Rather than reinvent the wheel, it integrates the best of the best industry-standard and proven open source frameworks, several of which are briefly described in this section.

Groovy

Groovy is one of the pillars of Grails. Grails 2.0 comes with Groovy 1.8. As you learned in Chapters 1-3, Groovy is a powerful and flexible open source language that stands on its own. However, its integration with Java, dynamic scripting features, and simple syntax makes it a perfect complement to Grails and provides the agile nature of the entire solution.

Spring Framework

Spring Framework is best described by its creator Rod Johnson as providing an application level of abstraction on top of the Java EE API. For example, rather than having to deal with the details of handling transactions, Spring provides a means for declaring transactions around regular Plain Old Java Objects (POJOs) so that you can focus on implementing business logic. In addition, because Spring brings Java EE features to POJOs, you’re able to develop and test your application code outside a Java EE container, thereby increasing productivity. Along with Hibernate, Spring was a major influence on the new Enterprise JavaBeans (EJB) 3.0 spec, which attempts to simplify Java EE development.

Grails implicitly handles much of the Spring integration. However, in Chapter 6, you will learn how to explicitly configure and integrate with Spring if you find it necessary.

Hibernate

Hibernate is an object-relational persistence framework that provides the foundation for GORM. It’s able to map complex domain classes written as POJOs or POGOs (Plain Old Groovy Objects) to relational database tables, as well as map relationships between the tables. As mentioned in the previous section, Hibernate had a big influence on the EJB 3.0 specification, specifically the Java Persistence API (JPA). Hibernate is one of the many JBoss projects. For more information about Hibernate, go to http://www.hibernate.org .

SiteMesh

SiteMesh is a web page layout framework that implements the decorator design pattern for rendering HTML with constant components such as the header, footers, and navigation. It is one of the components found in the OpenSymphony suite and is hosted on the OpenSymphony site. Grails hides most of the SiteMesh details from you as a developer, but in Chapter 5, you’ll see how to create page layouts and other web components such as GSP. You can find detailed information about SiteMesh at http://wiki.sitemesh.org/display/sitemesh/Home .

Ajax Frameworks

By default, Grails includes the jQuery library, but also provides support for other frameworks such as Prototype, Dojo, Yahoo UI, and the Google Web Toolkit through the plugin system. Chapter 8 will explain how to add Ajax functionality to your application to increase usability.

Tomcat

Grails 2.0 replaces Jetty with an embedded Tomcat container that is configured for on-the-fly reloading. Chapter 12 will explain how to deploy Grails applications to other containers.

H2

Grails 2.0 now uses the H23 database instead of HSQLDB, and enables the H2 database console in development mode (at the URI /dbconsole) so that the in-memory database can be easily queried from the browser. By default, Grails uses the embedded in-memory configuration, so that each time the application is run, the database is rebuilt from scratch and all data is lost. Chapter 12 will explain how to configure Grails to use other databases such as MySQL. We will discuss H2 further in “H2 Console,” later in this chapter. To find out more about H2, including how to download it, go to http://www.h2database.com/html/main.html .

Grails Architecture

Now that you know some of the features and open source frameworks included in Grails, you are more prepared to understand the Grails architecture, which is illustrated in Figure 4-1.

9781430248064_Fig04-01.jpg

Figure 4-1 .  Grails architecture

In Figure 4-1, notice that the foundation of Grails is the Java Virtual Machine (JVM).Also, notice the separation in the architecture from the Java language and the JVM. In the past couple of years, the Java community has seen a rash of new and ported languages being run on the JVM. This is particularly important in Grails, because in the next level up from the JVM, you see that both the Java and Groovy languages are used.

The final layer of the architecture is the applications you will build with Grails. Typically, this layer follows the MVC pattern. Grails also makes it easy to organize your application to make coarse-grained services.

To simplify development, Grails includes a command-line tool for creating many Grails artifacts and managing Grails projects. The Grails command line is built on top of Gant, a build system that uses the Groovy language to script Apache Ant tasks rather than Ant’s XML format. You will learn more about Gant and adding your own scripts to the Grails command line in Chapter 12.

From a runtime perspective, you can think of Grails out of the box as looking like Figure 4-2.

9781430248064_Fig04-02.jpg

Figure 4-2 .  Grails default runtime

In Figure 4-2, you see a web browser making a request to a Tomcat web container. The container forwards the request on to a controller in a similar fashion to the standard MVC model. The controller may set or use data from a domain class (model). As mentioned earlier, all Grails domain classes are persistable through the GORM framework.

You don’t need to use a Data Access Object (DAO) pattern or write SQL to persist objects. In Chapter 6, you will learn how to take full advantage of the persistable domain classes.

Out-of-the-box Grails uses an embedded H2 database, which means the database runs in the same JVM as your application and the Tomcat web container. When the controller is done, it forwards the request to a GSP, which is the view technology to render the HTML that is returned to the requesting browser.

Installing Grails

Considering the alternative to using Grails—downloading and installing a web container or application server, database, and MVC framework—installing Grails seems almost too easy. All you need to do is uncompress a file and set up some environment variables, and you’re done. Most everything is self-contained. Grails does require two prerequisites, though: you must have a JDK 1.6 or above, and you must have the JAVA_HOME environment variable configured for that JDK. In this book, we will use Grails 2.1.0

Follow these steps to install Grails:

  1. Download the latest Grails .zip or .tar/.gz file release from http://grails.codehaus.org/Download .
  2. Extract the archive to your preferred location.
  3. Create a GRAILS_HOME environment variable that points to the path where the Grails archive was extracted.
  4. Append the GRAILS_HOMEin directory to the PATH environment variable.

Once you complete these steps, the Grails command line will be available. You can use it to create the project, create artifacts, run the application, and package the application.

To validate your installation, open a command window and type the command grails -version:

> grails –version

If you have successfully installed Grails, the command will output the following:

Grails version: 2.1.0

Collab-Todo Application

Throughout this book, we’ll use a single web application example to demonstrate how to write a web application using the Grails framework. Intermittently we will use stand-alone examples to introduce some concepts so that the learning of Grails does not get tightly coupled with the application we build in the process. The application that we will use in this book is a collaborative Web 2.0 to-do application and is called Collab-Todo. The application allows users to create and manage todos in categories. It also allows users to create buddy lists of other Collab-Todo users to make it easy to assign tasks to other users. In addition, it includes reports and batch e-mails, along with a thick client and web service access.

It is important for you to experience for yourself the power and productivity of Grails early on, so for the remainder of this chapter, you will be learning to take advantage of Grails conventions and scaffolding to create a simple but functional version of the Collab-Todo application. This initial version of the application will not be a production-suitable application from a usability and design perspective. However, the Grails scaffolding is able to render a simple but functional CRUD web application with almost no code besides your domain class code. In addition, Grails will generate a database schema and populate a database with the schema when the application is run. This scaffolding-based version of the application is suitable for testing domain objects as well as quick application prototyping.

Figure 4-3 shows an example of what the CRUD todo pages will look like by the end of the chapter.

9781430248064_Fig04-03.jpg

Figure 4-3 .  Todo List page

As you can see in Figure 4-3, the Todo List page provides the ability to view all the todos in the database as well as create new todos or delete existing todos. It also provides a link to the edit page, where you can create a new todo or update an existing todo.

Figure 4-4 shows the Edit Todo page, which is basically the same page used for updating and creating todos.

9781430248064_Fig04-04.jpg

Figure 4-4 .  Edit Todo page

As you can tell from Figures 4-3 and 4-4, this is not the most attractive application, and you probably won’t want to release this to your users. In Chapter 5, you’ll learn how to make the application more usable and pleasing to your users’ eyes, and in Chapter 8, you’ll learn how to make it even better by adding Web 2.0 features.

Figure 4-5 is a Unified Modeling Language (UML) diagram of a subset of the Collab-Todo domain classes you’ll be creating in this chapter.

9781430248064_Fig04-05.jpg

Figure 4-5 .  Subset of the Collab-Todo domain classes

Notice the domain model in Figure 4-5 is very simple and includes only three domain classes. In Chapter 6, you will extend this domain model and learn about the Grails persistence framework, GORM. Initially, the domain consists of a User class, which has a Todo (task) class, and user­defined Category classes used for organizing todos into logical groups.

Creating Collab-Todo application

To create the Collab-Todo application, you need to execute the create-app target using an optional project name on the command line, as shown here:

> grails create-app collab-todo

The entire line in the preceding command line is a command, where create-app is a target. A target is a specific task that you want Grails to execute.

If you don’t supply the project name when using create-app, you will be prompted for one. On execution of this command, Grails downloads the dependencies and creates the application. The output of executing the create-app target is shown here:

|Downloading: D:grails-2.1.0liborg.springframework.uaaorg.springframework.u
| Downloading: D:grails-2.1.0libcom.google.protobufprotobuf-javaivy-2.4.1.x
| Downloading: D:grails-2.1.0liborg.bouncycastlecpg-jdk15jarscpg-jdk15-1
.........
 Created Grails Application at D:devlworkspace/collab-todo

Instead of creating the application from command line, you can use the IDE of your choice. We recommend the Groovy/Grails Tool Suite (GGTS), which you can download from http://www.springsource.org/downloads/sts-ggts.  This book uses the latest version: GGTS 3.0. GGTS provides the best Eclipse-powered development environment for building Groovy and Grails applications. GGTS provides support for the latest versions of Groovy and Grails, and comes on top of the latest Eclipse releases.

To create a new project in GGTS, use the menu options File image New image Grails Project and enter the project name as “collab-todo”.

After the create-app target has run, or after creating a new project using GGTS, you have a new directory matching the name of your project. This is the root of your new project, and you must make all subsequent Grails command-line calls from within this directory. It’s a good idea to use the cd command to get into the directory now so you don’t forget. Within the new project directory, you will find a structure matching the directory structure shown in Figure 4-6.

9781430248064_Fig04-06.jpg

Figure 4-6 .  Directory structure created by running the create­app target

As mentioned earlier, the directory structure generated from the create-app target is a part of the Grails practice of convention over configuration. The target provides locations for placing common artifacts. Throughout the book, you will learn details about each directory. For now, Table 4-1 provides a summary of the more important directories.

Table 4-1. Important Directories in the Grails Convention

Directory Description
grails-app/conf Common configuration files such as bootstrapping, logging, data source, and URL mapping (see the “Configurations” sidebar)
grails-app/conf/hibernate Custom Hibernate mappings, which are rarely needed (covered in Chapter 6 )
grails-app/conf/spring Custom Spring mapping files
grails-app/controllers Application controllers that handle requests (covered in Chapter 5 )
grails-app/domain Domain model classes (covered in Chapter 6 )
grails-app/i18n Internationalized message bundles (covered in Chapter 5 )
grails-app/services Services (covered in Chapter 6 )
grails-app/taglib Custom dynamic tag libraries
grails-app/views GSP (covered in Chapter 5 )
grails-app/views/layout Commonly shared page layouts (covered in Chapter 5 )
lib Third-party JAR files, such as database drivers
scripts Gant script for automating tasks (covered in Chapter 12 )
src/java Additional Java source files
src/groovy Additional Groovy files
test/integration Integration tests
test/unit Unit tests (introduced later in this chapter)
web-app Web artifacts that will ultimately comprise a web application archive (WAR) (many of the artifacts are covered in Chapter 5 )
web-app/css Cascading Style Sheets (covered in Chapter 5 )
web-app/images Web graphics (covered in Chapter 5 )
web-app/js JavaScript (covered in Chapter 8 )
web-app/WEB-INF Common Servlet specification WEB-INF directory containing private artifacts such as configuration files like web.xml, the Spring application context, and the SiteMesh config

Running the Application

At this point, you have a functional application that you can run and access via a web browser. It does not do much yet, but running it now will enable you to get instant feedback as you add domain and controller classes.

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

> grails run-app

The output of executing the run-app target is shown here:

Server running. Browse to http://localhost:8080/collab-todo 

To run the application in GGTS, click on “Grails Command History” as highlighted in Figure 4-7, type “run-app” on the command window, and hit Enter.

9781430248064_Fig04-07.jpg

Figure 4-7 .  Running the application in GGTS

Running the run-app target performs some initial project setup by copying files into your web application’s WEB-INF directories. Then it starts a Tomcat web container that listens on localhost port 8080. Tomcat then loads the application, causing the Grails internal classes to get initialized for filtering URL mappings and requests along with GrailsDispatchServlet. To test your app, point your web browser to that URL, as shown in Figure 4-8.

9781430248064_Fig04-08.jpg

Figure 4-8 .  Default Grails page

Figure 4-8 shows the default Grails page. As you can see, it is not very interesting; it looks like a static page. However, as you’ll see soon, there is some dynamism to this page. If you want to modify this page, it is the GSP grails-appviewsindex.gsp.

Creating the Controller

A controller handles requests and creates or prepares the response. A controller can generate the response directly or delegate to a view. 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 the unit test for the controller class in test/unit. It also creates a grails-app/views/<controller name> 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 are prompted for one. The output of executing the create-controller target is shown here:

| Created file grails-app/controllers/collab/todo/TodoController.groovy
| Created file grails-app/views/todo
| Created file test/unit/collab/todo/TodoControllerTests.groovy

Notice that when running the create-controller with the optional class name, you can leave the class name in lowercase, and Grails will automatically uppercase it for you so that it follows the standard Groovy class naming convention.

To create the controller using GGTS, click on the controllers in the collab-todo project hierarchy, and then use New image Controller as shown in Figure 4-9. Type “Todo” in the create–controller wizard as illustrated in Figure 4-10.

9781430248064_Fig04-09.jpg

Figure 4-9 .  Creating a controller

9781430248064_Fig04-10.jpg

Figure 4-10 .  Controller name

This creates the controller as well as the unit test for the controller, as illustrated in Figure 4-11.

9781430248064_Fig04-11.jpg

Figure 4-11 .  Controller and unit test

Listing 4-1 shows the generated TodoController class.

Listing 4-1.  Grails-Generated TodoController Class

package collab.todo
class TodoController {

    def index() { }
}

The TodoController class in Listing 4-1 contains an empty index action. Chapter 5 will explain actions on the controller. We will print a simple response using one of the implicit methods, the render method, which comes with controllers in Grails, as illustrated in Listing 4-2.

Listing 4-2.  Using the render Method

package collab.todo
class TodoController {

    def index() {
 render "create new tasks"
 }
}

Now run the application by typing “run-app” in the command window as explained earlier. After changing TodoController to look like it does in Listing 4-2, refresh your browser to reveal a new TodoController link on the initial page, as shown in Figure 4-12. Clicking on the controller shows the response, as illustrated in Figure 4-13.

9781430248064_Fig04-12.jpg

Figure 4-12 .  Initial Grails page with the TodoController link added

9781430248064_Fig04-13.jpg

Figure 4-13 .  Rendering the response

Testing the Controller

At the time of creating the controller, Grails also creates unit tests for the controller as discussed earlier. Listing 4-3 illustrates the unit test generated by Grails, and Listing 4-4 tests the controller.

Listing 4-3.  Generated Test

package collab.todo

import grails.test.mixin.*
import org.junit.*

/**
 * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions
 */
@TestFor(TodoController)
class TodoControllerTests {

    void testSomething() {
       fail "Implement me"
    }
}

The TodoController class in Listing 4-2 renders a textual response. To test this controller, we assert the value of the response as illustrated in Listing 4-4.

Listing 4-4.  Testing the Controller

package collab.todo

import grails.test.mixin.*
import org.junit.*

/**
 * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions
 */
@TestFor(TodoController)
class TodoControllerTests {

    void testSomething() {
                controller.index()
       assert "create new tasks" == response.text
    }
}

To run the test, we use the same command window that we use to run the application. Instead of typing “run-app” in the command window, type “test-app” (you can also type this target on the command line) and browse to the URL presented in the console to view the test report as illustrated in Figure 4-14.

9781430248064_Fig04-14.jpg

Figure 4-14 .  Test report

Scaffolding

Scaffolding lets you auto-generate a whole application for a given domain class including views and controller actions for CRUD operations. Scaffolding can be either static or dynamic; both types of scaffolding generate the exact same code. The main difference is that in static scaffolding, the generated code is available to the user prior to compile time and can be easily modified if necessary. In dynamic scaffolding, however, the code is generated in memory at runtime and is not visible to the user. We will explain both dynamic and static scaffolding, but before that we will create a domain class and then auto-generate a whole application for it using scaffolding.

Creating a Domain Class

At this point, the application we created doesn’t really do anything; it just renders a simple textual response. We will move on by creating a domain class. 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 a unit test for the domain class in test/unit.

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

> grails create­domain-class todo

If you don’t supply the class name, you are prompted for one. The output of executing the create-domain-class target is shown here:

| Created file grails-app/domain/collab/todo/Todo.groovy
| Created file test/unit/collab/todo/TodoTests.groovy

Notice that when running the create-domain-class target with the optional class name, you can leave the class name in lowercase, and Grails will automatically uppercase it for you so that it follows the standard Groovy class naming convention.

To create the domain class using GGTS, click domain in the project hierarchy and then use New image Domain Class as illustrated in Figure 4-15.

9781430248064_Fig04-15.jpg

Figure 4-15 .  Creating Domain class

Listing 4-5 shows the generated Todo domain class.

Listing 4-5.  Grails-Generated Todo Domain Class

package collab.todo
class Todo {

    static constraints = {
    }
}

The Todo domain class in Listing 4-5 appears to be the most basic of Groovy classes. As you will learn in the next couple of sections and in the next two chapters, there is more to Grails domain classes than meets the eye.

Listing 4-6 shows the Todo domain class after adding the fields shown in the UML diagram in Figure 4-5.

Listing 4-6.  Todo Domain Class After Adding Attributes, Constraints, and the toString() Method

 1. class Todo {
2.
3.   String name
4.   String note
5.   Date createdDate
6.   Date dueDate
7.   Date completedDate
8.   String priority
9.   String status
10.
11.   static constraints = {
12.     name(blank:false)
13.     createdDate()
14.     priority()
15.     status()
16.     note(maxSize:1000, nullable:true)
17.     completedDate(nullable:true)
18.     dueDate(nullable:true)
19.   }
20.
21.   String toString() {
22.     name
23.   }
24. }

In Listing 4-6, you see that lines 3-9 are several fields of both String and Date types that you would expect to find in a Todo domain class. However, there are some additional properties you don’t see that are implicit to a Grails domain class by convention. They include the id and version properties.

The id property, as you might expect, represents a unique auto-incrementing identifier and is null until the object is initially saved. The version property is a Hibernate mechanism for managing optimistic locking. Each time an object is saved, its version number gets incremented, and like the id, it is initially null. Before Hibernate saves any object, it first checks the version number in the database, and if the versions don’t match the object about to be saved—meaning it was already modified since the last read—Hibernate will throw an org.hibernate.StaleObjectStateException.

Lines 11-19 demonstrate the Grails construct of constraints. These are basically rules governing the values of the properties. For example, line 12 states the name property is required and may not be empty using a blank:false constraint, while the note, completedDate, and dueDate properties on lines 16-18 are allowed to be null. Also, note that the note property on line 16 has a maximum length of 1,000 characters. In addition to constraining the properties, the constraints dictate the order of fields on the edit pages as well as the types of HTML form fields rendered by the Grails scaffolding. The order of the constraints represents the order of the fields on the page. While a String is usually represented by an HTML input field of type text, a String property with a maxSize is usually rendered as an HTML input field of a text area to support the larger amounts of input data.

Domain classes can also have behavior implemented as methods. Lines 21-23 show the toString() method being overridden. The default toString() behavior of a Grails domain class is to print the class name followed by a colon and the object ID. To make the toString() a little more helpful, line 21 prepends the name property of the Todo instance.

This section has not even scratched the surface of domain classes. You will learn more about them in Chapter 6.

Dynamic Scaffolding

As explained earlier, the dynamic scaffolding generates controller actions and views for CRUD applications at runtime. To dynamically scaffold a domain class, we need a controller. We created a controller (TodoController) in Listing 4.1. To use the dynamic scaffolding, change the index action to a scaffold property and assign it the domain class, as shown in Listing 4-7. That’s all there is to it. This causes List Page, Create Page, Edit Page, and Show Page views, as well as delete functionality, to be generated for the specified domain class.

Listing 4-7.  Dynamic Scaffolding-Enabled TodoController

package collab.todo
  class TodoController {
  static scaffold = Todo
}

After changing TodoController to look like it does in Listing 4-7, refresh your browser and click the TodoController link on the welcome page.

Selecting the TodoController link brings you to the Todo List page shown in Figure 4-16.

9781430248064_Fig04-16.jpg

Figure 4-16 .  Todo List page

From the list page shown in Figure 4-16, you have the ability to create new domain objects (as shown in Figure 4-17 ) by clicking the New Todo button on the navigation bar.

9781430248064_Fig04-17.jpg

Figure 4-17 .  Create Todo page

The save page displays the list of properties in the order in which the constraints are ordered as shown in the Create Todo page in Figure 4-17. Note that the Grails scaffolding displays the edit fields in the appropriate date type format. A string is displayed as an HTML text input field, while createdDate is displayed as a series of drop-downs for the day of month, month, year, hour, and seconds. In addition, the note property is displayed as an HTML text area input due to the maxSize constraint. That’s not all: the Grails scaffolding is also smart enough to use the constraints for doing form validation, as shown in Figure 4-18.

9781430248064_Fig04-18.jpg

Figure 4-18 .  Validation errors

Notice in Figure 4-18 that a validation message is displayed at the top of the page if the form is submitted with an empty name. The blank:false constraint makes the name property required.

Figure 4-19 shows a read-only view.

9781430248064_Fig04-19.jpg

Figure 4-19 .  Show Todo page

The Show Todo page displays all the properties and values. It also provides access to the Edit Todo page, as shown in Figure 4-20, where you can delete the domain object.

9781430248064_Fig04-20.jpg

Figure 4-20 .  Edit Todo page

The Edit Todo page, shown in Figure 4-20, is really the same as the Create Todo page, except the data is repopulated with the domain object values, and it has Update and Delete buttons at the bottom of the page.

Static Scaffolding

Dynamic scaffolding is particularly useful in testing the domain class and developing the prototype, but you may want to customize the logic and views. You can use static scaffolding for this purpose. Static scaffolding can also serve as a great learning tool, for instance, to understand the mechanics of a CRUD application. To generate the controller for the domain class Todo using static scaffolding, use the following command:

> grails generate-controller  collab.todo.Todo

With this command, Grails generates the TodoController class inside grails-app/controllers. The generate-controller command is different from the create-controller command introduced earlier, in that the create-controller command creates an empty controller with a default action index(), while the generate-controller command creates the controller with all the code for the CRUD operation. Similarly, to generate views, use the following command:

> grails generate-views  collab.todo.Todo

With this command, Grails generates .gsp files inside grails-app/views/todo.

Grails also provides the possibility to generate both controllers and views in one command, like so:

> grails generate-all  collab.todo.Todo

One important thing to keep in mind when using static scaffolding: because all the controller code and views code are generated for the domain class, Grails will not update this code if the domain class is changed, and will relinquish this responsibility to the developer.

Finishing the Remaining Domains

Now that you’ve created the Todo domain and controller classes, you can repeat the steps for creating the domain classes and controller classes for the remaining domain and controllers: Category and User. Then you can add the relationships between the domain classes.

As illustrated in the UML diagram in Figure 4-5, the Category class is very simple. Listing 4-8 shows the code after generating the class using the Grails create-domain-class target and adding the properties from the UML diagram.

Listing 4-8.  Category Domain Class

package collab.todo
class Category {
  String name
  String description

  static constraints = {
    name(blank:false)
  }

  String toString() {
    name
  }
}

In Listing 4-8, you see the Category class has just name and description properties and an overloaded toString() method that returns the name property. This overloaded toString() method becomes important later, because it is used to populate an HTML select field. Without it, the select field would only display the category’s id, making it difficult to differentiate categories in the list. The Category class also includes a constraint, which requires the name property.

The User domain class follows the same pattern as both the Todo and Category classes. Listing 4-9 shows the code after generating the class with the Grails create-domain-class target and adding the properties from the UML diagram.

Listing 4-9.  User Domain Class

package collab.todo
class User {
  String userName
  String firstName
  String lastName

  static constraints = {
    userName(blank:false,unique:true)
    firstName(blank:false)
    lastName(blank:false)
  }

  String  toString () {
"$lastName, $firstName"
  }
}

In Listing 4-9, the User class contains userName, firstName, and lastName properties. It also contains constraints that make all properties required and it forces the userName property to be unique in the database. Finally, the overridden toString()method returns the user’s name in a last-name-first format.

Finishing the Remaining Controllers

The controller classes are carbon copies of TodoController. Listing 4-10 shows CategoryController after it was created with the Grails create-controller target and the scaffolding variable set.

Listing 4-10.  CategoryController

package collab.todo
class CategoryController {

  static scaffold = Category
}

Listing 4-11 shows UserController.

Listing 4-11.  UserController

package collab.todo
class UserController {

  static scaffold = User
}

After completing the Category and User domain and controller classes, the application start page displays all three controllers. In addition, CRUD pages for both Category and User are available when clicking on the respective controller links. Grails also provides the means to do statistics. At the command prompt, type grails stats, and you should see output similar to the following:

D:devlworkspacecollab-todo>grails stats
+−−--------------------+−−-----+−−-----+
 | Name                 | Files |  LOC  |
 +−−--------------------+−−-----+−−-----+
 | Controllers          |     3 |    12 |
 | Domain Classes       |     3 |    54 |
 | Unit Tests           |     6 |    60 |
 +−−--------------------+−−-----+−−-----+
 | Totals               |    12 |   126 |
 +−−--------------------+−−-----+−−-----+

Creating Domain Relationships

At this point, you have three standalone domain classes—Todo, Category, and User—with no relationships between them. But remember that the UML diagram in Figure 4-5 showed that users had user-defined categories as well as todos that were organized by categories. Now it’s time to represent those one­to-many relationships between the domain classes using the belongsTo and hasMany properties.

Listing 4-12 shows the new Todo class, which shows the relationships with User and Category.

Listing 4-12.  Todo Domain Class with Relationships to the User and Category Domain Classes

class Todo {
  String name
  String note
  Date createdDate
  Date dueDate
  Date completedDate
  String priority
  String status
  User owner
  Category category

  static belongsTo = [User, Category]

  static constraints = {
    name(blank:false)
    createdDate()
    priority()
    status()
    note(maxSize:1000, nullable:true)
    completedDate(nullable:true)
    dueDate(nullable:true)
  }

  String toString() {
    name
  }

}

Notice in Listing 4-12 that the relationship is defined with the belongsTo property to the User and Category classes. We’ve also added new owner and category properties. belongsTo tells GORM to delete the todo if either the associated user or the category is deleted. Scaffolding renders these relationships as the select fields on the Create Todo and Edit Todo screens, as shown in Figure 4-21.

9781430248064_Fig04-21.jpg

Figure 4-21 .  Create Todo edit page with Category and Owner select fields

Like the Todo class, the Category class has a belongsTo relationship with User, but it also has a collection of Todos, as shown in Listing 4-13.

Listing 4-13.  Category Domain Class with Relationships to the User and Todo Domain Classes

class Category {
  String name
  String description
  User user
  static belongsTo = User
  static hasMany = [todos: Todo]

  static constraints = {
    name(blank:false)
  }

  String toString() {
    name
  }

}

Notice that in addition to belongsTo associated with User, Category contains a hasMany property, which is a map designating a one-to-many relationship with the Todo class. Also, the collection is available via the todos property.

Finally, the User class in Listing 4-14 has now defined its relationships with Todo and Category.

Listing 4-14.  User Domain Class with Relationships to the Todo and Category Domain Classes

class User {
  String userName
  String firstName
  String lastName

  static hasMany = [todos: Todo, categories: Category]

  static constraints = {
    userName(blank:false,unique:true)
    firstName(blank:false)
    lastName(blank:false)
  }

  String  toString () {
    "$lastName, $firstName"
  }

}

As shown in Listing 4-14, the changes required to include the relationships with the Todo and Category classes only take a single line. The hasMany property identifies collections named todos and categories.

image Note  We’ll discuss relationships in more detail in Chapter 6.

As stated earlier, when you run the application, Hibernate creates a database schema based on domain classes. Figure 4-22 shows an entity relational diagram of the domain classes so far.

9781430248064_Fig04-22.jpg

Figure 4-22 .  Entity relational diagram

Notice that the entity relational diagram looks almost identical to the UML diagram shown in Figure 4-5. Hibernate creates three tables with table names based on the class names. It also creates fields for each of the properties using underscores instead of CamelCase. Also, notice the id and version columns are the Hibernate columns for object identity and optimistic locking. Hibernate also creates foreign keys to represent the relationships between the domain classes.

During development, out-of-the-box Grail uses a Tomcat web container and an embedded H2 database. However, many operational environments use other web containers or applications servers and use server-based databases. In Chapter 12, we will look at how to package and deploy an application to an alternative operating environment.

H2 Console

As discussed earlier, Grails 2.0 enables the H2 database console in development mode (at the URI /dbconsole) so that the in-memory database can be easily queried from the browser. To see the dbconsole in action, browse to http://localhost:8080/collab-todo/dbconsole . The default log in parameters should match the default in grails-app/ conf/Datasource.groovy, as illustrated in Figure 4-23.

9781430248064_Fig04-23.jpg

Figure 4-23 .  H2 console

Now, create a user, category, and todo task in our Collab-Todo application and then enter SELECT * from USER in the database console. The user we created in the application will show up, as illustrated in Figure 4-24.

9781430248064_Fig04-24.jpg

Figure 4-24 .  Querying the table in H2

Grails Plugins

In Grails, there is the likelihood that a plugin already exists that does what you need, so you may want to find out which plugins are already available. To see a list of available plugins, call the list-plugins command target:

> grails list-plugins

This command establishes a network connection to a remote server. Invoking the list-plugins target displays a table of all plugins, along with the following output:

.....
To find more info about plugin type 'grails plugin-info [NAME]'
To install type 'grails install-plugin [NAME] [VERSION]'
For further info visit http://grails.org/Plugins

You may want to know more about a particular plugin without installing it. This can be accomplished by calling the plugin-info command target with the plugin’s name as a parameter.

D:devlworkspacecollab-todo>grails plugin-info quartz

Invoking the command yields the output as shown:

| Downloading: quartz-1.0-RC2.pom
--------------------------------------------------------------------------
Information about Grails plugin
--------------------------------------------------------------------------
Name: quartz    | Latest release: 1.0-RC2
--------------------------------------------------------------------------
Quartz plugin for Grails
--------------------------------------------------------------------------
Author: Sergey Nebolsin, Graeme Rocher
--------------------------------------------------------------------------
Author's e-mail: [email protected]
--------------------------------------------------------------------------
Find more info here: http://grails.org/plugin/quartz
--------------------------------------------------------------------------
This plugin adds Quartz job scheduling features to Grails application.
Dependency Definition
--------------------------------------------------------------------------
    :quartz:1.0-RC2
Required Repositories
--------------------------------------------------------------------------
     http://plugins.grails.org
     http://repo.grails.org/grails/plugins/
     http://repo.grails.org/grails/core/
     http://svn.codehaus.org/grails/trunk/grails-plugins
     http://repo1.maven.org/maven2/
Transitive Dependencies
--------------------------------------------------------------------------
     org.hibernate:hibernate-core:3.6.10.Final (compile)
     org.quartz-scheduler:quartz:1.8.4 (compile)
To get info about specific release of plugin 'grails plugin-info [NAME] [VERSION]'
To get list of all plugins type 'grails list-plugins'
To install latest version of plugin type 'grails install-plugin [NAME]'
To install specific version of plugin type 'grails install-plugin [NAME] [VERSION]'
For further info visit http://grails.org/Plugins

Installing a plugin from the command line is just as easy. For example, to install quartz, type the following on the command line:

> grails install-plugin quartz

To remove a plugin, call the uninstall-plugin command target. To uninstall the

quartz plugin:

> grails uninstall-plugin quartz

To install a plugin in GGTS, right-click on plugins under the project hierarchy and then open the Grails Plugin Manager, which is shown in Figure 4-25.

9781430248064_Fig04-25.jpg

Figure 4-25 .  Grails plugin manager

Grails Interactive Mode

Until this point, all of the Grails commands that we have seen have been executed by running grails and passing a command name as an argument. With Grails interactive mode, there is no need to prefix every command with grails. For example, you might type something like the following on the command line:

grails create-domain-class collab.todo.Task

However, in interactive mode, you can type the shorter:

create-domain-class collab.todo.Task

To start interactive mode, enter the "grails" command with no arguments, as shown in Figure 4-26.

9781430248064_Fig04-26.jpg

Figure 4-26 .  Grails interactive mode

9781430248064_Fig04-27.jpg

Figure 4-27 .  Shorter commands in interactive mode

In interactive mode, type “crea” followed by pressing Tab. Interactive mode returns a list of all available commands that start with “crea”, as shown in Figure 4-28.

9781430248064_Fig04-28.jpg

Figure 4-28 .  Tab-completion for “crea” and “ru” in interactive mode

To exit interactive mode, type “exit” at the interactive mode prompt. Interactive mode keeps the JVM running and allows for quicker execution of commands, thereby increasing developer productivity.

Summary

In this chapter, you learned that Grails is a new web development framework that combines the best of Java open source, conventions, the Groovy dynamic language, and the power of the Java platform.

You also saw how easy it is to develop a fully functional application using Grails scaffolding to do most of the work. In Chapter 5, you will learn how to make the application pretty and customize its look and feel, as well as how to make the controllers more functional. Then in Chapter 6, you will learn how to enhance the domain classes, including accessing more of the persistence features of GORM.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset