Groovy Grails DevJam Jam Session

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    12 Favorites

    Groovy Grails DevJam Jam Session - Presentation Transcript

    1. Groovy/Grails DevJam
    2. Act I
    3. “When you program in Groovy, in many ways you’re writing a special kind of Java.” -Dierk König Groovy in Action
    4. .groovy .java
    5. 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.
    6. 20% 80%
    7. getters and setters
    8. 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 }
    9. 1 package com.piragua.groovy 2 3 class SimpleBook { 4 String title 5 String authorName 6 }
    10. javap -private SimpleBook Compiled from \"SimpleBook.groovy\" 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); ... }
    11. javap -private SimpleBook Compiled from \"SimpleBook.groovy\" 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); ... }
    12. 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 \"<u>${title}</u> by ${authorName}, (${numberOfPages} pages)\" 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 \"<u>\" + title + \"</u> by \" + authorName + \", (\" + numberOfPages + \" pages)\"; 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 }
    13. constructor convenience http://flickr.com/photos/9229859@N02/1052409181/
    14. 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(\"Mike Hugo\"); 16 book.setTitle(\"Groovy Jam\"); 17 book.setSubTitle(\"Jammin\"); 18 book.setPublisher(\"Piragua Press\"); 19 book.setPublishDate(new Date()); 20 }
    15. 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: \"Groovy Jam\", subTitle:\"Jammin\", 9 authorName: \"Mike Hugo\", numberOfPages: 300, 10 publishDate:new Date(), publisher: \"Piragua Press\") 11 }
    16. null safe dereferencing http://flickr.com/photos/synthesisstudios/352834727/
    17. 32 public String toString() { 33 String upperCaseTitle = null; 34 if (title != null){ 35 upperCaseTitle = title.toUpperCase(); 36 } 37 return upperCaseTitle; 38 }
    18. String toString(){ title?.toUpperCase() }
    19. // more complex String toString(){ book?.publisher?.address?.city?.toUpperCase() }
    20. groovy strings http://flickr.com/photos/austinevan/416813459/
    21. // Java Example public String displayString() { return \"<u>\" + title + \"</u> by \" + authorName + \", (\" + numberOfPages + \" pages)\"; }
    22. // Java Example public String displayString() { return \"<u>\" + title + \"</u> by \" + authorName + \", (\" + numberOfPages + \" pages)\"; }
    23. String displayString() { \"<u>${title}</u> by ${authorName}, (${numberOfPages} pages)\" }
    24. String multiLineDisplayString() { \"\"\"<u>${title}</u> by ${authorName} (${numberOfPages} pages)\"\"\" }
    25. collections http://flickr.com/photos/stibbons/375342559/
    26. 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 }
    27. 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 }
    28. 8 List chapters //... 17 Chapter findChapterByTitle(String title) { 18 // finding the first item that matches criteria 19 chapters?.find({it?.title == title}) 20 }
    29. 8 List chapters //... 22 List findChaptersByTitleStartingWith(String searchKeyword) { 23 // finding all matching items 24 chapters?.findAll({it?.title?.startsWith(searchKeyword)}) 25 }
    30. 8 List chapters //... 27 void printChapterTitles() { 28 // iterating over a list 29 chapters.each {chapter -> 30 println chapter?.title 31 } 32 }
    31. duck typing http://flickr.com/photos/davidw/380277419/
    32. 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(\"username\"); 15 if (username != null) { 16 HttpSession session = request.getSession(true); 17 session.setAttribute(\"loggedInUser\", username); 18 } 19 20 } 21 } 22
    33. 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 }
    34. 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 }
    35. If we had more time... • file handling • really easy regular expressions • groovy truth • case / switch • closures • meta programming
    36. http://groovy.codehaus.org/ http://groovy.mn/
    37. Act II
    38. Web MVC Framework
    39. convention http://flickr.com/photos/markpasc/92779595
    40. configuration http://flickr.com/photos/clintjcl/169886338
    41. DRY http://flickr.com/photos/joshsommers/935470210/
    42. Development
    43. Deployment
    44. Artifacts http://flickr.com/photos/ragesoss/118620722/
    45. Artefacts http://flickr.com/photos/ragesoss/118620722/
    46. grails create-app devjam
    47. 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)
    48. 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)
    49. 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)
    50. Zero
    51. Customer class Customer { ! Address address } Address
    52. class Customer { ! static hasMany = [incidents:Incident] } Customer Incident
    53. class Customer { ! static hasMany = [products:Product] } class Product { static hasMany = [customers:Customer] static belongsTo = Customer //Customer owns the relationship } Customer Customer Product Product
    54. http://server/devjam/event/list name of application
    55. http://server/devjam/event/list name of controller
    56. http://server/devjam/event/list name of action
    57. http://server/devjam/event/list?max=10
    58. Data Binding
    59. Dependency Injection
    60. Demo
    61. If we had more time... • testing • tag libraries • services • plugins • content negotiation
    62. http://grails.org http://grails.org/doc/1.0.x/
    63. Act III
    64. http://flickr.com/photos/johnniewalker/359440369
    65. http://flickr.com/photos/philliecasablanca/2473728872
    66. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated
    67. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated
    68. http://flickr.com/photos/13010608@N02/2441101135/
    69. + +
    70. http://flickr.com/photos/kevint/85911467
    71. 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 }]
    72. http://flickr.com/photos/nengard/82039595
    73. 200,000 1 Million $250/month users page views/month VPS
    74. http://flickr.com/photos/oxygenws/39895404
    75. XYZ Thing
    76. http://flickr.com/photos/thatblondegirl/467513888
    77. Thank You
    78. 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
    79. 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)
    80. 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
    81. “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
    82. .groovy .java In fact, most of the time you can take .java file and rename it .groovy and it will compile and run
    83. Groovy and Java work seamlessly together -your java classes can reference groovy classes and groovy classes can reference java classes
    84. 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
    85. What this means is if you’re already using Java, it works with everything you already have - IDEs - Open Source Frameworks - Application Servers, etc.
    86. 20% 80% For me, it comes down to the 80/20 rule. Groovy gives me the ability to write concise code that\"s straight to the point of what I\"m trying to do. I don\"t have to include “ceremony” - code that doesn\"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...
    87. 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...
    88. 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, let\"s look at the same class in Groovy...
    89. 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 - that\"s because Groovy provides sensible defaults for these - Lets take a look at a snippet of the byte code as shown by javap
    90. javap -private SimpleBook Compiled from \"SimpleBook.groovy\" 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?
    91. javap -private SimpleBook Compiled from \"SimpleBook.groovy\" 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 - that\"s the default - attributes are private by default - methods are public by default
    92. 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 \"<u>${title}</u> by ${authorName}, (${numberOfPages} pages)\" 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 \"<u>\" + title + \"</u> by \" + authorName + \", (\" + numberOfPages + \" pages)\"; 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?
    93. constructor convenience http://flickr.com/photos/9229859@N02/1052409181/
    94. 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(\"Mike Hugo\"); 16 book.setTitle(\"Groovy Jam\"); 17 book.setSubTitle(\"Jammin\"); 18 book.setPublisher(\"Piragua Press\"); 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
    95. 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: \"Groovy Jam\", subTitle:\"Jammin\", 9 authorName: \"Mike Hugo\", numberOfPages: 300, 10 publishDate:new Date(), publisher: \"Piragua Press\") 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 - it\"s descriptive - you know what\"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?
    96. null safe dereferencing http://flickr.com/photos/synthesisstudios/352834727/
    97. 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
    98. String toString(){ title?.toUpperCase() } In Groovy, you can use the ? operator to safely traverse the tree of an object graph
    99. // 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
    100. groovy strings http://flickr.com/photos/austinevan/416813459/
    101. // Java Example public String displayString() { return \"<u>\" + title + \"</u> by \" + authorName + \", (\" + numberOfPages + \" pages)\"; } Yeck. String concatenation is evil So is using string buffer
    102. // Java Example public String displayString() { return \"<u>\" + title + \"</u> by \" + authorName + \", (\" + numberOfPages + \" pages)\"; } Yeck. String concatenation is evil So is using string buffer
    103. String displayString() { \"<u>${title}</u> by ${authorName}, (${numberOfPages} pages)\" } Groovy strings allow you to construct strings using ${} notation You can also do multi line strings
    104. String multiLineDisplayString() { \"\"\"<u>${title}</u> by ${authorName} (${numberOfPages} pages)\"\"\" } You can also do multi line strings
    105. collections http://flickr.com/photos/stibbons/375342559/
    106. 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 you\"re looking for, set it in a temp variable and break
    107. 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
    108. 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 - #it\" is an implicit parameter passed to a closure, can be named
    109. 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
    110. 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
    111. 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
    112. oh wait. you can\"t do this in java. no example here.
    113. 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(\"username\"); 15 if (username != null) { 16 HttpSession session = request.getSession(true); 17 session.setAttribute(\"loggedInUser\", username); 18 } 19 20 } 21 } 22 Here\"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,
    114. 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
    115. 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 don\"t
    116. 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
    117. 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
    118. 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-
    119. Act II So now, on to Grails...What is Grails?
    120. Web MVC Framework Grails is a Web Model/View/Controller framework
    121. that leverages the power of Groovy, Hibernate, Spring and Java
    122. convention http://flickr.com/photos/markpasc/92779595 With it you can do rapid application development by using the concepts of Convention...
    123. configuration http://flickr.com/photos/clintjcl/169886338 instead of configuration (AKA convention over configuration)
    124. 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?
    125. 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 -
    126. 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
    127. Artifacts http://flickr.com/photos/ragesoss/118620722/ Artifacts. or, if you’re british
    128. 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)
    129. 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
    130. The domain subdirectory is for any class that you want to be persistent. These classes are automatically mapped to the DB through Hibernate
    131. 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
    132. 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
    133. 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
    134. 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
    135. 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
    136. Not only are the domain classes automatically mapped to the DB, Grails adds persistent methods like .save() - inserts or updates an object
    137. .get(id) pass in the ID of a persistent object and hibernate will retrieve it
    138. .list() select * from table
    139. and last but not least, dynamic finders like “findByTitle”
    140. and you can even add criteria like ‘EventDateLessThan’
    141. how about a query using case insensitive ‘like’?
    142. or a query using HQL?
    143. or a query using criteria?
    144. 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.
    145. Customer class Customer { ! Address address } Address Associations are also supported - you can have - one to one
    146. class Customer { ! static hasMany = [incidents:Incident] } Customer Incident - one to many
    147. 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
    148. Controllers are servlets in the Grails world. Any groovy class in this directory will have a url mapping by convention - no xml config required:
    149. http://server/devjam/event/list name of application The context root of your app is the name of the application, in this case “devjam”
    150. http://server/devjam/event/list name of controller The next part of a URL is the name of the controller
    151. 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
    152. 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)
    153. 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)
    154. 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
    155. Views are GSP (grails server pages) instead of JSPs
    156. you can reference anything that is in the ‘model’ with ${} notation (like eventInstance)
    157. there’s a convention for where the views go - by default views for the “EventController” go in the “views/event” subdirectory
    158. Grails uses SiteMesh to decorate pages - so your GSPs are simple HTML
    159. that have a layout applied to them
    160. Demo Demo - build a simple Grails app to -list events (demo sca\"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)
    161. 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
    162. 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
    163. 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
    164. Act III Act III: - when should you consider using these tools in an existing environment? - greenfield environment? - Where have they worked and where haven\"t they? When should you consider using these tools in an existing environment?
    165. The first question I ask is “Are you already a Java shop?”
    166. 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...
    167. http://flickr.com/photos/philliecasablanca/2473728872 And you also have resources that understand Java
    168. If your company/client is open source friendly
    169. Then bringing Groovy into your existing environment is a piece of cake.
    170. 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
    171. 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
    172. Integrating Grails into an existing environment may not be quite as easy
    173. 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 o\"er. (See “Grails In Action” book for using Grails to map the “Legacy Database from Hell”)
    174. http://flickr.com/photos/13010608@N02/2441101135/ But where Grails really excels is in a green field
    175. + + -If your team is familiar with Hibernate and Spring -Your process includes iterative development and a fast feedback loop -And testing is important
    176. Then you should seriously be considering Grails for your next project
    177. http://flickr.com/photos/kevint/85911467 Where has it worked?
    178. 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)
    179. 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)
    180. There are tons of success stories for Grails (http://grails.org/ Success+Stories) Some very large, some smaller.
    181. 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
    182. Linked in uses Grails for some of its sites for corporate customers http://blog.linkedin.com/2008/06/11/grails-at-linkedin/
    183. Hot o\" 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
    184. http://flickr.com/photos/oxygenws/39895404 Where has it failed?
    185. 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
    186. 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.
    187. I hope you\"ve enjoyed the overview of Groovy/Grails and some thoughts to consider when choosing them
    188. http://flickr.com/photos/thatblondegirl/467513888 Obviously, I’m drinking the Koolaid
    189. But I’ve also been working with Groovy and Grails for almost 2 years and I’m still a happy camper.
    190. 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 e\"ective
    191. Thank You

    + Mike HugoMike Hugo, 10 months ago

    custom

    1764 views, 12 favs, 1 embeds more stats

    Groovy is a dynamic programming language that runs more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 1764
      • 1631 on SlideShare
      • 133 from embeds
    • Comments 0
    • Favorites 12
    • Downloads 160
    Most viewed embeds
    • 133 views on http://www.piragua.com

    more

    All embeds
    • 133 views on http://www.piragua.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories