SlideShare une entreprise Scribd logo
1  sur  228
Télécharger pour lire hors ligne
Groovy/Grails DevJam
Act I
“When you program in Groovy, in many ways
 you’re writing a special kind of Java.”


                               -Dierk König
                            Groovy in Action
.groovy
.java
hugobook:groovy mjhugo$ groovyc
usage: groovyc [options] <source-files>
options:
    --encoding <encoding>   Specify the encoding of the user class files.
 -F <flag>
 -J <property=value>
 -d                         Specify where to place generated class files.
 -e,--exception             Print stack trace on error.
 -h,--help                  Print a synopsis of standard options.
 -j,--jointCompilation      Attach javac compiler to compile .java files.
 -v,--version               Print the version.
20%



      80%
getters and setters
1    package com.piragua.java;
2
3    public class SimpleBook {
4        private String title;
5        private String authorName;
6
7        public String getTitle() {
8            return title;
9        }
10
11       public void setTitle(String title) {
12           this.title = title;
13       }
14
15       public String getAuthorName() {
16           return authorName;
17       }
18
19       public void setAuthorName(String authorName) {
20           this.authorName = authorName;
21       }
22   }
1   package com.piragua.groovy
2
3   class SimpleBook {
4       String title
5       String authorName
6   }
javap -private SimpleBook

Compiled from quot;SimpleBook.groovyquot;
public class com.piragua.groovy.SimpleBook ... {

    private java.lang.String title;
    private java.lang.String author;

    public java.lang.String getTitle();
    public void setTitle(java.lang.String);

    public java.lang.String getAuthor();
    public void setAuthor(java.lang.String);

    ...

}
javap -private SimpleBook

Compiled from quot;SimpleBook.groovyquot;
public class com.piragua.groovy.SimpleBook ... {

    private java.lang.String title;
    private java.lang.String author;

    public java.lang.String getTitle();
    public void setTitle(java.lang.String);

    public java.lang.String getAuthor();
    public void setAuthor(java.lang.String);

    ...

}
1    package com.piragua.java;                                                                     1    package com.piragua.groovy
2                                                                                                  2
3    import java.util.Date;                                                                        3    class Book {
4    import java.util.List;                                                                        4        String title
5                                                                                                  5        String authorName
6    public class Book {                                                                           6        Integer numberOfPages
7        private String title;                                                                     7        String subTitle
8        private String authorName;                                                                8        List chapters
9        private Integer numberOfPages;                                                            9        Date publishDate
10       private String subTitle;                                                                  10       String publisher
11       private List<Chapter> chapters;                                                           11
12       private Date publishDate;                                                                 12       String toString() {
13       private String publisher;                                                                 13           title?.toUpperCase()
14                                                                                                 14       }
15       public String getPublisher() {                                                            15
16           return publisher;                                                                     16       String displayString() {
17       }                                                                                         17           quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot;
18                                                                                                 18       }
19       public void setPublisher(String publisher) {                                              19
20           this.publisher = publisher;                                                           20       Chapter findChapterByTitle(String title) {
21       }                                                                                         21           // finding the first item that matches criteria
22                                                                                                 22           chapters?.find({it?.title == title})
23       public Date getPublishDate() {                                                            23       }
24           return publishDate;                                                                   24   }
25       }
26
27       public void setPublishDate(Date publishDate) {
28           this.publishDate = publishDate;
29       }
30
31       public List getChapters() {
32           return chapters;
33       }
34
35       public void setChapters(List chapters) {
36           this.chapters = chapters;
37       }
38
39       public String getTitle() {
40           return title;
41       }
42
43       public void setTitle(String title) {
44           this.title = title;
45       }
46
47       public String getAuthorName() {
48           return authorName;
49       }
50
51       public void setAuthorName(String authorName) {
52           this.authorName = authorName;
53       }
54
55       public Integer getNumberOfPages() {
56           return numberOfPages;
57       }
58
59       public void setNumberOfPages(Integer numberOfPages) {
60           this.numberOfPages = numberOfPages;
61       }
62
63       public String getSubTitle() {
64           return subTitle;
65       }
66
67       public void setSubTitle(String subTitle) {
68           this.subTitle = subTitle;
69       }
70
71       public String toString() {
72           String upperCaseTitle = null;
73           if (title != null) {
74               upperCaseTitle = title.toUpperCase();
75           }
76           return upperCaseTitle;
77       }
78
79       public String displayString() {
80           return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;;
81       }
82
83       public Chapter findChapterByTitle(String chapterTitle) {
84           Chapter foundChapter = null;
85
86           if (chapterTitle != null && chapters != null) {
87               for (int i = 0; i < chapters.size(); i++) {
88                   if (chapters.get(i) != null &&
89                           chapterTitle.equals(chapters.get(i).getTitle())) {
90                       foundChapter = chapters.get(i);
91                       break;
92                   }
93               }
94           }
95           return foundChapter;
96       }
97   }
constructor convenience




