2007 09 10 fzi training groovy grails v ws

57
1 R. Volz - Groovy & Grails Groovy & Grails Lightning Talk Raphael Volz Sep. 10, 2007 FZI, Karlsruhe Builds on content from the following presentations Rod Cope and James Strachan The Groovy Programming Language Presentation held at JavaOne 2004 Graeme Rocher Rapid Web Application Development with Grails Presentation held at JavaOne 2006

Upload: loffenauer

Post on 09-May-2015

5.415 views

Category:

Technology


0 download

DESCRIPTION

2-3 hour introduction to GROOVY and GRAILS given on Sep 10, 2007 for an internal tech talk at the FZI, Germany

TRANSCRIPT

Page 1: 2007 09 10 Fzi Training Groovy Grails V Ws

1 R. Volz - Groovy & Grails

Groovy & Grails Lightning Talk

Raphael Volz

Sep. 10, 2007

FZI, Karlsruhe

Builds on content from the following presentations

Rod Cope and James StrachanThe Groovy Programming LanguagePresentation held at JavaOne 2004

Graeme RocherRapid Web Application Development with GrailsPresentation held at JavaOne 2006

Page 2: 2007 09 10 Fzi Training Groovy Grails V Ws

2 R. Volz - Groovy & Grails

Agenda

Why should I care ?

Get Groovy

Find Grails

Page 3: 2007 09 10 Fzi Training Groovy Grails V Ws

3 R. Volz - Groovy & Grails

Why should I care ?

40-60%User Interface

40-60%Functionality

Software Development Effort

Variance Max. 20 %User Interface

Min. 80%Functionality

Focus :Users Great Interface

Developer Gigantic Functionality

Typically Research

… try to be efficientin programming efforts …

... try to be efficientin UI efforts...

Page 4: 2007 09 10 Fzi Training Groovy Grails V Ws

4 R. Volz - Groovy & Grails

Efficiency Problems in Web Development

Many repetitive tasks Consider example data flow:

Database – Object Representation – Presentation HTML

Different structure of individual applications Hard to understand Hard to maintain

Difficulty to get started Many concepts at once:

HTML, XML, SQL, JavaScript, Programming Languages …

Need: Simplification Standardization Capture “Best Practices”

Page 5: 2007 09 10 Fzi Training Groovy Grails V Ws

5 R. Volz - Groovy & Grails

Java’s biggest strengths in Web development ?

VM and Binary Compatibility We can build deployment units (class, jar, jnlp, war, ear, rar, car) and

run them anywhere We can easily reuse libraries, APIs and tools

e.g. high quality BPM, SemWeb, Market APIs

Lots of reusable software & components & tools We can innovate at the source code level if we play nice at

the binary level

Page 6: 2007 09 10 Fzi Training Groovy Grails V Ws

6 R. Volz - Groovy & Grails

Problems with Java in Web Dev’t

Verbose Many import statements Try… Catch Nightmare …

Static Compile Cycle prevents necessary agility

Language Concepts (in my opinion) slow to embrace “modern” concepts … … many of which are helpful for Web Development

Page 7: 2007 09 10 Fzi Training Groovy Grails V Ws

7 R. Volz - Groovy & Grails

Agenda

Why should I care ?

Get Groovy

Find Grails

Page 8: 2007 09 10 Fzi Training Groovy Grails V Ws

8 R. Volz - Groovy & Grails

Get Groovy – An agile dynamic language for Java

Integrates with Java Can call Java Can be called by Java Compiles to Java byte code

Simplifies syntax of java Adds modern language features from

Python, Ruby, Dylan and Smalltalk to Java Supports DSL (domain specific languages)

to compact syntax and increase readability Reduces scaffolding code (Web, GUI, database) Simplifies testing (mocks up out-of-the-box)

Page 9: 2007 09 10 Fzi Training Groovy Grails V Ws

9 R. Volz - Groovy & Grails

Groovy // Simplifying Java Syntax (1)

Feature Java Groovy

Semicolon after statement

MUST OPTIONAL

Brackets with method calls

MUST OPTIONAL

Typing of variables MUST OPTIONAL

Default scope PRIVATE PUBLIC

Imports Declare all imports Automatically imports groovy.lang.* groovy.util.* java.lang.* java.util.* java.net.* java.io.* java.math.BigInteger java.math.BigDecimal

Page 10: 2007 09 10 Fzi Training Groovy Grails V Ws

10 R. Volz - Groovy & Grails

Groovy // New features beyond Java

Everything is an object Groovy Beans

Automatically generates get/set methods Uses these methods when attributes are read

Simple Notation of lists and (hash) maps Closures - Objects with executable code Operator overloading Extended Switch

Page 11: 2007 09 10 Fzi Training Groovy Grails V Ws

11 R. Volz - Groovy & Grails

Println “Hello World”

Groovy // Hello World

Java

public class HelloWorld {

public static void main (String[] args) {

System.out.println( “Hello World”);

}

}

Groovy

println “Hello World”

Simplifications applied1. Public optional

2. Type information optional

3. Every Class knows “println”

4. Script needs no class and main method context

5. Semicolon optional

6. Brackets are optional when calling methods

class HelloWorld {static void

main (String[] args) { System.out.println( “Hello World”);}

}

class HelloWorld {static main (args) { System.out.println( “Hello World”);}

}

class HelloWorld { static main (args) {

println(“Hello World”); }}

println(“Hello World”); Println “Hello World”

Page 12: 2007 09 10 Fzi Training Groovy Grails V Ws

12 R. Volz - Groovy & Grails

Groovy // Closures : Blocks of code as objects

def c = { println "hello" }c()

square = { x -> x * x }assert square(2) == 4

square = { it * it }

3.times { println "hoch!" }

def sum = 01.upto(5) { sum += it }assert sum == 15

Use to substitute repeated code blocks

Closure with parameter

Closure with default parameter "it" does not require return

Times function

upto function

Remember LISP ?

... pass around as references, store, execute at arbitratry time

... similar to anonymous inner classes, but nicer syntax and more flexible

Page 13: 2007 09 10 Fzi Training Groovy Grails V Ws

13 R. Volz - Groovy & Grails

Groovy // Calling Java APIS

10 liner to get "Google Patent Search" results via HTMLUnit

1 import com.gargoylesoftware.htmlunit.WebClient

2 def searchTerm = 'Robot'

// Patent Search with Google

3 def client = new WebClient()

4 def page = client.getPage('http://www.google.com/patents')

5 def input = page.forms[0].getInputByName('q')

6 input.valueAttribute = searchTerm

7 page = page.forms[0].submit()

8 def results = page.anchors.grep { it.classAttribute == 'big' }

9 results.each {

10 println it.hrefAttribute.padRight(30) + ' : ' + it.asText() }

Closure

Page 14: 2007 09 10 Fzi Training Groovy Grails V Ws

14 R. Volz - Groovy & Grails

Groovy // Everything is an object

def i = 1

assert i == new Integer (1)

def k = iassert i.is(k)assert !(i.is(new Integer(i)))

No primitive datatypes Int, short byte, long real objects

== is equals() Checks equality of objects

is() checks identity of objects

Very, very usefulwhen writing test code !!!

Page 15: 2007 09 10 Fzi Training Groovy Grails V Ws

16 R. Volz - Groovy & Grails

Groovy // Simplified List Handling

def list = [1,2,3]assert list[0] == 1assert list[-1] == 3assert list[1..2] == [2,3]

assert list + [4,5] == [1,2,3,4,5]assert list << 9 == [1,2,3,9]

assert [1,2,3] - [2] == [1,3]assert [1,2] * 2 == [1,2,1,2]

def sum = 0for (i in list) sum+= iasset sum == 6

Simplified addressing of list elements avoids calls to len()

Simplied modification of lists

Simplified iteration

Page 16: 2007 09 10 Fzi Training Groovy Grails V Ws

17 R. Volz - Groovy & Grails

Groovy // List Handling Example

public class Filter { public static void main( String[] args ) { List list = new java.util.ArrayList(); list.add( "Rod" ); list.add( "James" ); list.add( "Chris" ); Filter filter = new Filter(); List shorts = filter.filterLongerThan( list, 4 ) for ( String item : shorts ) { System.out.println( item ); } } public List filterLongerThan( List list, int length ) { List result = new ArrayList(); for ( String item : list ) { if ( item.length() <= length ) { result.add( item ); } } return result; }}

Select all names with at most 3 characters from a list

Groovy

Java

list = ["Rod", "James", "Chris"]shorts = list.findAll { it.size() <= 4 }shorts.each { println it }

Page 17: 2007 09 10 Fzi Training Groovy Grails V Ws

18 R. Volz - Groovy & Grails

Groovy // Ranges and Maps

def sum = 0for (i in 1..10) sum += iassert sum ==55

map = ['rod' : 33, 'james' : 35]assert map['rod'] == map.rod

map.joe = 28 assert map == ['rod':33, 'james':35, 'joe':28]

assert map.subMap(['rod', 'joe']) == ['rod':33, 'joe':28]

Page 18: 2007 09 10 Fzi Training Groovy Grails V Ws

19 R. Volz - Groovy & Grails

Basic Sorting

list = [ 'dog', 'bird', 'chick' ] println( list.sort() )

-> [bird, chick, dog] println( list.sort { it.size() }.reverse() )

-> [chick, bird, dog]

Page 19: 2007 09 10 Fzi Training Groovy Grails V Ws

20 R. Volz - Groovy & Grails

Sorting JavaBeans

class Person { name; age }list = [ new Person( name:'Rod', age:33 ),

new Person( name:'James', age:35 ) ]list.sort { | person | person.age }list.sort { [ it.name, it.age ] }list.sort { | a, b | a.name <=> b.name }println( list.sort{it.name}.name )

-> [James, Rod]println(list.sort{it.name}.name.join(':'))

-> "James:Rod"

Page 20: 2007 09 10 Fzi Training Groovy Grails V Ws

21 R. Volz - Groovy & Grails

Groovy // Operator Overloading

Maps Operators to Methods Can be implemented by any class and subsequently used Operator Name Method

a+b plus a.plus(b)a-b minus a.minus(b)a*b star a.multiply(b)a/b divide a.div(b)a % b modulo a.mod(b)a++ increment a.next()a-- decrement a.previous()a**b power a.power(b)

Page 21: 2007 09 10 Fzi Training Groovy Grails V Ws

22 R. Volz - Groovy & Grails

Groovy // Advanced switch

switch (v) { case 1: println 'Number one'; break;

case 'test': println 'String test'; break;

case 2..15 : println 'in range 2 to 15'; break;

case [1, '1', 'One'] : println 'Number one'; break;

case ~/A.*/: println 'Starts with A'; break;

default: println 'Default Output'; break}

Page 22: 2007 09 10 Fzi Training Groovy Grails V Ws

23 R. Volz - Groovy & Grails

Groovy // Additional Library

Adds methods missing from the JDK String

contains(), count(), execute(), padLeft(), center(), padRight(), reverse(), tokenize(), each(), etc.

Collection count(), collect(), join(), each(), reverseEach(), find/All(), min(),

max(), inject(), sort(), etc.

File eachFile(), eachLine(), withPrintWriter(), write(), getText(), etc.

Page 23: 2007 09 10 Fzi Training Groovy Grails V Ws

24 R. Volz - Groovy & Grails

Groovy // Strings and Regular Expressions

def cal = new GregorianCalendar()println "Date: $cal.time"

assert 'only letters' ==~ /((\w*) *)*/

assert 'only letters' =~ /\w*/

def matcher = 'only letters' =~ /\w*/mather.each { println it }

Usage of variables in strings

Matches whole words

Matches all words

Print all words

Page 24: 2007 09 10 Fzi Training Groovy Grails V Ws

25 R. Volz - Groovy & Grails

Groovy // GPath path expressions

class Person { name; age }

list = [ new Person( name:'Rod', age:33 ),

new Person( name:'James', age:35 ) ]

println( list.find {it.age > 25}.name )

-> [Rod]

println( list.findAll {it.age > 25}.name )

-> [Rod, James]

println( list.any{ it.name.size() > 4 } )

-> true

Page 25: 2007 09 10 Fzi Training Groovy Grails V Ws

26 R. Volz - Groovy & Grails

Groovy // Builders

Implemenation of Builder Design Pattern Used to construct other things

Groovy provides builders for Groovy objects NodeBuilder XML,HTML groovy.xml.MarkupBuilder Swing SwingBuilder Ant AntBuilder

Can add own Builders (very powerful) Who writes one for RDF ? Who writes one for OWL ? Who writes one for BPEL ?

Page 26: 2007 09 10 Fzi Training Groovy Grails V Ws

27 R. Volz - Groovy & Grails

Groovy // XML Builder

Groovy

data = ['Rod': ['Misha':8, 'Bowie':2], 'Eric': ['Poe':4, 'Doc':3] ]

xml = new groovy.xml.MarkupBuilder()

people = xml.people() {

for ( entry in data ) { person( name: entry.key ) { for ( dog in entry.value) { pet( name:dog.key, age:dog.value ) } }

}

}

XML

<people>

<person name='Rod'>

<pet name='Bowie' age='2' />

<pet name='Misha' age='8' />

</person>

<person name='Eric'>

<pet name='Poe' age='4' />

<pet name='Doc' age='3' />

</person>

</people>

Page 27: 2007 09 10 Fzi Training Groovy Grails V Ws

28 R. Volz - Groovy & Grails

Groovy // XML Parser

XML

<people>

<person name='Rod'>

<pet name='Bowie' age='2' />

<pet name='Misha' age='8' />

</person>

<person name='Eric'>

<pet name='Poe' age='4' />

<pet name='Doc' age='3' />

</person>

</people>

Groovy

def persons = new XmlParser().parseText(text);

assert people.person.pet.name ==['Bowie', 'Misha', 'Poe', 'Doc']

Page 28: 2007 09 10 Fzi Training Groovy Grails V Ws

29 R. Volz - Groovy & Grails

Groovy // Dynamic Features

Meta Object protocol Intercept method calls Control access to properties Control access to classes

Expando Objectdef e = new Expando ()e.a = Math.PIe.m = { println 'I am an expando, this is new method m' }e.m()

Duck Typingclass Fish { def swim() { println 'I am a fish' } }class Dolphin {def swim() { println 'I am a dolphin' } }[new Fish(), new Dolphin()].each { it.swim() }

Page 29: 2007 09 10 Fzi Training Groovy Grails V Ws

30 R. Volz - Groovy & Grails

Groovy // Summary

Groovy Dynamic, flexible Components Focus Adaptivity, Prototyping

Java Static, stable Components Critical for runtime More efficient compiler

Typically 50% less development effort (*)

Note: (*) Comes at higher debugging expense and 20-90% performance

Page 30: 2007 09 10 Fzi Training Groovy Grails V Ws

31 R. Volz - Groovy & Grails

Agenda

Why should I care ?

Get Groovy

Find Grails

Page 31: 2007 09 10 Fzi Training Groovy Grails V Ws

32 R. Volz - Groovy & Grails

What is GRAILS ?

Grails is an MVC Web framework Initially inspired by Ruby on Rails

Built upon solid bricks & best of breed components Spring: IoC, DI, Spring MVC, transactional support, experimental

Spring WebFlow… Hibernate: ORM, querying mechanism… Groovy: for focusing on everything that matters And: SiteMesh, Quarz, AJAX frameworks…

« Convention over configuration »: Focus not on wiring and configuration!

Page 32: 2007 09 10 Fzi Training Groovy Grails V Ws

33 R. Volz - Groovy & Grails

GRAILS // Layering on Java Components

Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006, p. 7

Page 33: 2007 09 10 Fzi Training Groovy Grails V Ws

34 R. Volz - Groovy & Grails

GRAILS // Step 1

Page 34: 2007 09 10 Fzi Training Groovy Grails V Ws

35 R. Volz - Groovy & Grails

Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006, p. 39

Page 35: 2007 09 10 Fzi Training Groovy Grails V Ws

36 R. Volz - Groovy & Grails

GRAILS // Basic application already there after Step 1

Page 36: 2007 09 10 Fzi Training Groovy Grails V Ws

37 R. Volz - Groovy & Grails

GRAILS // Step 2 - Define a Model

• Now that the skeleton is there, focus on the model• Model backed by GORM• The model is just a set POGOs (Plain Old Groovy Objects)

• First class of our domain: the books

class Book {String title

String authorString publisher

}

Page 37: 2007 09 10 Fzi Training Groovy Grails V Ws

