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
Agenda
Why should I care ?
Get Groovy
Find 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 efficient in programming efforts … ... try to be efficient in UI efforts...
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”
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
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
Agenda
Why should I care ?
Get Groovy
Find 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)
Groovy // Simplifying Java Syntax (1)
Automatically imports
groovy.lang.*
groovy.util.*
java.lang.*
java.util.*
java.net.*
java.io.*
java.math.BigInteger
java.math.BigDecimal
Declare all imports Imports PUBLIC PRIVATE Default scope OPTIONAL MUST Typing of variables OPTIONAL MUST Brackets with method calls OPTIONAL MUST Semicolon after statement Groovy Java Feature
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
Groovy // Hello World
Java
public class HelloWorld {
public static void main (String[] args) {
System.out.println( “Hello World”);
}
}
Groovy
println “Hello World”
Simplifications applied
Public optional
Type information optional
Every Class knows “println”
Script needs no class and main method context
Semicolon optional
Brackets are optional when calling methods
Println “Hello World” 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”
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 = 0 1.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
Groovy // Calling Java APIS
10 liner to get "Google Patent Search" results via HTMLUnit
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 }
Groovy // Ranges and Maps
def sum = 0 for (i in 1..10) sum += i assert sum ==55
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)
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 }
Groovy // Additional Library
Adds methods missing from the JDK
String
contains(), count(), execute(), padLeft(), center(), padRight(), reverse(), tokenize(), each(), etc.
def e = new Expando () e.a = Math.PI e.m = { println 'I am an expando, this is new method m' } e.m()
Duck Typing
class Fish { def swim() { println 'I am a fish' } } class Dolphin {def swim() { println 'I am a dolphin' } } [new Fish(), new Dolphin()].each { it.swim() }
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
Agenda
Why should I care ?
Get Groovy
Find 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!
GRAILS // Layering on Java Components Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006, p. 7
GRAILS // Step 1
Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006, p. 39
GRAILS // Basic application already there after Step 1
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 POGO s
(Plain Old Groovy Objects)
• First class of our domain: the books
class Book {
String title
String author
String publisher
}
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()
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
GRAILS // Scaffolding provides basic GUI for CRUD
GRAILS // Taking control of GRAILS V iew M odel C ontroller grails generate-controller /grails-app/controllers grails generate-views /grails-app/views grails create-domain-class /grails-app/model J obs S ervices /grails-app/jobs /grails-app/services grails create-app 1 2 Web Test Unit Test 4 5 6 grails generate-all 3
GRAILS // VIEW CONTROLLER INTERACTION Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006
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 ! V M C S J
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 V M C S J
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 ]”) } } V M C S J
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 )} V M C S J
GRAILS // Querying your Model
Grails provides various querying mechanisms:
Dynamic finder methods
Query by example
Criteria builders
Full-blown HQL queries
V M C S J
GRAILS // Query Examples • Book. find By Title (“The Stand”) Book.findByTitle Like (“Harry Pot%”) Book.findByReleaseData Between (start, end) Book.findByTitleLike Or ReleaseData LessThan ( “ %Grails%”, someData) • Find by relationship Book.find All By Author ( Author.get(1) ) • Affect sorting Book.findAllbyAuthor(me, [sort:‘title’,order:’asc’] ) V M C S J
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 V M C S J TIP: Use grails install-templates to install and customize your the templates to be used for generation (templates in ../src/templates)
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> V M C S J
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… V M C S J
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 V M C S J
GRAILS // Controllers provide actions to execute (call) class Book Controller { 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 ] } } V M C S J
GRAILS // Chaining and Flashing Source: G. K. Rocher, The Definite Guide to Grails, Apress, 2006
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 } V M C S J
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 My Job {} def cronExpression = “0 0 24 * * ?” def execute() { print “Job run!” } } V M C S J
Further Reading
Concluding Notes
Slides (largely) inspired by the following two 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
0 comments
Post a comment