http://flickr.com/photos/9229859@N02/1052409181/
1    package com.piragua.java;
2
3    import junit.framework.TestCase;
4
5    import java.util.ArrayList;
6    import java.util.Date;
7
8    public class BookTest extends TestCase {
9        Book book;
10       Chapter chapter;
11
12      public void setUp() {
13          book = new Book();
14          book.setNumberOfPages(300);
15          book.setAuthorName(quot;Mike Hugoquot;);
16          book.setTitle(quot;Groovy Jamquot;);
17          book.setSubTitle(quot;Jamminquot;);
18          book.setPublisher(quot;Piragua Pressquot;);
19          book.setPublishDate(new Date());
20      }
1    package com.piragua.groovy
2
3    public class BookTest extends GroovyTestCase {
4        Book book
5        Chapter grails, groovy, why
6
7       void setUp() {
8         book = new Book(title: quot;Groovy Jamquot;, subTitle:quot;Jamminquot;,
9            authorName: quot;Mike Hugoquot;, numberOfPages: 300,
10           publishDate:new Date(), publisher: quot;Piragua Pressquot;)
11      }
null safe dereferencing




http://flickr.com/photos/synthesisstudios/352834727/
32   public String toString() {
33       String upperCaseTitle = null;
34       if (title != null){
35           upperCaseTitle = title.toUpperCase();
36       }
37       return upperCaseTitle;
38   }
String toString(){
    title?.toUpperCase()
}
// more complex
String toString(){
    book?.publisher?.address?.city?.toUpperCase()
}
groovy strings




http://flickr.com/photos/austinevan/416813459/
// Java Example

public String displayString() {
    return quot;<u>quot; + title + quot;</u> by quot; +
        authorName + quot;, (quot; +
        numberOfPages + quot; pages)quot;;
}
// Java Example

public String displayString() {
    return quot;<u>quot; + title + quot;</u> by quot; +
        authorName + quot;, (quot; +
        numberOfPages + quot; pages)quot;;
}
String displayString() {
    quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot;
}
String multiLineDisplayString() {

quot;quot;quot;<u>${title}</u>
by ${authorName}
(${numberOfPages} pages)quot;quot;quot;

}
collections




http://flickr.com/photos/stibbons/375342559/
11 private List<Chapter> chapters;
//...
55 public Chapter findChapterByTitle(String chapterTitle) {
56     Chapter foundChapter = null;
57
58     if (chapterTitle != null && chapters != null) {
59         for (int i = 0; i < chapters.size(); i++) {
60             if (chapters.get(i) != null &&
61                     chapterTitle.equals(chapters.get(i).getTitle())) {
62                 foundChapter = chapters.get(i);
63                 break;
64             }
65         }
66     }
67     return foundChapter;
68 }
11 private List<Chapter> chapters;
//...
55 public Chapter findChapterByTitle(String chapterTitle) {
56     Chapter foundChapter = null;
57
58     if (chapterTitle != null && chapters != null) {
59         for (int i = 0; i < chapters.size(); i++) {
60             if (chapters.get(i) != null &&
61                     chapterTitle.equals(chapters.get(i).getTitle())) {
62                 foundChapter = chapters.get(i);
63                 break;
64             }
65         }
66     }
67     return foundChapter;
68 }
8     List chapters
//...
17    Chapter findChapterByTitle(String title) {
18        // finding the first item that matches criteria
19        chapters?.find({it?.title == title})
20    }
8     List chapters
//...
22    List findChaptersByTitleStartingWith(String searchKeyword) {
23        // finding all matching items
24        chapters?.findAll({it?.title?.startsWith(searchKeyword)})
25    }
8     List chapters
//...
27    void printChapterTitles() {
28        // iterating over a list
29        chapters.each {chapter ->
30            println chapter?.title
31        }
32    }
duck typing




http://flickr.com/photos/davidw/380277419/
1    package com.piragua.java;
2
3    import javax.servlet.ServletException;
4    import javax.servlet.http.*;
5    import java.io.IOException;
6
7    public class MyServlet extends HttpServlet {
8
9        @Override
10       protected void doPost(HttpServletRequest request,
11                             HttpServletResponse response)
12               throws ServletException, IOException {
13
14           String username = request.getParameter(quot;usernamequot;);
15           if (username != null) {
16               HttpSession session = request.getSession(true);
17               session.setAttribute(quot;loggedInUserquot;, username);
18           }
19
20       }
21   }
22
1    package com.piragua.groovy
2
3    import javax.servlet.http.*
4    import com.piragua.java.MyServlet
5
6    public class MyServletTest extends GroovyTestCase {
7
8     Map params
9     Map session
10
11     def request
12
13     protected void setUp() {
14       params = [:]
15       session = [:]
16       def mockSession = [setAttribute: {k, v -> session[k] = v }]
17
18        request = [
19          getParameter: {param -> return params[param]},
20          getSession: {createNew -> return mockSession as HttpSession}]
21    }
23   void testDoGetFoundUser() {
24       params.username = 'mike'
25       new MyServlet().doPost(request as HttpServletRequest,
26               [:] as HttpServletResponse)
27       assertEquals(params.username, session.loggedInUser)
28   }
29
30   void testDoGetNoUser() {
31       params.username = null
32       new MyServlet().doPost(request as HttpServletRequest,
33              [:] as HttpServletResponse)
34       assertNull(session.loggedInUser)
35   }
If we had more time...
•   file handling

•   really easy regular expressions

•   groovy truth

•   case / switch

•   closures

•   meta programming
http://groovy.codehaus.org/   http://groovy.mn/
Act II
Web MVC Framework
convention




http://flickr.com/photos/markpasc/92779595
configuration




http://flickr.com/photos/clintjcl/169886338
DRY


http://flickr.com/photos/joshsommers/935470210/
Development
Deployment
Artifacts



http://flickr.com/photos/ragesoss/118620722/
Artefacts



http://flickr.com/photos/ragesoss/118620722/
grails create-app devjam
mysql> describe event;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| version    | bigint(20)   | NO   |     | NULL    |                |
| event_date | datetime     | NO   |     | NULL    |                |
| title      | varchar(255) | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> describe event;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| version    | bigint(20)   | NO   |     | NULL    |                |
| event_date | datetime     | NO   |     | NULL    |                |
| title      | varchar(255) | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> describe event;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| version    | bigint(20)   | NO   |     | NULL    |                |
| event_date | datetime     | NO   |     | NULL    |                |
| title      | varchar(255) | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
Zero
Customer

           class Customer {
           ! Address address
           }

Address
class Customer {
! static hasMany = [incidents:Incident]
}




    Customer               Incident
class Customer {
! static hasMany = [products:Product]
}

class Product {
    static hasMany = [customers:Customer]
    static belongsTo = Customer //Customer owns the relationship
}




                           Customer
      Customer                                   Product
                            Product
http://server/devjam/event/list

 name of application
http://server/devjam/event/list

  name of controller
http://server/devjam/event/list

   name of action
http://server/devjam/event/list?max=10
Data Binding
Dependency Injection
Demo
If we had more time...
•   testing

•   tag libraries

•   services

•   plugins

•   content negotiation
http://grails.org   http://grails.org/doc/1.0.x/
Act III
http://flickr.com/photos/johnniewalker/359440369
http://flickr.com/photos/philliecasablanca/2473728872
Learning Curve
100




 75




 50




 25




  0

      * data for this chart is completely fabricated
Learning Curve
100




 75




 50




 25




  0

      * data for this chart is completely fabricated
http://flickr.com/photos/13010608@N02/2441101135/
+   +
http://flickr.com/photos/kevint/85911467
1    package com.piragua.groovy
2
3    import javax.servlet.http.*
4    import com.piragua.java.MyServlet
5
6    class MyServletTest extends GroovyTestCase {
7
8     Map params
9     Map session
10
11     def request
12
13     protected void setUp() {
14       params = [:]
15       session = [:]
16       def mockSession = [setAttribute: {k, v -> session[k] = v }]
http://flickr.com/photos/nengard/82039595
200,000       1 Million    $250/month
 users    page views/month     VPS
http://flickr.com/photos/oxygenws/39895404
XYZ Thing
http://flickr.com/photos/thatblondegirl/467513888
Thank You
Groovy/Grails DevJam




https://duke.dev.java.net/images/guitar/DukeAsKeith-daylight.png
http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/cruise/reporting-app/images/DukeGroovyChair.jpg
3 things to talk about tonight:
-Brief overview of Groovy
-High level Grails (and Live Coding!)
-Thumbs up and Thumbs Down:
! -When should you choose to use Groovy/Grails in existing or
greenfield project
! -Where it has worked (and why) and where it has failed (and why)
Act I




What is Groovy? - ask the audience...possible answers:
- answers.com: “Very pleasing; wonderful.”
- agile language
- scripting language for the JVM
- dynamically typed language
- build tool
- runtime tool for the JVM
- high level language for the JVM that compiles to byte code
- open source java language
“When you program in Groovy, in many ways
                     you’re writing a special kind of Java.”


                                                   -Dierk König
                                                Groovy in Action




Groovy is all of those things, but most of all I like this definition.
What is Groovy? - answer by Dierk König, Groovy committer and
author of “Groovy in Action”
- dynamic language for the JVM
.groovy
                     .java




In fact, most of the time you can take .java file and rename
it .groovy and it will compile and run
Groovy and Java work seamlessly together

-your java classes can reference groovy classes and groovy
classes can reference java classes
hugobook:groovy mjhugo$ groovyc
                usage: groovyc [options] <source-files>
                options:
                    --encoding <encoding>   Specify the encoding of the user class files.
                 -F <flag>
                 -J <property=value>
                 -d                         Specify where to place generated class files.
                 -e,--exception             Print stack trace on error.
                 -h,--help                  Print a synopsis of standard options.
                 -j,--jointCompilation      Attach javac compiler to compile .java files.
                 -v,--version               Print the version.




This is because of something unique to groovy - the Groovy Joint
Compiler
- you can compile .groovy and .java files at the same time
allowing that seamless interaction
What this means is if you’re already using Java, it works with
everything you already have
- IDEs
- Open Source Frameworks
- Application Servers, etc.
20%



                                         80%

For me, it comes down to the 80/20 rule.
Groovy gives me the ability to write concise code thatquot;s straight to the point of
what Iquot;m trying to do. I donquot;t have to include “ceremony” - code that doesnquot;t
relate to the task at hand (Stuart Halloway, http://blog.thinkrelevance.com/
2008/4/1/ending-legacy-code-in-our-lifetime) and can focus directly on the goal
my code is trying to achieve.

Examples...
getters and setters




Getters and Setters Example
Standard stuff - create some properties and have your IDE of choice generate the
getters and setters
but WHY generate them? they add so much noise to your code...
1    package com.piragua.java;
                 2
                 3    public class SimpleBook {
                 4        private String title;
                 5        private String authorName;
                 6
                 7        public String getTitle() {
                 8            return title;
                 9        }
                 10
                 11       public void setTitle(String title) {
                 12           this.title = title;
                 13       }
                 14
                 15       public String getAuthorName() {
                 16           return authorName;
                 17       }
                 18
                 19       public void setAuthorName(String authorName) {
                 20           this.authorName = authorName;
                 21       }
                 22   }




Java example: two properties, 15 lines of code for getters/
setters

Now, letquot;s look at the same class in Groovy...
1   package com.piragua.groovy
                    2
                    3   class SimpleBook {
                    4       String title
                    5       String authorName
                    6   }




Same class, 0 lines of code for getters/setters

Also notice that the attributes and the class are not scoped - thatquot;s
because Groovy provides sensible defaults for these -

Lets take a look at a snippet of the byte code as shown by javap
javap -private SimpleBook

                   Compiled from quot;SimpleBook.groovyquot;
                   public class com.piragua.groovy.SimpleBook ... {

                       private java.lang.String title;
                       private java.lang.String author;

                       public java.lang.String getTitle();
                       public void setTitle(java.lang.String);

                       public java.lang.String getAuthor();
                       public void setAuthor(java.lang.String);

                       ...

                   }




- getters and setters are provided automatically
! - You can add your own getters and setters to define custom
behavior - but how often do you really do this?
javap -private SimpleBook

                     Compiled from quot;SimpleBook.groovyquot;
                     public class com.piragua.groovy.SimpleBook ... {

                         private java.lang.String title;
                         private java.lang.String author;

                         public java.lang.String getTitle();
                         public void setTitle(java.lang.String);

                         public java.lang.String getAuthor();
                         public void setAuthor(java.lang.String);

                         ...

                     }




- no need to define class as public - thatquot;s the default
- attributes are private by default
- methods are public by default
1    package com.piragua.java;                                                                     1    package com.piragua.groovy
                      2                                                                                                  2
                      3    import java.util.Date;                                                                        3    class Book {
                      4    import java.util.List;                                                                        4        String title
                      5                                                                                                  5        String authorName
                      6    public class Book {                                                                           6        Integer numberOfPages
                      7        private String title;                                                                     7        String subTitle
                      8        private String authorName;                                                                8        List chapters
                      9        private Integer numberOfPages;                                                            9        Date publishDate
                      10       private String subTitle;                                                                  10       String publisher
                      11       private List<Chapter> chapters;                                                           11
                      12       private Date publishDate;                                                                 12       String toString() {
                      13       private String publisher;                                                                 13           title?.toUpperCase()
                      14                                                                                                 14       }
                      15       public String getPublisher() {                                                            15
                      16           return publisher;                                                                     16       String displayString() {
                      17       }                                                                                         17           quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot;
                      18                                                                                                 18       }
                      19       public void setPublisher(String publisher) {                                              19
                      20           this.publisher = publisher;                                                           20       Chapter findChapterByTitle(String title) {
                      21       }                                                                                         21           // finding the first item that matches criteria
                      22                                                                                                 22           chapters?.find({it?.title == title})
                      23       public Date getPublishDate() {                                                            23       }
                      24           return publishDate;                                                                   24   }
                      25       }
                      26
                      27       public void setPublishDate(Date publishDate) {
                      28           this.publishDate = publishDate;
                      29       }
                      30
                      31       public List getChapters() {
                      32           return chapters;
                      33       }
                      34
                      35       public void setChapters(List chapters) {
                      36           this.chapters = chapters;
                      37       }
                      38
                      39       public String getTitle() {
                      40           return title;
                      41       }
                      42
                      43       public void setTitle(String title) {
                      44           this.title = title;
                      45       }
                      46
                      47       public String getAuthorName() {
                      48           return authorName;
                      49       }
                      50
                      51       public void setAuthorName(String authorName) {
                      52           this.authorName = authorName;
                      53       }
                      54
                      55       public Integer getNumberOfPages() {
                      56           return numberOfPages;
                      57       }
                      58
                      59       public void setNumberOfPages(Integer numberOfPages) {
                      60           this.numberOfPages = numberOfPages;
                      61       }
                      62
                      63       public String getSubTitle() {
                      64           return subTitle;
                      65       }
                      66
                      67       public void setSubTitle(String subTitle) {
                      68           this.subTitle = subTitle;
                      69       }
                      70
                      71       public String toString() {
                      72           String upperCaseTitle = null;
                      73           if (title != null) {
                      74               upperCaseTitle = title.toUpperCase();
                      75           }
                      76           return upperCaseTitle;
                      77       }
                      78
                      79       public String displayString() {
                      80           return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;;
                      81       }
                      82
                      83       public Chapter findChapterByTitle(String chapterTitle) {
                      84           Chapter foundChapter = null;
                      85
                      86           if (chapterTitle != null && chapters != null) {
                      87               for (int i = 0; i < chapters.size(); i++) {
                      88                   if (chapters.get(i) != null &&
                      89                           chapterTitle.equals(chapters.get(i).getTitle())) {
                      90                       foundChapter = chapters.get(i);
                      91                       break;
                      92                   }
                      93               }
                      94           }
                      95           return foundChapter;
                      96       }
                      97   }




This is the same class - on the left is Java (97 lines of code), on the right is
Groovy (24 lines of code).
6 pt font
Each class has 7 attributes and three methods.

When you go to maintain the Book class, which file would you rather work
with?
constructor convenience




http://flickr.com/photos/9229859@N02/1052409181/
1    package com.piragua.java;
                     2
                     3    import junit.framework.TestCase;
                     4
                     5    import java.util.ArrayList;
                     6    import java.util.Date;
                     7
                     8    public class BookTest extends TestCase {
                     9        Book book;
                     10       Chapter chapter;
                     11
                     12      public void setUp() {
                     13          book = new Book();
                     14          book.setNumberOfPages(300);
                     15          book.setAuthorName(quot;Mike Hugoquot;);
                     16          book.setTitle(quot;Groovy Jamquot;);
                     17          book.setSubTitle(quot;Jamminquot;);
                     18          book.setPublisher(quot;Piragua Pressquot;);
                     19          book.setPublishDate(new Date());
                     20      }




Constructor Shortcut
Happens all the time in unit testing, but also sometimes in real code for
setting defaults
New up an object, then call all the setters to populate some values
1    package com.piragua.groovy
                   2
                   3    public class BookTest extends GroovyTestCase {
                   4        Book book
                   5        Chapter grails, groovy, why
                   6
                   7       void setUp() {
                   8         book = new Book(title: quot;Groovy Jamquot;, subTitle:quot;Jamminquot;,
                   9            authorName: quot;Mike Hugoquot;, numberOfPages: 300,
                   10           publishDate:new Date(), publisher: quot;Piragua Pressquot;)
                   11      }




In groovy, you can use named parameters in the constructor to build
objects
- can happen in any order
- can pass all, some, or none of the attributes to the constructor
- itquot;s descriptive - you know whatquot;s being set because it says it right
here (e.g. title: “groovy jam”)...if you created a java constructor how
would you remember which order to pass the parameters?
null safe dereferencing




http://flickr.com/photos/synthesisstudios/352834727/
32   public String toString() {
                  33       String upperCaseTitle = null;
                  34       if (title != null){
                  35           upperCaseTitle = title.toUpperCase();
                  36       }
                  37       return upperCaseTitle;
                  38   }




In Java, you often have times where you check to see if something
is null before performing an action on it
String toString(){
                          title?.toUpperCase()
                      }




In Groovy, you can use the ? operator to safely traverse the tree of an object
graph
// more complex
                       String toString(){
                           book?.publisher?.address?.city?.toUpperCase()
                       }




If any of the attributes in this example are null, groovy will stop at that point
and return null
groovy strings




http://flickr.com/photos/austinevan/416813459/
// Java Example

                  public String displayString() {
                      return quot;<u>quot; + title + quot;</u> by quot; +
                          authorName + quot;, (quot; +
                          numberOfPages + quot; pages)quot;;
                  }




Yeck.

String concatenation is evil
So is using string buffer
// Java Example

                  public String displayString() {
                      return quot;<u>quot; + title + quot;</u> by quot; +
                          authorName + quot;, (quot; +
                          numberOfPages + quot; pages)quot;;
                  }




Yeck.

String concatenation is evil
So is using string buffer
String displayString() {
                    quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot;
                }




Groovy strings allow you to construct strings using ${}
notation

You can also do multi line strings
String multiLineDisplayString() {

                quot;quot;quot;<u>${title}</u>
                by ${authorName}
                (${numberOfPages} pages)quot;quot;quot;

                }




You can also do multi line strings
collections




http://flickr.com/photos/stibbons/375342559/
11 private List<Chapter> chapters;
                    //...
                    55 public Chapter findChapterByTitle(String chapterTitle) {
                    56     Chapter foundChapter = null;
                    57
                    58     if (chapterTitle != null && chapters != null) {
                    59         for (int i = 0; i < chapters.size(); i++) {
                    60             if (chapters.get(i) != null &&
                    61                     chapterTitle.equals(chapters.get(i).getTitle())) {
                    62                 foundChapter = chapters.get(i);
                    63                 break;
                    64             }
                    65         }
                    66     }
                    67     return foundChapter;
                    68 }




Java example of finding a chapter by title

- iterate over the the list until you find the one youquot;re looking for, set it in a
temp variable and break
11 private List<Chapter> chapters;
                   //...
                   55 public Chapter findChapterByTitle(String chapterTitle) {
                   56     Chapter foundChapter = null;
                   57
                   58     if (chapterTitle != null && chapters != null) {
                   59         for (int i = 0; i < chapters.size(); i++) {
                   60             if (chapters.get(i) != null &&
                   61                     chapterTitle.equals(chapters.get(i).getTitle())) {
                   62                 foundChapter = chapters.get(i);
                   63                 break;
                   64             }
                   65         }
                   66     }
                   67     return foundChapter;
                   68 }




Java example of finding a chapter by title

- by the way, did you notice all the null checking going on that distracts
from the essence of the code: finding a chapter by title
8     List chapters
                 //...
                 17    Chapter findChapterByTitle(String title) {
                 18        // finding the first item that matches criteria
                 19        chapters?.find({it?.title == title})
                 20    }




Groovy example

- use .find and pass a closure
- closure is executed against every item in the list until a
match is found

- #itquot; is an implicit parameter passed to a closure, can be
named
8     List chapters
                //...
                22    List findChaptersByTitleStartingWith(String searchKeyword) {
                23        // finding all matching items
                24        chapters?.findAll({it?.title?.startsWith(searchKeyword)})
                25    }




- can also use .findAll
8     List chapters
                 //...
                 27    void printChapterTitles() {
                 28        // iterating over a list
                 29        chapters.each {chapter ->
                 30            println chapter?.title
                 31        }
                 32    }




or .each to iterate over a collection
duck typing




                           http://flickr.com/photos/davidw/380277419/




http://en.wikipedia.org/wiki/Duck_typing
If it walks like a duck and quacks like a duck, I would call it a duck.

Rather than create an interface to define the contract, use behavior at
runtime to determine the functionality

So now, a Java example
oh wait. you canquot;t do this in java. no example here.
1    package com.piragua.java;
                 2
                 3    import javax.servlet.ServletException;
                 4    import javax.servlet.http.*;
                 5    import java.io.IOException;
                 6
                 7    public class MyServlet extends HttpServlet {
                 8
                 9        @Override
                 10       protected void doPost(HttpServletRequest request,
                 11                             HttpServletResponse response)
                 12               throws ServletException, IOException {
                 13
                 14           String username = request.getParameter(quot;usernamequot;);
                 15           if (username != null) {
                 16               HttpSession session = request.getSession(true);
                 17               session.setAttribute(quot;loggedInUserquot;, username);
                 18           }
                 19
                 20       }
                 21   }
                 22




Herequot;s an example of a Java Servlet. It takes a parameter from
the request, and if it is not null, sets it in to the session.

If I wanted to test this, I would have to provide a full
implementation of HttpServletRequest and HttpServletResponse
just in order to call the method.

Note: Spring (and other frameworks) provide Mock
implementations of HttpServletRequest and HttpServletResponse,
1    package com.piragua.groovy
                    2
                    3    import javax.servlet.http.*
                    4    import com.piragua.java.MyServlet
                    5
                    6    public class MyServletTest extends GroovyTestCase {
                    7
                    8     Map params
                    9     Map session
                    10
                    11     def request
                    12
                    13     protected void setUp() {
                    14       params = [:]
                    15       session = [:]
                    16       def mockSession = [setAttribute: {k, v -> session[k] = v }]
                    17
                    18        request = [
                    19          getParameter: {param -> return params[param]},
                    20          getSession: {createNew -> return mockSession as HttpSession}]
                    21    }




But using Groovy, I can utilize Duck Typing to mock out the
implementation.

Line 20 has an example: “mockSession as HttpSession”

more in the tests
23   void testDoGetFoundUser() {
                   24       params.username = 'mike'
                   25       new MyServlet().doPost(request as HttpServletRequest,
                   26               [:] as HttpServletResponse)
                   27       assertEquals(params.username, session.loggedInUser)
                   28   }
                   29
                   30   void testDoGetNoUser() {
                   31       params.username = null
                   32       new MyServlet().doPost(request as HttpServletRequest,
                   33              [:] as HttpServletResponse)
                   34       assertNull(session.loggedInUser)
                   35   }




Line 25: “request as HttpServletRequest” - my map (defined in the setup
method) now looks like a HttpServletRequest to the Servlet under test

Line 33: “[:] as HttpServletResponse” just acts as a non-null
HttpServletResponse. How would you do this in Java? Create a class,
implement the HttpServletResponse interface with a bunch of empty
methods, then new it up and pass it into the doPost method. That sucks.

Now, I know duck typing is controversial. Interfaces can be a good thing,
and they enforce the contract at compile time. With duck typing, you donquot;t
If we had more time...
                                         •   file handling

                                         •   really easy regular expressions

                                         •   groovy truth

                                         •   case / switch

                                         •   closures

                                         •   meta programming




For reference in the handout:
- File: Convenience methods for writing and reading files: http://docs.codehaus.org/display/GROOVY/JN2015-Files
- Truth: .equals is the same as ==; 1 is true, 0 is false; null is false; empty string is false; etc. : http://docs.codehaus.org/
display/GROOVY/Groovy+Truth
- Regular expressions are so easy! http://naleid.com/blog/2008/05/19/dont-fear-the-regexp/
- Case / Switch: can switch on any type: http://groovy.codehaus.org/Logical+Branching
- Closures: named block of code. pass it around, reuse it, do all sorts of fun things: http://groovy.codehaus.org/Closures
- Meta Programming: http://groovy.dzone.com/articles/metaprogramming-groovy-ii-expa , also http://naleid.com/blog/
2008/05/07/what-methods-does-my-groovygrails-class-have/
- See more differences from Java: http://groovy.codehaus.org/Differences+from+Java
http://groovy.codehaus.org/   http://groovy.mn/




Two resources:
Groovy website @ codehaus - api, documentation, and lots of examples
Groovy Users Group of MN - meets the second Tuesday of the month in NE
minneapolis

Also see this presentation by Guillaume LaForge (groovy project manager)
on Groovy
http://www.slideshare.net/glaforge/groovy-and-grails-in-action-devoxx-2008-
university-guillaume-laforge-presentation
Three books:
-Groovy in Action (Dierk König)
-Groovy Recipies (Scott Davis)
-Programming Groovy (Venkat Subramaniam)


http://www.amazon.com/Groovy-Action-Dierk-Koenig/dp/
1932394842
http://www.amazon.com/Groovy-Recipes-Greasing-Pragmatic-
Act II




So now, on to Grails...What is Grails?
Web MVC Framework




Grails is a Web Model/View/Controller framework
that leverages the power of Groovy, Hibernate, Spring and Java
convention




                   http://flickr.com/photos/markpasc/92779595




With it you can do rapid application development by using the
concepts of Convention...
configuration




                   http://flickr.com/photos/clintjcl/169886338




instead of configuration (AKA convention over configuration)
DRY


                   http://flickr.com/photos/joshsommers/935470210/




And “Don’t Repeat Yourself”
Why add all sorts of ceremony to your code in configuration
when it could be implied?
Development




Grails provides a full *development* environment out of the box
including an:
- in-memory HSQL DB
- Jetty application server
- Automatic reloading of most artifacts

But you’re not limited to that in Development or even in
Production -
Deployment




Jetty and HSQLDB are just the defaults -
You can deploy a grails application on any application server that
can handle a WAR file
and any database that has a JDBC driver

But I’m getting ahead of myself...let’s get started with some Grails
basics
Artifacts



                        http://flickr.com/photos/ragesoss/118620722/




Artifacts. or, if you’re british
Artefacts



                      http://flickr.com/photos/ragesoss/118620722/




A lot of the core contributors to Grails are in the UK, so you
sometimes run into this (in the Grails code base)
grails create-app devjam




Every Grails Application has a common structure
Underneath the ‘grails-app’ directory there are sub-directories for
“special” grails artifacts.
Let’s look at a few
The domain subdirectory is for any class that you want to be
persistent.
These classes are automatically mapped to the DB through
Hibernate
Grails will automatically create your database tables based on
your domain classes using Hibernate’s hbm2ddl
There are other ways to manage DB migrations, this is just the
default
mysql> describe event;
               +------------+--------------+------+-----+---------+----------------+
               | Field      | Type         | Null | Key | Default | Extra          |
               +------------+--------------+------+-----+---------+----------------+
               | id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
               | version    | bigint(20)   | NO   |     | NULL    |                |
               | event_date | datetime     | NO   |     | NULL    |                |
               | title      | varchar(255) | NO   |     | NULL    |                |
               +------------+--------------+------+-----+---------+----------------+
               4 rows in set (0.00 sec)




!   - the domain class name becomes the table name
mysql> describe event;
                +------------+--------------+------+-----+---------+----------------+
                | Field      | Type         | Null | Key | Default | Extra          |
                +------------+--------------+------+-----+---------+----------------+
                | id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
                | version    | bigint(20)   | NO   |     | NULL    |                |
                | event_date | datetime     | NO   |     | NULL    |                |
                | title      | varchar(255) | NO   |     | NULL    |                |
                +------------+--------------+------+-----+---------+----------------+
                4 rows in set (0.00 sec)




!   - attribute names are converted into column names
mysql> describe event;
                 +------------+--------------+------+-----+---------+----------------+
                 | Field      | Type         | Null | Key | Default | Extra          |
                 +------------+--------------+------+-----+---------+----------------+
                 | id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
                 | version    | bigint(20)   | NO   |     | NULL    |                |
                 | event_date | datetime     | NO   |     | NULL    |                |
                 | title      | varchar(255) | NO   |     | NULL    |                |
                 +------------+--------------+------+-----+---------+----------------+
                 4 rows in set (0.00 sec)




- id (PK) and version (optimistic locking) columns are added to
DB, but don’t need to be explicitly specified in code

all of these defaults can be overridden through a mapping DSL or
through explicit Hibernate configuration
The next couple examples are screen shots of the “Grails Console”
- an interactive Swing console that is wired up with hibernate and
all your spring beans and everything
Not only are the domain classes automatically mapped to the DB,
Grails adds persistent methods like

.save() - inserts or updates an object
.get(id)

pass in the ID of a persistent object and hibernate will retrieve it
.list()

select * from table
and last but not least, dynamic finders like “findByTitle”
and you can even add criteria like ‘EventDateLessThan’
how about a query using case insensitive ‘like’?
or a query using HQL?
or a query using criteria?
Zero
All of this with: Zero - the amount of configuration and DAO lines
of code you have to do to perform crud on a domain class.
Customer

                                    class Customer {
                                    ! Address address
                                    }

                         Address




Associations are also supported - you can have
- one to one
class Customer {
                ! static hasMany = [incidents:Incident]
                }




                    Customer               Incident




- one to many
class Customer {
                 ! static hasMany = [products:Product]
                 }

                 class Product {
                     static hasMany = [customers:Customer]
                     static belongsTo = Customer //Customer owns the relationship
                 }




                                            Customer
                       Customer                                   Product
                                             Product




- many to many
Controllers are servlets in the Grails world. Any groovy class in
this directory will have a url mapping by convention - no xml
config required:
http://server/devjam/event/list

                      name of application




The context root of your app is the name of the application, in
this case “devjam”
http://server/devjam/event/list

                      name of controller




The next part of a URL is the name of the controller
http://server/devjam/event/list

                       name of action




and the final part is the name of the action (which is a closure
defined in the controller)

These are the defaults - you can change URL mappings to your
liking
http://server/devjam/event/list?max=10




Grails puts all the parameters coming in to a controller in to a
map called ‘params’ - you can access them using ‘dot’ notation
(like ‘params dot max’ to get the ‘max’ parameter)
Data Binding




This is also fantastic for data binding
- on a new object you can pass the ‘params’ map straight to a
object constructor (thank you Groovy constructor convenience)
Dependency Injection




Grails artifacts like controllers and services are created as spring
beans - and grails autowires beans together by name.

In the case, AuthenticateService will automatically be injected into
the EventController - no config needed
Views are GSP (grails server pages) instead of JSPs
you can reference anything that is in the ‘model’ with ${} notation
(like eventInstance)
there’s a convention for where the views go - by default views for
the “EventController” go in the “views/event” subdirectory
Grails uses SiteMesh to decorate pages - so your GSPs are simple
HTML
that have a layout applied to them
Demo


Demo - build a simple Grails app to
-list events (demo scaquot;olding)
-create a new event (demo domain constraints)
-allow users to RSVP to them (demo reloading of controller and
dependency injection)
-create RSS feed of events list (install and use feeds plugin)
If we had more time...
                                   •   testing

                                   •   tag libraries

                                   •   services

                                   •   plugins

                                   •   content negotiation




For reference in the handout:
Testing: http://www.grails.org/Testing+Plugin
Tag Libraries: http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.3%20Tag%20Libraries
Services: http://grails.org/doc/1.0.x/guide/8.%20The%20Service%20Layer.html
Plugins: http://grails.org/Plugins
Content Negotiation: http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.8%20Content%20Negotiation
http://grails.org   http://grails.org/doc/1.0.x/




Two resources:
Grails.org website - great starting point - and a grails app itself
Grails reference guide - excellent documentation of Grails
Two excellent books coming out very soon (early editions
available from publisher now)

GIA (May?): http://www.amazon.com/Grails-Action-Glen-Smith/
dp/1933988932/
DGG (Jan): http://www.amazon.com/Definitive-Guide-Grails-
Second/dp/1590599950
Act III




Act III:
- when should you consider using these tools in an existing
environment?
- greenfield environment?
- Where have they worked and where havenquot;t they?

When should you consider using these tools in an existing
environment?
The first question I ask is “Are you already a Java shop?”
http://flickr.com/photos/johnniewalker/359440369




If you are - then you already have the infrastructure you need to
build and deploy applications with Groovy/Grails...
http://flickr.com/photos/philliecasablanca/2473728872




And you also have resources that understand Java
If your company/client is open source friendly
Then bringing Groovy into your existing environment is a piece of
cake.
Learning Curve
                 100




                  75




                  50




                  25




                  0

                       * data for this chart is completely fabricated




The learning curve for a new language might look like this
Learning Curve
                 100




                  75




                  50




                  25




                  0

                       * data for this chart is completely fabricated




With Groovy, your Java developers will have a jump start on
learning the language
-the syntax is basically the same
-all the Java APIs are available to you
-can immediately be productive with the language and
conveniences it provides
Integrating Grails into an existing environment may not be quite
as easy
If you’re already using Hibernate for the ORM layer, then it’s
possible. You can take your existing database, existing hibernate
mapping files and Java domain classes and take advantage of all
the features Grails has to oquot;er.

(See “Grails In Action” book for using Grails to map the “Legacy
Database from Hell”)
http://flickr.com/photos/13010608@N02/2441101135/




But where Grails really excels is in a green field
+         +




-If your team is familiar with Hibernate and Spring
-Your process includes iterative development and a fast feedback
loop
-And testing is important
Then you should seriously be considering Grails for your next
project
http://flickr.com/photos/kevint/85911467




Where has it worked?
1    package com.piragua.groovy
                2
                3    import javax.servlet.http.*
                4    import com.piragua.java.MyServlet
                5
                6    class MyServletTest extends GroovyTestCase {
                7
                8     Map params
                9     Map session
                10
                11     def request
                12
                13     protected void setUp() {
                14       params = [:]
                15       session = [:]
                16       def mockSession = [setAttribute: {k, v -> session[k] = v }]




Unit Testing is a great way to start integrating Groovy into your
code base
- collections / xml / file convenience features reduce the amount
of ceremony in your tests
- can make mocking is easier (as shown in earlier groovy slides)
http://flickr.com/photos/nengard/82039595




“internal” apps are a great place for Grails - it’s very easy to
develop a fully functional web app very quickly

I built one at my last client in 12 hours (full user login, search,
audit history and workflow task management)
There are tons of success stories for Grails (http://grails.org/
Success+Stories)
Some very large, some smaller.
200,000       1 Million    $250/month
                    users    page views/month     VPS




Like this example - this Brazilian Entertainment website has 200k
users, 1 million page views per month and runs on a $250/month
VPS - no load balancing or major performance tuning

Feb 2008
reference: http://www.nabble.com/Grails-1.0.1-is-out-
td15548113.html
Linked in uses Grails for some of its sites for corporate customers

http://blog.linkedin.com/2008/06/11/grails-at-linkedin/
Hot oquot; the press - a full case study is coming soon!
wired.com/reviews is Grails powered and more of Wired.com is
moving to Grails soon
http://flickr.com/photos/oxygenws/39895404




Where has it failed?
I have seen projects run into trouble when they don’t test enough.
The dynamic nature of Groovy/Grails means that the compiler
won’t find certain errors - you need good testing to mitigate this
XYZ Thing




Too far outside the box

For instance - one project that didn’t use the conventions that
GORM provides and tried to roll their own persistence mechanism
didn’t go so well.
I hope youquot;ve enjoyed the overview of Groovy/Grails and some thoughts
to consider when choosing them
http://flickr.com/photos/thatblondegirl/467513888




Obviously, I’m drinking the Koolaid
But I’ve also been working with Groovy and Grails for almost 2
years and I’m still a happy camper.
I encourage you to go download Groovy or download Grails and
walk through the “Getting Started” tutorials - and see how these
new tools can help you be more equot;ective
Thank You

Contenu connexe

Tendances

Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8confGR8Conf
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyAli Tanwir
 
Groovy AST Transformations
Groovy AST TransformationsGroovy AST Transformations
Groovy AST Transformationshendersk
 
Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseAndrew Eisenberg
 
Groovy AST Demystified
Groovy AST DemystifiedGroovy AST Demystified
Groovy AST DemystifiedAndres Almiray
 
Groovy for java developers
Groovy for java developersGroovy for java developers
Groovy for java developersPuneet Behl
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java DevelopersAndres Almiray
 
AST Transformations
AST TransformationsAST Transformations
AST TransformationsHamletDRC
 
Groovy And Grails JUG Sardegna
Groovy And Grails JUG SardegnaGroovy And Grails JUG Sardegna
Groovy And Grails JUG SardegnaJohn Leach
 
cdac@parag.gajbhiye@groovy metaprogrammning
cdac@parag.gajbhiye@groovy metaprogrammningcdac@parag.gajbhiye@groovy metaprogrammning
cdac@parag.gajbhiye@groovy metaprogrammningParag Gajbhiye
 
GTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyGTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyAndres Almiray
 
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski
 
Groovy and Grails intro
Groovy and Grails introGroovy and Grails intro
Groovy and Grails introMiguel Pastor
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentSchalk Cronjé
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDanny Preussler
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
Groovy And Grails JUG Trento
Groovy And Grails JUG TrentoGroovy And Grails JUG Trento
Groovy And Grails JUG TrentoJohn Leach
 
Bytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMBytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMashleypuls
 

Tendances (20)

Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8conf
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Groovy AST Transformations
Groovy AST TransformationsGroovy AST Transformations
Groovy AST Transformations
 
Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-Eclipse
 
Groovy AST Demystified
Groovy AST DemystifiedGroovy AST Demystified
Groovy AST Demystified
 
Groovy for java developers
Groovy for java developersGroovy for java developers
Groovy for java developers
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java Developers
 
groovy & grails - lecture 7
groovy & grails - lecture 7groovy & grails - lecture 7
groovy & grails - lecture 7
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Groovy And Grails JUG Sardegna
Groovy And Grails JUG SardegnaGroovy And Grails JUG Sardegna
Groovy And Grails JUG Sardegna
 
cdac@parag.gajbhiye@groovy metaprogrammning
cdac@parag.gajbhiye@groovy metaprogrammningcdac@parag.gajbhiye@groovy metaprogrammning
cdac@parag.gajbhiye@groovy metaprogrammning
 
GTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyGTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with Groovy
 
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
 
Groovy and Grails intro
Groovy and Grails introGroovy and Grails intro
Groovy and Grails intro
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
 
Exploring lambdas and invokedynamic for embedded systems
Exploring lambdas and invokedynamic for embedded systemsExploring lambdas and invokedynamic for embedded systems
Exploring lambdas and invokedynamic for embedded systems
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and Toothpick
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Groovy And Grails JUG Trento
Groovy And Grails JUG TrentoGroovy And Grails JUG Trento
Groovy And Grails JUG Trento
 
Bytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASMBytecode manipulation with Javassist and ASM
Bytecode manipulation with Javassist and ASM
 

En vedette

ICAP OT Maximizing Value 2010-03
ICAP OT Maximizing Value 2010-03ICAP OT Maximizing Value 2010-03
ICAP OT Maximizing Value 2010-03Smarter-Companies
 
Grails lucenecacherdfperformance
Grails lucenecacherdfperformanceGrails lucenecacherdfperformance
Grails lucenecacherdfperformanceMike Hugo
 
Ficha autoevaluacion trabajo final
Ficha autoevaluacion trabajo finalFicha autoevaluacion trabajo final
Ficha autoevaluacion trabajo finalAna Gonzales Pérez
 
Hi speed video toepassingen in de industrie 20120615-s
Hi speed video toepassingen in de industrie 20120615-sHi speed video toepassingen in de industrie 20120615-s
Hi speed video toepassingen in de industrie 20120615-sWouterdestecker
 
Exit Planners Guide to Building Corporate Value through Intangible Capital
Exit Planners Guide to Building Corporate Value through Intangible CapitalExit Planners Guide to Building Corporate Value through Intangible Capital
Exit Planners Guide to Building Corporate Value through Intangible CapitalSmarter-Companies
 
Badolie
BadolieBadolie
Badoliecalp1
 
Post-Election Health Policy - Impact on Physicians
Post-Election Health Policy - Impact on PhysiciansPost-Election Health Policy - Impact on Physicians
Post-Election Health Policy - Impact on Physiciansguestd63c45
 
Douche
DoucheDouche
Douchecalp1
 
11 Moments of Hitting the Sales Wall and How to Get Over It
11 Moments of Hitting the Sales Wall and How to Get Over It11 Moments of Hitting the Sales Wall and How to Get Over It
11 Moments of Hitting the Sales Wall and How to Get Over ItMichael Lang
 
Schaumburg Regional Airport Billboard Ads
Schaumburg Regional Airport Billboard AdsSchaumburg Regional Airport Billboard Ads
Schaumburg Regional Airport Billboard Adsmaryjane627
 
Mercer Island, Wa Estate
Mercer Island, Wa EstateMercer Island, Wa Estate
Mercer Island, Wa EstateMark Shuler
 
Social Media: Oh Where to Begin?
Social Media: Oh Where to Begin?Social Media: Oh Where to Begin?
Social Media: Oh Where to Begin?Smarter-Companies
 
LocationSelector.com
LocationSelector.comLocationSelector.com
LocationSelector.comZoe Harries
 

En vedette (16)

ICAP OT Maximizing Value 2010-03
ICAP OT Maximizing Value 2010-03ICAP OT Maximizing Value 2010-03
ICAP OT Maximizing Value 2010-03
 
Grails lucenecacherdfperformance
Grails lucenecacherdfperformanceGrails lucenecacherdfperformance
Grails lucenecacherdfperformance
 
Ficha autoevaluacion trabajo final
Ficha autoevaluacion trabajo finalFicha autoevaluacion trabajo final
Ficha autoevaluacion trabajo final
 
Hi speed video toepassingen in de industrie 20120615-s
Hi speed video toepassingen in de industrie 20120615-sHi speed video toepassingen in de industrie 20120615-s
Hi speed video toepassingen in de industrie 20120615-s
 
Exit Planners Guide to Building Corporate Value through Intangible Capital
Exit Planners Guide to Building Corporate Value through Intangible CapitalExit Planners Guide to Building Corporate Value through Intangible Capital
Exit Planners Guide to Building Corporate Value through Intangible Capital
 
Badolie
BadolieBadolie
Badolie
 
La Planta
La PlantaLa Planta
La Planta
 
Post-Election Health Policy - Impact on Physicians
Post-Election Health Policy - Impact on PhysiciansPost-Election Health Policy - Impact on Physicians
Post-Election Health Policy - Impact on Physicians
 
Douche
DoucheDouche
Douche
 
11 Moments of Hitting the Sales Wall and How to Get Over It
11 Moments of Hitting the Sales Wall and How to Get Over It11 Moments of Hitting the Sales Wall and How to Get Over It
11 Moments of Hitting the Sales Wall and How to Get Over It
 
Jgdg Portfolio
Jgdg PortfolioJgdg Portfolio
Jgdg Portfolio
 
Schaumburg Regional Airport Billboard Ads
Schaumburg Regional Airport Billboard AdsSchaumburg Regional Airport Billboard Ads
Schaumburg Regional Airport Billboard Ads
 
Mercer Island, Wa Estate
Mercer Island, Wa EstateMercer Island, Wa Estate
Mercer Island, Wa Estate
 
Social Media: Oh Where to Begin?
Social Media: Oh Where to Begin?Social Media: Oh Where to Begin?
Social Media: Oh Where to Begin?
 
LocationSelector.com
LocationSelector.comLocationSelector.com
LocationSelector.com
 
Group Presentation Ecmod
Group Presentation EcmodGroup Presentation Ecmod
Group Presentation Ecmod
 

Similaire à Groovy Grails DevJam Jam Session

java question Fill the add statement areaProject is to wo.pdf
java question Fill the add statement areaProject is to wo.pdfjava question Fill the add statement areaProject is to wo.pdf
java question Fill the add statement areaProject is to wo.pdfdbrienmhompsonkath75
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEDarwin Durand
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and UtilitiesPramod Kumar
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Laporan Resmi Algoritma dan Struktur Data :
Laporan Resmi Algoritma dan Struktur Data : Laporan Resmi Algoritma dan Struktur Data :
Laporan Resmi Algoritma dan Struktur Data : Siska Amelia
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy PluginsPaul King
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)HamletDRC
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for KotlinTechMagic
 
Type script, for dummies
Type script, for dummiesType script, for dummies
Type script, for dummiessantiagoaguiar
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages VictorSzoltysek
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в JavaDEVTYPE
 
CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodecamp Romania
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency GotchasAlex Miller
 
Link.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docxLink.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docxSHIVA101531
 
Lombokの紹介
Lombokの紹介Lombokの紹介
Lombokの紹介onozaty
 
Production.javapublic class Production {    Declaring instance.pdf
Production.javapublic class Production {    Declaring instance.pdfProduction.javapublic class Production {    Declaring instance.pdf
Production.javapublic class Production {    Declaring instance.pdfsooryasalini
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code genkoji lin
 

Similaire à Groovy Grails DevJam Jam Session (20)

java question Fill the add statement areaProject is to wo.pdf
java question Fill the add statement areaProject is to wo.pdfjava question Fill the add statement areaProject is to wo.pdf
java question Fill the add statement areaProject is to wo.pdf
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Laporan Resmi Algoritma dan Struktur Data :
Laporan Resmi Algoritma dan Struktur Data : Laporan Resmi Algoritma dan Struktur Data :
Laporan Resmi Algoritma dan Struktur Data :
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for Kotlin
 
Type script, for dummies
Type script, for dummiesType script, for dummies
Type script, for dummies
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
CodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical GroovyCodeCamp Iasi 10 march 2012 - Practical Groovy
CodeCamp Iasi 10 march 2012 - Practical Groovy
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency Gotchas
 
Link.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docxLink.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docx
 
Workshop Scala
Workshop ScalaWorkshop Scala
Workshop Scala
 
Lombokの紹介
Lombokの紹介Lombokの紹介
Lombokの紹介
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Production.javapublic class Production {    Declaring instance.pdf
Production.javapublic class Production {    Declaring instance.pdfProduction.javapublic class Production {    Declaring instance.pdf
Production.javapublic class Production {    Declaring instance.pdf
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 

Dernier

57 Bidens Annihilation Nation Policy.pdf
57 Bidens Annihilation Nation Policy.pdf57 Bidens Annihilation Nation Policy.pdf
57 Bidens Annihilation Nation Policy.pdfGerald Furnkranz
 
Brief biography of Julius Robert Oppenheimer
Brief biography of Julius Robert OppenheimerBrief biography of Julius Robert Oppenheimer
Brief biography of Julius Robert OppenheimerOmarCabrera39
 
IndiaWest: Your Trusted Source for Today's Global News
IndiaWest: Your Trusted Source for Today's Global NewsIndiaWest: Your Trusted Source for Today's Global News
IndiaWest: Your Trusted Source for Today's Global NewsIndiaWest2
 
Quiz for Heritage Indian including all the rounds
Quiz for Heritage Indian including all the roundsQuiz for Heritage Indian including all the rounds
Quiz for Heritage Indian including all the roundsnaxymaxyy
 
Referendum Party 2024 Election Manifesto
Referendum Party 2024 Election ManifestoReferendum Party 2024 Election Manifesto
Referendum Party 2024 Election ManifestoSABC News
 
Top 10 Wealthiest People In The World.pdf
Top 10 Wealthiest People In The World.pdfTop 10 Wealthiest People In The World.pdf
Top 10 Wealthiest People In The World.pdfauroraaudrey4826
 
Opportunities, challenges, and power of media and information
Opportunities, challenges, and power of media and informationOpportunities, challenges, and power of media and information
Opportunities, challenges, and power of media and informationReyMonsales
 
Manipur-Book-Final-2-compressed.pdfsal'rpk
Manipur-Book-Final-2-compressed.pdfsal'rpkManipur-Book-Final-2-compressed.pdfsal'rpk
Manipur-Book-Final-2-compressed.pdfsal'rpkbhavenpr
 
Rohan Jaitley: Central Gov't Standing Counsel for Justice
Rohan Jaitley: Central Gov't Standing Counsel for JusticeRohan Jaitley: Central Gov't Standing Counsel for Justice
Rohan Jaitley: Central Gov't Standing Counsel for JusticeAbdulGhani778830
 
Global Terrorism and its types and prevention ppt.
Global Terrorism and its types and prevention ppt.Global Terrorism and its types and prevention ppt.
Global Terrorism and its types and prevention ppt.NaveedKhaskheli1
 
AP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep Victory
AP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep VictoryAP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep Victory
AP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep Victoryanjanibaddipudi1
 
VIP Girls Available Call or WhatsApp 9711199012
VIP Girls Available Call or WhatsApp 9711199012VIP Girls Available Call or WhatsApp 9711199012
VIP Girls Available Call or WhatsApp 9711199012ankitnayak356677
 
complaint-ECI-PM-media-1-Chandru.pdfra;;prfk
complaint-ECI-PM-media-1-Chandru.pdfra;;prfkcomplaint-ECI-PM-media-1-Chandru.pdfra;;prfk
complaint-ECI-PM-media-1-Chandru.pdfra;;prfkbhavenpr
 

Dernier (13)

57 Bidens Annihilation Nation Policy.pdf
57 Bidens Annihilation Nation Policy.pdf57 Bidens Annihilation Nation Policy.pdf
57 Bidens Annihilation Nation Policy.pdf
 
Brief biography of Julius Robert Oppenheimer
Brief biography of Julius Robert OppenheimerBrief biography of Julius Robert Oppenheimer
Brief biography of Julius Robert Oppenheimer
 
IndiaWest: Your Trusted Source for Today's Global News
IndiaWest: Your Trusted Source for Today's Global NewsIndiaWest: Your Trusted Source for Today's Global News
IndiaWest: Your Trusted Source for Today's Global News
 
Quiz for Heritage Indian including all the rounds
Quiz for Heritage Indian including all the roundsQuiz for Heritage Indian including all the rounds
Quiz for Heritage Indian including all the rounds
 
Referendum Party 2024 Election Manifesto
Referendum Party 2024 Election ManifestoReferendum Party 2024 Election Manifesto
Referendum Party 2024 Election Manifesto
 
Top 10 Wealthiest People In The World.pdf
Top 10 Wealthiest People In The World.pdfTop 10 Wealthiest People In The World.pdf
Top 10 Wealthiest People In The World.pdf
 
Opportunities, challenges, and power of media and information
Opportunities, challenges, and power of media and informationOpportunities, challenges, and power of media and information
Opportunities, challenges, and power of media and information
 
Manipur-Book-Final-2-compressed.pdfsal'rpk
Manipur-Book-Final-2-compressed.pdfsal'rpkManipur-Book-Final-2-compressed.pdfsal'rpk
Manipur-Book-Final-2-compressed.pdfsal'rpk
 
Rohan Jaitley: Central Gov't Standing Counsel for Justice
Rohan Jaitley: Central Gov't Standing Counsel for JusticeRohan Jaitley: Central Gov't Standing Counsel for Justice
Rohan Jaitley: Central Gov't Standing Counsel for Justice
 
Global Terrorism and its types and prevention ppt.
Global Terrorism and its types and prevention ppt.Global Terrorism and its types and prevention ppt.
Global Terrorism and its types and prevention ppt.
 
AP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep Victory
AP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep VictoryAP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep Victory
AP Election Survey 2024: TDP-Janasena-BJP Alliance Set To Sweep Victory
 
VIP Girls Available Call or WhatsApp 9711199012
VIP Girls Available Call or WhatsApp 9711199012VIP Girls Available Call or WhatsApp 9711199012
VIP Girls Available Call or WhatsApp 9711199012
 
complaint-ECI-PM-media-1-Chandru.pdfra;;prfk
complaint-ECI-PM-media-1-Chandru.pdfra;;prfkcomplaint-ECI-PM-media-1-Chandru.pdfra;;prfk
complaint-ECI-PM-media-1-Chandru.pdfra;;prfk
 

Groovy Grails DevJam Jam Session

  • 2.
  • 4. “When you program in Groovy, in many ways you’re writing a special kind of Java.” -Dierk König Groovy in Action
  • 6.
  • 7. hugobook:groovy mjhugo$ groovyc usage: groovyc [options] <source-files> options: --encoding <encoding> Specify the encoding of the user class files. -F <flag> -J <property=value> -d Specify where to place generated class files. -e,--exception Print stack trace on error. -h,--help Print a synopsis of standard options. -j,--jointCompilation Attach javac compiler to compile .java files. -v,--version Print the version.
  • 8.
  • 9. 20% 80%
  • 11. 1 package com.piragua.java; 2 3 public class SimpleBook { 4 private String title; 5 private String authorName; 6 7 public String getTitle() { 8 return title; 9 } 10 11 public void setTitle(String title) { 12 this.title = title; 13 } 14 15 public String getAuthorName() { 16 return authorName; 17 } 18 19 public void setAuthorName(String authorName) { 20 this.authorName = authorName; 21 } 22 }
  • 12. 1 package com.piragua.groovy 2 3 class SimpleBook { 4 String title 5 String authorName 6 }
  • 13. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... }
  • 14. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... }
  • 15. 1 package com.piragua.java; 1 package com.piragua.groovy 2 2 3 import java.util.Date; 3 class Book { 4 import java.util.List; 4 String title 5 5 String authorName 6 public class Book { 6 Integer numberOfPages 7 private String title; 7 String subTitle 8 private String authorName; 8 List chapters 9 private Integer numberOfPages; 9 Date publishDate 10 private String subTitle; 10 String publisher 11 private List<Chapter> chapters; 11 12 private Date publishDate; 12 String toString() { 13 private String publisher; 13 title?.toUpperCase() 14 14 } 15 public String getPublisher() { 15 16 return publisher; 16 String displayString() { 17 } 17 quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; 18 18 } 19 public void setPublisher(String publisher) { 19 20 this.publisher = publisher; 20 Chapter findChapterByTitle(String title) { 21 } 21 // finding the first item that matches criteria 22 22 chapters?.find({it?.title == title}) 23 public Date getPublishDate() { 23 } 24 return publishDate; 24 } 25 } 26 27 public void setPublishDate(Date publishDate) { 28 this.publishDate = publishDate; 29 } 30 31 public List getChapters() { 32 return chapters; 33 } 34 35 public void setChapters(List chapters) { 36 this.chapters = chapters; 37 } 38 39 public String getTitle() { 40 return title; 41 } 42 43 public void setTitle(String title) { 44 this.title = title; 45 } 46 47 public String getAuthorName() { 48 return authorName; 49 } 50 51 public void setAuthorName(String authorName) { 52 this.authorName = authorName; 53 } 54 55 public Integer getNumberOfPages() { 56 return numberOfPages; 57 } 58 59 public void setNumberOfPages(Integer numberOfPages) { 60 this.numberOfPages = numberOfPages; 61 } 62 63 public String getSubTitle() { 64 return subTitle; 65 } 66 67 public void setSubTitle(String subTitle) { 68 this.subTitle = subTitle; 69 } 70 71 public String toString() { 72 String upperCaseTitle = null; 73 if (title != null) { 74 upperCaseTitle = title.toUpperCase(); 75 } 76 return upperCaseTitle; 77 } 78 79 public String displayString() { 80 return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; 81 } 82 83 public Chapter findChapterByTitle(String chapterTitle) { 84 Chapter foundChapter = null; 85 86 if (chapterTitle != null && chapters != null) { 87 for (int i = 0; i < chapters.size(); i++) { 88 if (chapters.get(i) != null && 89 chapterTitle.equals(chapters.get(i).getTitle())) { 90 foundChapter = chapters.get(i); 91 break; 92 } 93 } 94 } 95 return foundChapter; 96 } 97 }
  • 17. 1 package com.piragua.java; 2 3 import junit.framework.TestCase; 4 5 import java.util.ArrayList; 6 import java.util.Date; 7 8 public class BookTest extends TestCase { 9 Book book; 10 Chapter chapter; 11 12 public void setUp() { 13 book = new Book(); 14 book.setNumberOfPages(300); 15 book.setAuthorName(quot;Mike Hugoquot;); 16 book.setTitle(quot;Groovy Jamquot;); 17 book.setSubTitle(quot;Jamminquot;); 18 book.setPublisher(quot;Piragua Pressquot;); 19 book.setPublishDate(new Date()); 20 }
  • 18. 1 package com.piragua.groovy 2 3 public class BookTest extends GroovyTestCase { 4 Book book 5 Chapter grails, groovy, why 6 7 void setUp() { 8 book = new Book(title: quot;Groovy Jamquot;, subTitle:quot;Jamminquot;, 9 authorName: quot;Mike Hugoquot;, numberOfPages: 300, 10 publishDate:new Date(), publisher: quot;Piragua Pressquot;) 11 }
  • 20. 32 public String toString() { 33 String upperCaseTitle = null; 34 if (title != null){ 35 upperCaseTitle = title.toUpperCase(); 36 } 37 return upperCaseTitle; 38 }
  • 21. String toString(){ title?.toUpperCase() }
  • 22. // more complex String toString(){ book?.publisher?.address?.city?.toUpperCase() }
  • 24. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; }
  • 25. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; }
  • 26. String displayString() { quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; }
  • 27. String multiLineDisplayString() { quot;quot;quot;<u>${title}</u> by ${authorName} (${numberOfPages} pages)quot;quot;quot; }
  • 29. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 }
  • 30. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 }
  • 31. 8 List chapters //... 17 Chapter findChapterByTitle(String title) { 18 // finding the first item that matches criteria 19 chapters?.find({it?.title == title}) 20 }
  • 32. 8 List chapters //... 22 List findChaptersByTitleStartingWith(String searchKeyword) { 23 // finding all matching items 24 chapters?.findAll({it?.title?.startsWith(searchKeyword)}) 25 }
  • 33. 8 List chapters //... 27 void printChapterTitles() { 28 // iterating over a list 29 chapters.each {chapter -> 30 println chapter?.title 31 } 32 }
  • 35.
  • 36. 1 package com.piragua.java; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.*; 5 import java.io.IOException; 6 7 public class MyServlet extends HttpServlet { 8 9 @Override 10 protected void doPost(HttpServletRequest request, 11 HttpServletResponse response) 12 throws ServletException, IOException { 13 14 String username = request.getParameter(quot;usernamequot;); 15 if (username != null) { 16 HttpSession session = request.getSession(true); 17 session.setAttribute(quot;loggedInUserquot;, username); 18 } 19 20 } 21 } 22
  • 37. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 public class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }] 17 18 request = [ 19 getParameter: {param -> return params[param]}, 20 getSession: {createNew -> return mockSession as HttpSession}] 21 }
  • 38. 23 void testDoGetFoundUser() { 24 params.username = 'mike' 25 new MyServlet().doPost(request as HttpServletRequest, 26 [:] as HttpServletResponse) 27 assertEquals(params.username, session.loggedInUser) 28 } 29 30 void testDoGetNoUser() { 31 params.username = null 32 new MyServlet().doPost(request as HttpServletRequest, 33 [:] as HttpServletResponse) 34 assertNull(session.loggedInUser) 35 }
  • 39. If we had more time... • file handling • really easy regular expressions • groovy truth • case / switch • closures • meta programming
  • 40. http://groovy.codehaus.org/ http://groovy.mn/
  • 41.
  • 44.
  • 53.
  • 54.
  • 55. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
  • 56. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
  • 57. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67. Zero
  • 68. Customer class Customer { ! Address address } Address
  • 69. class Customer { ! static hasMany = [incidents:Incident] } Customer Incident
  • 70. class Customer { ! static hasMany = [products:Product] } class Product { static hasMany = [customers:Customer] static belongsTo = Customer //Customer owns the relationship } Customer Customer Product Product
  • 71.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83. Demo
  • 84. If we had more time... • testing • tag libraries • services • plugins • content negotiation
  • 85. http://grails.org http://grails.org/doc/1.0.x/
  • 86.
  • 88.
  • 91.
  • 92.
  • 93. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated
  • 94. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated
  • 95.
  • 96.
  • 98. + +
  • 99.
  • 101. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }]
  • 103.
  • 104. 200,000 1 Million $250/month users page views/month VPS
  • 105.
  • 106.
  • 108.
  • 110.
  • 112.
  • 113.
  • 116. 3 things to talk about tonight: -Brief overview of Groovy -High level Grails (and Live Coding!) -Thumbs up and Thumbs Down: ! -When should you choose to use Groovy/Grails in existing or greenfield project ! -Where it has worked (and why) and where it has failed (and why)
  • 117. Act I What is Groovy? - ask the audience...possible answers: - answers.com: “Very pleasing; wonderful.” - agile language - scripting language for the JVM - dynamically typed language - build tool - runtime tool for the JVM - high level language for the JVM that compiles to byte code - open source java language
  • 118. “When you program in Groovy, in many ways you’re writing a special kind of Java.” -Dierk König Groovy in Action Groovy is all of those things, but most of all I like this definition. What is Groovy? - answer by Dierk König, Groovy committer and author of “Groovy in Action” - dynamic language for the JVM
  • 119. .groovy .java In fact, most of the time you can take .java file and rename it .groovy and it will compile and run
  • 120. Groovy and Java work seamlessly together -your java classes can reference groovy classes and groovy classes can reference java classes
  • 121. hugobook:groovy mjhugo$ groovyc usage: groovyc [options] <source-files> options: --encoding <encoding> Specify the encoding of the user class files. -F <flag> -J <property=value> -d Specify where to place generated class files. -e,--exception Print stack trace on error. -h,--help Print a synopsis of standard options. -j,--jointCompilation Attach javac compiler to compile .java files. -v,--version Print the version. This is because of something unique to groovy - the Groovy Joint Compiler - you can compile .groovy and .java files at the same time allowing that seamless interaction
  • 122. What this means is if you’re already using Java, it works with everything you already have - IDEs - Open Source Frameworks - Application Servers, etc.
  • 123. 20% 80% For me, it comes down to the 80/20 rule. Groovy gives me the ability to write concise code thatquot;s straight to the point of what Iquot;m trying to do. I donquot;t have to include “ceremony” - code that doesnquot;t relate to the task at hand (Stuart Halloway, http://blog.thinkrelevance.com/ 2008/4/1/ending-legacy-code-in-our-lifetime) and can focus directly on the goal my code is trying to achieve. Examples...
  • 124. getters and setters Getters and Setters Example Standard stuff - create some properties and have your IDE of choice generate the getters and setters but WHY generate them? they add so much noise to your code...
  • 125. 1 package com.piragua.java; 2 3 public class SimpleBook { 4 private String title; 5 private String authorName; 6 7 public String getTitle() { 8 return title; 9 } 10 11 public void setTitle(String title) { 12 this.title = title; 13 } 14 15 public String getAuthorName() { 16 return authorName; 17 } 18 19 public void setAuthorName(String authorName) { 20 this.authorName = authorName; 21 } 22 } Java example: two properties, 15 lines of code for getters/ setters Now, letquot;s look at the same class in Groovy...
  • 126. 1 package com.piragua.groovy 2 3 class SimpleBook { 4 String title 5 String authorName 6 } Same class, 0 lines of code for getters/setters Also notice that the attributes and the class are not scoped - thatquot;s because Groovy provides sensible defaults for these - Lets take a look at a snippet of the byte code as shown by javap
  • 127. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... } - getters and setters are provided automatically ! - You can add your own getters and setters to define custom behavior - but how often do you really do this?
  • 128. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... } - no need to define class as public - thatquot;s the default - attributes are private by default - methods are public by default
  • 129. 1 package com.piragua.java; 1 package com.piragua.groovy 2 2 3 import java.util.Date; 3 class Book { 4 import java.util.List; 4 String title 5 5 String authorName 6 public class Book { 6 Integer numberOfPages 7 private String title; 7 String subTitle 8 private String authorName; 8 List chapters 9 private Integer numberOfPages; 9 Date publishDate 10 private String subTitle; 10 String publisher 11 private List<Chapter> chapters; 11 12 private Date publishDate; 12 String toString() { 13 private String publisher; 13 title?.toUpperCase() 14 14 } 15 public String getPublisher() { 15 16 return publisher; 16 String displayString() { 17 } 17 quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; 18 18 } 19 public void setPublisher(String publisher) { 19 20 this.publisher = publisher; 20 Chapter findChapterByTitle(String title) { 21 } 21 // finding the first item that matches criteria 22 22 chapters?.find({it?.title == title}) 23 public Date getPublishDate() { 23 } 24 return publishDate; 24 } 25 } 26 27 public void setPublishDate(Date publishDate) { 28 this.publishDate = publishDate; 29 } 30 31 public List getChapters() { 32 return chapters; 33 } 34 35 public void setChapters(List chapters) { 36 this.chapters = chapters; 37 } 38 39 public String getTitle() { 40 return title; 41 } 42 43 public void setTitle(String title) { 44 this.title = title; 45 } 46 47 public String getAuthorName() { 48 return authorName; 49 } 50 51 public void setAuthorName(String authorName) { 52 this.authorName = authorName; 53 } 54 55 public Integer getNumberOfPages() { 56 return numberOfPages; 57 } 58 59 public void setNumberOfPages(Integer numberOfPages) { 60 this.numberOfPages = numberOfPages; 61 } 62 63 public String getSubTitle() { 64 return subTitle; 65 } 66 67 public void setSubTitle(String subTitle) { 68 this.subTitle = subTitle; 69 } 70 71 public String toString() { 72 String upperCaseTitle = null; 73 if (title != null) { 74 upperCaseTitle = title.toUpperCase(); 75 } 76 return upperCaseTitle; 77 } 78 79 public String displayString() { 80 return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; 81 } 82 83 public Chapter findChapterByTitle(String chapterTitle) { 84 Chapter foundChapter = null; 85 86 if (chapterTitle != null && chapters != null) { 87 for (int i = 0; i < chapters.size(); i++) { 88 if (chapters.get(i) != null && 89 chapterTitle.equals(chapters.get(i).getTitle())) { 90 foundChapter = chapters.get(i); 91 break; 92 } 93 } 94 } 95 return foundChapter; 96 } 97 } This is the same class - on the left is Java (97 lines of code), on the right is Groovy (24 lines of code). 6 pt font Each class has 7 attributes and three methods. When you go to maintain the Book class, which file would you rather work with?
  • 131. 1 package com.piragua.java; 2 3 import junit.framework.TestCase; 4 5 import java.util.ArrayList; 6 import java.util.Date; 7 8 public class BookTest extends TestCase { 9 Book book; 10 Chapter chapter; 11 12 public void setUp() { 13 book = new Book(); 14 book.setNumberOfPages(300); 15 book.setAuthorName(quot;Mike Hugoquot;); 16 book.setTitle(quot;Groovy Jamquot;); 17 book.setSubTitle(quot;Jamminquot;); 18 book.setPublisher(quot;Piragua Pressquot;); 19 book.setPublishDate(new Date()); 20 } Constructor Shortcut Happens all the time in unit testing, but also sometimes in real code for setting defaults New up an object, then call all the setters to populate some values
  • 132. 1 package com.piragua.groovy 2 3 public class BookTest extends GroovyTestCase { 4 Book book 5 Chapter grails, groovy, why 6 7 void setUp() { 8 book = new Book(title: quot;Groovy Jamquot;, subTitle:quot;Jamminquot;, 9 authorName: quot;Mike Hugoquot;, numberOfPages: 300, 10 publishDate:new Date(), publisher: quot;Piragua Pressquot;) 11 } In groovy, you can use named parameters in the constructor to build objects - can happen in any order - can pass all, some, or none of the attributes to the constructor - itquot;s descriptive - you know whatquot;s being set because it says it right here (e.g. title: “groovy jam”)...if you created a java constructor how would you remember which order to pass the parameters?
  • 134. 32 public String toString() { 33 String upperCaseTitle = null; 34 if (title != null){ 35 upperCaseTitle = title.toUpperCase(); 36 } 37 return upperCaseTitle; 38 } In Java, you often have times where you check to see if something is null before performing an action on it
  • 135. String toString(){ title?.toUpperCase() } In Groovy, you can use the ? operator to safely traverse the tree of an object graph
  • 136. // more complex String toString(){ book?.publisher?.address?.city?.toUpperCase() } If any of the attributes in this example are null, groovy will stop at that point and return null
  • 138. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; } Yeck. String concatenation is evil So is using string buffer
  • 139. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; } Yeck. String concatenation is evil So is using string buffer
  • 140. String displayString() { quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; } Groovy strings allow you to construct strings using ${} notation You can also do multi line strings
  • 141. String multiLineDisplayString() { quot;quot;quot;<u>${title}</u> by ${authorName} (${numberOfPages} pages)quot;quot;quot; } You can also do multi line strings
  • 143. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 } Java example of finding a chapter by title - iterate over the the list until you find the one youquot;re looking for, set it in a temp variable and break
  • 144. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 } Java example of finding a chapter by title - by the way, did you notice all the null checking going on that distracts from the essence of the code: finding a chapter by title
  • 145. 8 List chapters //... 17 Chapter findChapterByTitle(String title) { 18 // finding the first item that matches criteria 19 chapters?.find({it?.title == title}) 20 } Groovy example - use .find and pass a closure - closure is executed against every item in the list until a match is found - #itquot; is an implicit parameter passed to a closure, can be named
  • 146. 8 List chapters //... 22 List findChaptersByTitleStartingWith(String searchKeyword) { 23 // finding all matching items 24 chapters?.findAll({it?.title?.startsWith(searchKeyword)}) 25 } - can also use .findAll
  • 147. 8 List chapters //... 27 void printChapterTitles() { 28 // iterating over a list 29 chapters.each {chapter -> 30 println chapter?.title 31 } 32 } or .each to iterate over a collection
  • 148. duck typing http://flickr.com/photos/davidw/380277419/ http://en.wikipedia.org/wiki/Duck_typing If it walks like a duck and quacks like a duck, I would call it a duck. Rather than create an interface to define the contract, use behavior at runtime to determine the functionality So now, a Java example
  • 149. oh wait. you canquot;t do this in java. no example here.
  • 150. 1 package com.piragua.java; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.*; 5 import java.io.IOException; 6 7 public class MyServlet extends HttpServlet { 8 9 @Override 10 protected void doPost(HttpServletRequest request, 11 HttpServletResponse response) 12 throws ServletException, IOException { 13 14 String username = request.getParameter(quot;usernamequot;); 15 if (username != null) { 16 HttpSession session = request.getSession(true); 17 session.setAttribute(quot;loggedInUserquot;, username); 18 } 19 20 } 21 } 22 Herequot;s an example of a Java Servlet. It takes a parameter from the request, and if it is not null, sets it in to the session. If I wanted to test this, I would have to provide a full implementation of HttpServletRequest and HttpServletResponse just in order to call the method. Note: Spring (and other frameworks) provide Mock implementations of HttpServletRequest and HttpServletResponse,
  • 151. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 public class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }] 17 18 request = [ 19 getParameter: {param -> return params[param]}, 20 getSession: {createNew -> return mockSession as HttpSession}] 21 } But using Groovy, I can utilize Duck Typing to mock out the implementation. Line 20 has an example: “mockSession as HttpSession” more in the tests
  • 152. 23 void testDoGetFoundUser() { 24 params.username = 'mike' 25 new MyServlet().doPost(request as HttpServletRequest, 26 [:] as HttpServletResponse) 27 assertEquals(params.username, session.loggedInUser) 28 } 29 30 void testDoGetNoUser() { 31 params.username = null 32 new MyServlet().doPost(request as HttpServletRequest, 33 [:] as HttpServletResponse) 34 assertNull(session.loggedInUser) 35 } Line 25: “request as HttpServletRequest” - my map (defined in the setup method) now looks like a HttpServletRequest to the Servlet under test Line 33: “[:] as HttpServletResponse” just acts as a non-null HttpServletResponse. How would you do this in Java? Create a class, implement the HttpServletResponse interface with a bunch of empty methods, then new it up and pass it into the doPost method. That sucks. Now, I know duck typing is controversial. Interfaces can be a good thing, and they enforce the contract at compile time. With duck typing, you donquot;t
  • 153. If we had more time... • file handling • really easy regular expressions • groovy truth • case / switch • closures • meta programming For reference in the handout: - File: Convenience methods for writing and reading files: http://docs.codehaus.org/display/GROOVY/JN2015-Files - Truth: .equals is the same as ==; 1 is true, 0 is false; null is false; empty string is false; etc. : http://docs.codehaus.org/ display/GROOVY/Groovy+Truth - Regular expressions are so easy! http://naleid.com/blog/2008/05/19/dont-fear-the-regexp/ - Case / Switch: can switch on any type: http://groovy.codehaus.org/Logical+Branching - Closures: named block of code. pass it around, reuse it, do all sorts of fun things: http://groovy.codehaus.org/Closures - Meta Programming: http://groovy.dzone.com/articles/metaprogramming-groovy-ii-expa , also http://naleid.com/blog/ 2008/05/07/what-methods-does-my-groovygrails-class-have/ - See more differences from Java: http://groovy.codehaus.org/Differences+from+Java
  • 154. http://groovy.codehaus.org/ http://groovy.mn/ Two resources: Groovy website @ codehaus - api, documentation, and lots of examples Groovy Users Group of MN - meets the second Tuesday of the month in NE minneapolis Also see this presentation by Guillaume LaForge (groovy project manager) on Groovy http://www.slideshare.net/glaforge/groovy-and-grails-in-action-devoxx-2008- university-guillaume-laforge-presentation
  • 155. Three books: -Groovy in Action (Dierk König) -Groovy Recipies (Scott Davis) -Programming Groovy (Venkat Subramaniam) http://www.amazon.com/Groovy-Action-Dierk-Koenig/dp/ 1932394842 http://www.amazon.com/Groovy-Recipes-Greasing-Pragmatic-
  • 156. Act II So now, on to Grails...What is Grails?
  • 157. Web MVC Framework Grails is a Web Model/View/Controller framework
  • 158. that leverages the power of Groovy, Hibernate, Spring and Java
  • 159. convention http://flickr.com/photos/markpasc/92779595 With it you can do rapid application development by using the concepts of Convention...
  • 160. configuration http://flickr.com/photos/clintjcl/169886338 instead of configuration (AKA convention over configuration)
  • 161. DRY http://flickr.com/photos/joshsommers/935470210/ And “Don’t Repeat Yourself” Why add all sorts of ceremony to your code in configuration when it could be implied?
  • 162. Development Grails provides a full *development* environment out of the box including an: - in-memory HSQL DB - Jetty application server - Automatic reloading of most artifacts But you’re not limited to that in Development or even in Production -
  • 163. Deployment Jetty and HSQLDB are just the defaults - You can deploy a grails application on any application server that can handle a WAR file and any database that has a JDBC driver But I’m getting ahead of myself...let’s get started with some Grails basics
  • 164. Artifacts http://flickr.com/photos/ragesoss/118620722/ Artifacts. or, if you’re british
  • 165. Artefacts http://flickr.com/photos/ragesoss/118620722/ A lot of the core contributors to Grails are in the UK, so you sometimes run into this (in the Grails code base)
  • 166. grails create-app devjam Every Grails Application has a common structure Underneath the ‘grails-app’ directory there are sub-directories for “special” grails artifacts. Let’s look at a few
  • 167. The domain subdirectory is for any class that you want to be persistent. These classes are automatically mapped to the DB through Hibernate
  • 168. Grails will automatically create your database tables based on your domain classes using Hibernate’s hbm2ddl There are other ways to manage DB migrations, this is just the default
  • 169. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) ! - the domain class name becomes the table name
  • 170. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) ! - attribute names are converted into column names
  • 171. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) - id (PK) and version (optimistic locking) columns are added to DB, but don’t need to be explicitly specified in code all of these defaults can be overridden through a mapping DSL or through explicit Hibernate configuration
  • 172. The next couple examples are screen shots of the “Grails Console” - an interactive Swing console that is wired up with hibernate and all your spring beans and everything
  • 173. Not only are the domain classes automatically mapped to the DB, Grails adds persistent methods like .save() - inserts or updates an object
  • 174. .get(id) pass in the ID of a persistent object and hibernate will retrieve it
  • 176. and last but not least, dynamic finders like “findByTitle”
  • 177. and you can even add criteria like ‘EventDateLessThan’
  • 178. how about a query using case insensitive ‘like’?
  • 179. or a query using HQL?
  • 180. or a query using criteria?
  • 181. Zero All of this with: Zero - the amount of configuration and DAO lines of code you have to do to perform crud on a domain class.
  • 182. Customer class Customer { ! Address address } Address Associations are also supported - you can have - one to one
  • 183. class Customer { ! static hasMany = [incidents:Incident] } Customer Incident - one to many
  • 184. class Customer { ! static hasMany = [products:Product] } class Product { static hasMany = [customers:Customer] static belongsTo = Customer //Customer owns the relationship } Customer Customer Product Product - many to many
  • 185. Controllers are servlets in the Grails world. Any groovy class in this directory will have a url mapping by convention - no xml config required:
  • 186. http://server/devjam/event/list name of application The context root of your app is the name of the application, in this case “devjam”
  • 187. http://server/devjam/event/list name of controller The next part of a URL is the name of the controller
  • 188. http://server/devjam/event/list name of action and the final part is the name of the action (which is a closure defined in the controller) These are the defaults - you can change URL mappings to your liking
  • 189. http://server/devjam/event/list?max=10 Grails puts all the parameters coming in to a controller in to a map called ‘params’ - you can access them using ‘dot’ notation (like ‘params dot max’ to get the ‘max’ parameter)
  • 190. Data Binding This is also fantastic for data binding - on a new object you can pass the ‘params’ map straight to a object constructor (thank you Groovy constructor convenience)
  • 191. Dependency Injection Grails artifacts like controllers and services are created as spring beans - and grails autowires beans together by name. In the case, AuthenticateService will automatically be injected into the EventController - no config needed
  • 192. Views are GSP (grails server pages) instead of JSPs
  • 193. you can reference anything that is in the ‘model’ with ${} notation (like eventInstance)
  • 194. there’s a convention for where the views go - by default views for the “EventController” go in the “views/event” subdirectory
  • 195. Grails uses SiteMesh to decorate pages - so your GSPs are simple HTML
  • 196. that have a layout applied to them
  • 197. Demo Demo - build a simple Grails app to -list events (demo scaquot;olding) -create a new event (demo domain constraints) -allow users to RSVP to them (demo reloading of controller and dependency injection) -create RSS feed of events list (install and use feeds plugin)
  • 198. If we had more time... • testing • tag libraries • services • plugins • content negotiation For reference in the handout: Testing: http://www.grails.org/Testing+Plugin Tag Libraries: http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.3%20Tag%20Libraries Services: http://grails.org/doc/1.0.x/guide/8.%20The%20Service%20Layer.html Plugins: http://grails.org/Plugins Content Negotiation: http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.8%20Content%20Negotiation
  • 199. http://grails.org http://grails.org/doc/1.0.x/ Two resources: Grails.org website - great starting point - and a grails app itself Grails reference guide - excellent documentation of Grails
  • 200. Two excellent books coming out very soon (early editions available from publisher now) GIA (May?): http://www.amazon.com/Grails-Action-Glen-Smith/ dp/1933988932/ DGG (Jan): http://www.amazon.com/Definitive-Guide-Grails- Second/dp/1590599950
  • 201. Act III Act III: - when should you consider using these tools in an existing environment? - greenfield environment? - Where have they worked and where havenquot;t they? When should you consider using these tools in an existing environment?
  • 202. The first question I ask is “Are you already a Java shop?”
  • 203. http://flickr.com/photos/johnniewalker/359440369 If you are - then you already have the infrastructure you need to build and deploy applications with Groovy/Grails...
  • 205. If your company/client is open source friendly
  • 206. Then bringing Groovy into your existing environment is a piece of cake.
  • 207. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated The learning curve for a new language might look like this
  • 208. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated With Groovy, your Java developers will have a jump start on learning the language -the syntax is basically the same -all the Java APIs are available to you -can immediately be productive with the language and conveniences it provides
  • 209. Integrating Grails into an existing environment may not be quite as easy
  • 210. If you’re already using Hibernate for the ORM layer, then it’s possible. You can take your existing database, existing hibernate mapping files and Java domain classes and take advantage of all the features Grails has to oquot;er. (See “Grails In Action” book for using Grails to map the “Legacy Database from Hell”)
  • 212. + + -If your team is familiar with Hibernate and Spring -Your process includes iterative development and a fast feedback loop -And testing is important
  • 213. Then you should seriously be considering Grails for your next project
  • 215. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }] Unit Testing is a great way to start integrating Groovy into your code base - collections / xml / file convenience features reduce the amount of ceremony in your tests - can make mocking is easier (as shown in earlier groovy slides)
  • 216. http://flickr.com/photos/nengard/82039595 “internal” apps are a great place for Grails - it’s very easy to develop a fully functional web app very quickly I built one at my last client in 12 hours (full user login, search, audit history and workflow task management)
  • 217. There are tons of success stories for Grails (http://grails.org/ Success+Stories) Some very large, some smaller.
  • 218. 200,000 1 Million $250/month users page views/month VPS Like this example - this Brazilian Entertainment website has 200k users, 1 million page views per month and runs on a $250/month VPS - no load balancing or major performance tuning Feb 2008 reference: http://www.nabble.com/Grails-1.0.1-is-out- td15548113.html
  • 219. Linked in uses Grails for some of its sites for corporate customers http://blog.linkedin.com/2008/06/11/grails-at-linkedin/
  • 220. Hot oquot; the press - a full case study is coming soon! wired.com/reviews is Grails powered and more of Wired.com is moving to Grails soon
  • 222. I have seen projects run into trouble when they don’t test enough. The dynamic nature of Groovy/Grails means that the compiler won’t find certain errors - you need good testing to mitigate this
  • 223. XYZ Thing Too far outside the box For instance - one project that didn’t use the conventions that GORM provides and tried to roll their own persistence mechanism didn’t go so well.
  • 224. I hope youquot;ve enjoyed the overview of Groovy/Grails and some thoughts to consider when choosing them
  • 226. But I’ve also been working with Groovy and Grails for almost 2 years and I’m still a happy camper.
  • 227. I encourage you to go download Groovy or download Grails and walk through the “Getting Started” tutorials - and see how these new tools can help you be more equot;ective