38 R. Volz - Groovy & Grails

GRAILS // GRAILS Contribution

• Automatically, Grails add dynamic instance & static methods to all your domain classes:

Static methods: Instance methods:

• Book.get(1) • Book.save()• Book.find() • book.validate()• Book.findAll() • book.update()

• bok.delete()

Page 38: 2007 09 10 Fzi Training Groovy Grails V Ws

39 R. Volz - Groovy & Grails

GRAILS // Step 3 Generation of views and controllers

• Once the Book class is created, let´s benefint from static scaffolding

→ grails generate-all→ grails run-app

• A BookController is created, as well as four GSP:

▪ create.gsp ▪ edit.gsp ▪ list.gsp ▪ show.gsp

Page 39: 2007 09 10 Fzi Training Groovy Grails V Ws

40 R. Volz - Groovy & Grails

GRAILS // Scaffolding provides basic GUI for CRUD

Page 40: 2007 09 10 Fzi Training Groovy Grails V Ws

41 R. Volz - Groovy & Grails

GRAILS // Taking control of GRAILS

View

Model Controller

grails generate-controller/grails-app/controllers

grails generate-views/grails-app/views

grails create-domain-class/grails-app/model

Jobs Services

/grails-app/jobs /grails-app/services

grails create-app1

2

grails generate-all

3

Web

Tes

tU

nit

Tes

t

4

56

Page 41: 2007 09 10 Fzi Training Groovy Grails V Ws

42 R. Volz - Groovy & Grails

GRAILS // VIEW CONTROLLER INTERACTION

Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006

Page 42: 2007 09 10 Fzi Training Groovy Grails V Ws

43 R. Volz - Groovy & Grails

GRAILS // Hibernate interaction

• Hibernate is the de facto ORM solution• Domain classes are automatically and transparently mapped with Hibernate

• 1:1, 1:n & m:n realtionships supported

• Various database environments (dev, test, prod)• Default HSQLDB in-memory config

• You can even provide your own Hibernate mapping files for legacy schemas• You can also reuse your EJB3!

VM C S J

Page 43: 2007 09 10 Fzi Training Groovy Grails V Ws

44 R. Volz - Groovy & Grails

GRAILS // A more complex domain

class Author { String firstName String lastName

def hasMany = [books: Book] String toString() { “$firstName $lastName” }}

class Book { String title Author author Publisher publisher

def belongsTo = [Publisher,Author]

String toString() { title }}

class Publisher { String name

def hasMany = [ books: Book]

String toString() { name }}

Author has many Books

Publisher has many Books

VM C S J

Page 44: 2007 09 10 Fzi Training Groovy Grails V Ws

45 R. Volz - Groovy & Grails

GRAILS // Domain with constraints to keep valid

Add an email to Author

class Author { String email // … static constraints = {

email (email: true) }}

Add an ISBN to Book

class Book { Stringisbn // … static constraints = {

isbn (matches:“ [0-9] {9} [0-9X ]”)}

}

VM C S J

Page 45: 2007 09 10 Fzi Training Groovy Grails V Ws

46 R. Volz - Groovy & Grails

GRAILS // ... and even more constraints

• Many constraints available:

blank, creditcard, email, inList, length, min, minLength, minSize, matches, max, maxLength, maxSize, notEqual, nullable, range, size, unique, url, validator

• And you can create your own closure validator:

even( validator: { it % 2 == 0 )}

VM C S J

Page 46: 2007 09 10 Fzi Training Groovy Grails V Ws

47 R. Volz - Groovy & Grails

GRAILS // Querying your Model

Grails provides various querying mechanisms:

Dynamic finder methods Query by example Criteria builders Full-blown HQL queries

VM C S J

Page 47: 2007 09 10 Fzi Training Groovy Grails V Ws

48 R. Volz - Groovy & Grails

GRAILS // Query Examples

• Book.findByTitle (“The Stand”)

Book.findByTitleLike(“Harry Pot%”) Book.findByReleaseDataBetween(start, end) Book.findByTitleLikeOrReleaseDataLessThan(

“%Grails%”, someData)

• Find by relationship Book.findAllByAuthor( Author.get(1) )

• Affect sorting Book.findAllbyAuthor(me,[sort:‘title’,order:’asc’])

VM C S J

Page 48: 2007 09 10 Fzi Training Groovy Grails V Ws

49 R. Volz - Groovy & Grails

GRAILS // Views

• Spring MVC under the hood• Support for flash scope between requests• GSP: Groovy alternative to JSP• Dynamic taglib development: no TLD, no configuration, just conventions• Adaptive AJAX tags (Yahoo, Dojo, Prototype)• Customizable layout with SiteMesh• Page fragments through reusable templates• View under grails-app/views

VM C S J

TIP: Use grails install-templates to install and customize your the templates to be used

for generation (templates in ../src/templates)

Page 49: 2007 09 10 Fzi Training Groovy Grails V Ws

50 R. Volz - Groovy & Grails

GRAILS // GSP Groovy Server Pages

<html> <head>

<meta name=“layout“ content=“main“ /> <title>Book List</title>

</head> <body> <a href=“${createLinkTo(dir:’’)}”>Home</a>

<g:link action=“create”>New Book</g:link> <g:if test=“${flash.message}”>

${flash.message} </g:if> <g:each in=“${bookList}”>${it.title}</g:each>

</body></html>

VM C S J

Page 50: 2007 09 10 Fzi Training Groovy Grails V Ws

51 R. Volz - Groovy & Grails

GRAILS // Rich Set of Dynamic Tag Libs

• Logical: if, else, elseif• Iterative: while, each, collect, findAll…• Linking: link, createLink, createLinkTo• Ajax: remoteFunction, remoteLink, formRemote, submitToRemote…• Form: form, select, currencySelect, localSelect, datePicker, checkBox…• Rendering: render*, layout*, paginate…• Validation: eachError, hasError, message• UI: rich TextEditor…

VM C S J

Page 51: 2007 09 10 Fzi Training Groovy Grails V Ws

52 R. Volz - Groovy & Grails

GRAILS // URL Convention

• URL mapping convention: controller/action/id http://localhost:8080/library/book/show/1 • Scaffolding can be ▪ dynamic (def scaffold = true) ▪ static (code generation)• Controllers pass data to the view through maps• Direct access to parameters• Easy redirect and forward• Can define allowed methods for each action

VM C S J

Page 52: 2007 09 10 Fzi Training Groovy Grails V Ws

53 R. Volz - Groovy & Grails

GRAILS // Controllers provide actions to execute (call)

class BookController { def index = { redirect(action:list,params:params) } def list = { [ bookList: Book.list( params )] }

def show = { [ book : Book.get( params.id ) ] }

def edit = { def book = Book.get( params.id ) if(!book) { flash.message = “Book ${params.id} not found” redirect(action:list) } else return [ book : book ] }}

VM C S J

Page 53: 2007 09 10 Fzi Training Groovy Grails V Ws

54 R. Volz - Groovy & Grails

GRAILS // Chaining and Flashing

Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006

Page 54: 2007 09 10 Fzi Training Groovy Grails V Ws

55 R. Volz - Groovy & Grails

GRAILS // Services

• Services are Groovy classes that should contain your business logic

• Automatic injection of services in controllers & services simply by declaring a field:

class BookController { MySuperService mySuperService }

VM C S J

Page 55: 2007 09 10 Fzi Training Groovy Grails V Ws

56 R. Volz - Groovy & Grails

Grails // Jobs

• You can create recuring events with Quartz under the hood, configured by Spring• Again a convention on the name and directory• Regular intervals, or cron definitions

• class MyJob {} def cronExpression = “0 0 24 * * ?” def execute() {

print “Job run!” } }

VM C S J

Page 56: 2007 09 10 Fzi Training Groovy Grails V Ws

57 R. Volz - Groovy & Grails

Further Reading

Page 57: 2007 09 10 Fzi Training Groovy Grails V Ws

58 R. Volz - Groovy & Grails

Concluding Notes

Slides (largely) inspired by the following two presentations Rod Cope and James Strachan

The Groovy Programming LanguagePresentation held at JavaOne 2004

Graeme RocherRapid Web Application Development with GrailsPresentation held at JavaOne 2006

Get started with... GRAILS: grails.codehaus.org GROOVY: groovy.codehaus.org