SlideShare ist ein Scribd-Unternehmen logo
1 von 116
Downloaden Sie, um offline zu lesen
© ASERT 2006-2010




                    Groovy Tutorial
                    Scripting on the JVM
                                 Dr Paul King
                             paulk@asert.com.au
                                @paulk_asert
                               ASERT, Australia
Topics
                     Introduction
                    • Simple Data Types
                    • Collective Data Types
                    • Control Structures
                    • Closures and Builders
© ASERT 2006-2010




                    • OO
                    • GDK methods
                    • XML
                    • Database interaction
                    • Testing
                    • Metaprogramming

                                                  ESDC 2010 - 2
What is Groovy?
                    • “Groovy is like a super version
                      of Java. It can leverage Java's
                      enterprise capabilities but also
                      has cool productivity features like closures,
                      DSL support, builders and dynamic typing.”
© ASERT 2006-2010




                     Groovy = Java –   boiler plate code
                                   +   mostly dynamic typing
                                   +   closures
                                   +   domain specific languages
                                   +   builders
                                   +   metaprogramming
                                   +   GDK library
                                                                ESDC 2010 - 3
Groovy Goodies Overview
                    • Fully object oriented
                    • Closures: reusable
                      and assignable
                      pieces of code
                    • Operators can be          • GPath: efficient
                      overloaded
© ASERT 2006-2010




                                                  object navigation
                    • Multimethods              • GroovyBeans
                    • Literal declaration for   • grep and switch
                      lists (arrays), maps,
                      ranges and regular        • Templates, builder,
                      expressions                 swing, Ant, markup,
                                                  XML, SQL, XML-RPC,
                                                  Scriptom, Grails,
                                                  tests, Mocks   ESDC 2010 - 4
Growing Acceptance …
  A slow and steady start but now gaining in
  momentum, maturity and mindshare




Now free
… Growing Acceptance …
© ASERT 2006-2010




                                             ESDC 2010 - 6
… Growing Acceptance …
© ASERT 2006-2010




                     Groovy and Grails downloads:
                     70-90K per month and growing   ESDC 2010 - 7
… Growing Acceptance …
© ASERT 2006-2010




                             Source: http://www.micropoll.com/akira/mpresult/501697-116746




                                                      Source: http://www.grailspodcast.com/
                                                                                        ESDC 2010 - 8
… Growing Acceptance …
© ASERT 2006-2010




                          http://www.jroller.com/scolebourne/entry/devoxx_2008_whiteboard_votes




                                                                     http://www.java.net
                                                                                           ESDC 2010 - 9
… Growing Acceptance …
                What alternative JVM language are you using or intending to use
© ASERT 2006-2010




                                 http://www.leonardoborges.com/writings
                                                                          ESDC 2010 - 10
… Growing Acceptance …
© ASERT 2006-2010




                    http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo.com)
                                                                                                                               ESDC 2010 - 11
… Growing Acceptance …
© ASERT 2006-2010




                      http://pollpigeon.com/jsf-grails-wicket/r/25665/
                                                                         ESDC 2010 - 12
… Growing Acceptance
© ASERT 2006-2010




                                           ESDC 2010 - 13
The Landscape of JVM Languages

                                                                                                           mostly
                                                                                                          dynamic
                                                                                                            typing
© ASERT 2006-2010




                                      Dynamic features call
                                      for dynamic types                                  Java bytecode calls
                                                                                             for static types




                    The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform.
                                                                                                                ESDC 2010 - 14
Groovy Starter
                    System.out.println("Hello, World!");   // optional semicolon,
                    println 'Hello, World!'                // System.out, brackets,
                                                           // main() method, class defn

                    def name = 'Guillaume'                 // dynamic typing
                    println "$name, I'll get the car."     // GString

                    String longer = """${name}, the car
                    is in the next row."""                 // multi-line string
© ASERT 2006-2010




                                                           // with static typing

                    assert 0.5 == 1/2                      // BigDecimal equals()

                    def printSize(obj) {                   // optional duck typing
                        print obj?.size()                  // safe dereferencing
                    }

                    def pets = ['ant', 'bee', 'cat']       //   native list syntax
                    pets.each { pet ->                     //   closure support
                        assert pet < 'dog'                 //   overloading '<' on String
                    }                                      //   or: for (pet in pets)...
                                                                                    ESDC 2010 - 15
A Better Java...
                    import java.util.List;
                    import java.util.ArrayList;

                    class Erase {
                        private List removeLongerThan(List strings, int length) {    This code
                            List result = new ArrayList();
                            for (int i = 0; i < strings.size(); i++) {
                                                                                       is valid
                                String s = (String) strings.get(i);                  Java and
                                if (s.length() <= length) {
                                    result.add(s);                                  valid Groovy
                                }
                            }
© ASERT 2006-2010




                            return result;
                        }
                        public static void main(String[] args) {
                            List names = new ArrayList();
                            names.add("Ted"); names.add("Fred");
                            names.add("Jed"); names.add("Ned");
                            System.out.println(names);
                                                                                     Based on an
                            Erase e = new Erase();                                   example by
                            List shortNames = e.removeLongerThan(names, 3);          Jim Weirich
                            System.out.println(shortNames.size());
                            for (int i = 0; i < shortNames.size(); i++) {            & Ted Leung
                                String s = (String) shortNames.get(i);
                                System.out.println(s);
                            }
                        }
                    }
                                                                                          ESDC 2010 - 16
...A Better Java...
                    import java.util.List;
                    import java.util.ArrayList;

                    class Erase {
                        private List removeLongerThan(List strings, int length) {        Do the
                            List result = new ArrayList();
                            for (int i = 0; i < strings.size(); i++) {
                                                                                      semicolons
                                String s = (String) strings.get(i);                  add anything?
                                if (s.length() <= length) {
                                    result.add(s);                                   And shouldn‟t
                                }
                            }                                                         we us more
© ASERT 2006-2010




                        }
                            return result;                                            modern list
                        public static void main(String[] args) {                       notation?
                            List names = new ArrayList();
                            names.add("Ted"); names.add("Fred");                        Why not
                            names.add("Jed"); names.add("Ned");
                            System.out.println(names);
                                                                                    import common
                            Erase e = new Erase();                                     libraries?
                            List shortNames = e.removeLongerThan(names, 3);
                            System.out.println(shortNames.size());
                            for (int i = 0; i < shortNames.size(); i++) {
                                String s = (String) shortNames.get(i);
                                System.out.println(s);
                            }
                        }
                    }
                                                                                           ESDC 2010 - 17
...A Better Java...
                    class Erase {
                        private List removeLongerThan(List strings, int length) {
                            List result = new ArrayList()
                            for (String s in strings) {
                                if (s.length() <= length) {
                                    result.add(s)
                                }
                            }
                            return result
                        }

                        public static void main(String[] args) {
© ASERT 2006-2010




                            List names = new ArrayList()
                            names.add("Ted"); names.add("Fred")
                            names.add("Jed"); names.add("Ned")
                            System.out.println(names)
                            Erase e = new Erase()
                            List shortNames = e.removeLongerThan(names, 3)
                            System.out.println(shortNames.size())
                            for (String s in shortNames) {
                                System.out.println(s)
                            }
                        }
                    }




                                                                                    ESDC 2010 - 18
...A Better Java...
                    class Erase {
                        private List removeLongerThan(List strings, int length) {
                            List result = new ArrayList()
                            for (String s in strings) {
                                if (s.length() <= length) {
                                    result.add(s)
                                                                                      Do we need
                                }                                                   the static types?
                            }
                            return result                                           Must we always
                        }
                                                                                      have a main
                        public static void main(String[] args) {                       method and
© ASERT 2006-2010




                            List names = new ArrayList()
                            names.add("Ted"); names.add("Fred")                     class definition?
                            names.add("Jed"); names.add("Ned")
                            System.out.println(names)                                  How about
                            Erase e = new Erase()
                            List shortNames = e.removeLongerThan(names, 3)
                                                                                        improved
                            System.out.println(shortNames.size())                     consistency?
                            for (String s in shortNames) {
                                System.out.println(s)
                            }
                        }
                    }




                                                                                             ESDC 2010 - 19
...A Better Java...
                    def removeLongerThan(strings, length) {
                        def result = new ArrayList()
                        for (s in strings) {
                            if (s.size() <= length) {
                                result.add(s)
                            }
                        }
                        return result
                    }
© ASERT 2006-2010




                    names = new ArrayList()
                    names.add("Ted")
                    names.add("Fred")
                    names.add("Jed")
                    names.add("Ned")
                    System.out.println(names)
                    shortNames = removeLongerThan(names, 3)
                    System.out.println(shortNames.size())
                    for (s in shortNames) {
                        System.out.println(s)
                    }



                                                              ESDC 2010 - 20
...A Better Java...
                    def removeLongerThan(strings, length) {
                        def result = new ArrayList()
                        for (s in strings) {
                            if (s.size() <= length) {
                                result.add(s)                    Shouldn‟t we
                            }
                        }                                        have special
                        return result                         notation for lists?
                    }
                                                                  And special
© ASERT 2006-2010




                    names = new ArrayList()                       facilities for
                    names.add("Ted")
                    names.add("Fred")                          list processing?
                    names.add("Jed")                                Is „return‟
                    names.add("Ned")
                    System.out.println(names)                  needed at end?
                    shortNames = removeLongerThan(names, 3)
                    System.out.println(shortNames.size())
                    for (s in shortNames) {
                        System.out.println(s)
                    }



                                                                            ESDC 2010 - 21
...A Better Java...
                    def removeLongerThan(strings, length) {
                        strings.findAll{ it.size() <= length }
                    }

                    names = ["Ted", "Fred", "Jed", "Ned"]
                    System.out.println(names)
                    shortNames = removeLongerThan(names, 3)
                    System.out.println(shortNames.size())
                    shortNames.each{ System.out.println(s) }
© ASERT 2006-2010




                                                                 ESDC 2010 - 22
...A Better Java...
                    def removeLongerThan(strings, length) {
                        strings.findAll{ it.size() <= length }
                    }
                                                                  Is the method
                    names = ["Ted", "Fred", "Jed", "Ned"]         now needed?
                    System.out.println(names)
                    shortNames = removeLongerThan(names, 3)      Easier ways to
                    System.out.println(shortNames.size())          use common
                    shortNames.each{ System.out.println(s) }
                                                                    methods?
© ASERT 2006-2010




                                                                   Are brackets
                                                                 required here?




                                                                         ESDC 2010 - 23
...A Better Java...
                    names = ["Ted", "Fred", "Jed", "Ned"]
                    println names
                    shortNames = names.findAll{ it.size() <= 3 }
                    println shortNames.size()
                    shortNames.each{ println it }
© ASERT 2006-2010




                                                              ESDC 2010 - 24
...A Better Java
                    names = ["Ted", "Fred", "Jed", "Ned"]
                    println names
                    shortNames = names.findAll{ it.size() <= 3 }
                    println shortNames.size()
                    shortNames.each{ println it }
© ASERT 2006-2010




                           [Ted, Fred, Jed, Ned]
                           3
                           Ted
                           Jed
                           Ned




                                                              ESDC 2010 - 25
Better JavaBeans...
                    import java.math.BigDecimal;                                            ...

                    public class BikeJavaBean {                                             public void setModel(String model) {
                        private String manufacturer;                                            this.model = model;
                        private String model;                                               }
                        private int frame;
                        private String serialNo;                                            public int getFrame() {
                        private double weight;                                                  return frame;
                        private String status;                                              }
                        private BigDecimal cost;
                                                                                            public String getSerialNo() {
                        public BikeJavaBean(String manufacturer, String model,                  return serialNo;
                                            int frame, String serialNo,                     }
                                            double weight, String status) {
                            this.manufacturer = manufacturer;                               public void setSerialNo(String serialNo) {
                            this.model = model;                                                 this.serialNo = serialNo;
                            this.frame = frame;                                             }
                            this.serialNo = serialNo;
© ASERT 2006-2010




                            this.weight = weight;                                           public double getWeight() {
                            this.status = status;                                               return weight;
                        }                                                                   }

                        public String toString() {                                          public void setWeight(double weight) {
                            return "Bike:“ +                                                    this.weight = weight;
                                    “n    manufacturer   --   "   +   manufacturer +       }
                                    "n    model          --   "   +   model +
                                    "n    frame          --   "   +   frame +              public String getStatus() {
                                    "n    serialNo       --   "   +   serialNo +               return status;
                                    "n";                                                   }
                        }
                                                                                            public void setStatus(String status) {
                        public String getManufacturer() {                                       this.status = status;
                            return manufacturer;                                            }
                        }
                                                                                            public BigDecimal getCost() {
                        public void setManufacturer(String manufacturer) {                      return cost;
                            this.manufacturer = manufacturer;                               }
                        }
                                                                                            public void setCost(BigDecimal cost) {
                        public String getModel() {                                              this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP);
                            return model;                                                   }
                        }                                                               }
                        ...

                    Modified example from: http://www.ibm.com/developerworks/library/j-pg09196.html                                             ESDC 2010 - 26
...Better JavaBeans...
                    import java.math.BigDecimal;                                            ...

                    public class BikeJavaBean {                                             public void setModel(String model) {
                                                                                                                                              Auto
                        private String manufacturer;                                            this.model = model;
                        private String model;
                        private int frame;
                                                                                            }                                             getters?
                        private String serialNo;
                        private double weight;
                        private String status;
                                                                                            public int getFrame() {

                                                                                            }
                                                                                                return frame;                                 Auto
                        private BigDecimal cost;
                                                                                            public String getSerialNo() {
                                                                                                                                          setters?
                        public BikeJavaBean(String manufacturer, String model,                  return serialNo;
                                            int frame, String serialNo,
                                            double weight, String status) {
                                                                                            }                                                 Auto
                            this.manufacturer = manufacturer;
                            this.model = model;
                            this.frame = frame;                                             }
                                                                                                this.serialNo = serialNo;            construction?
                                                                                            public void setSerialNo(String serialNo) {


                            this.serialNo = serialNo;
© ASERT 2006-2010




                            this.weight = weight;                                           public double getWeight() {
                            this.status = status;                                               return weight;
                        }                                                                   }

                        public String toString() {                                          public void setWeight(double weight) {
                            return "Bike:“ +                                                    this.weight = weight;
                                    “n    manufacturer   --   "   +   manufacturer +       }
                                    "n    model          --   "   +   model +
                                    "n    frame          --   "   +   frame +              public String getStatus() {
                                    "n    serialNo       --   "   +   serialNo +               return status;
                                    "n";                                                   }
                        }
                                                                                            public void setStatus(String status) {
                        public String getManufacturer() {                                       this.status = status;
                            return manufacturer;                                            }
                        }
                                                                                            public BigDecimal getCost() {
                        public void setManufacturer(String manufacturer) {                      return cost;
                            this.manufacturer = manufacturer;                               }
                        }
                                                                                            public void setCost(BigDecimal cost) {
                        public String getModel() {                                              this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP);
                            return model;                                                   }
                        }                                                               }
                        ...

                                                                                                                                                ESDC 2010 - 27
... Better JavaBeans ...
                    class BikeGroovyBean {
                        String manufacturer, model, serialNo, status
                        final Integer frame
                        Double weight
                        BigDecimal cost

                          public void setCost(BigDecimal newCost) {
                              cost = newCost.setScale(3, BigDecimal.ROUND_HALF_UP)
© ASERT 2006-2010




                          }

                          public String toString() {
                              return """Bike:
                          manufacturer -- $manufacturer
                          model        -- $model            More complicated than
                          frame        -- $frame            normal because we want:
                          serialNo     -- $serialNo         * Read only frame
                    """                                     * Custom setter for cost
                          }                                 * Custom toString()
                    }
                                                                              ESDC 2010 - 28
... Better JavaBeans
                    class BikeGroovyBean {
                        String manufacturer, model, serialNo, status
                        Integer frame
                        Double weight
                        BigDecimal cost
                    }
© ASERT 2006-2010




                                                                In more typical
                                                                cases it is often
                                                                as simple as this.




                                                                             ESDC 2010 - 29
Topics
                    • Introduction
                     Simple Data Types
                         Numbers, Other 'Primitives', Strings, Regexs, Dates & Times
                    •   Collective Data Types
                    •   Control Structures
                    •
© ASERT 2006-2010




                        Closures and Builders
                    •   OO
                    •   GDK methods
                    •   XML
                    •   Database interaction
                    •   Testing
                    •   Metaprogramming
                                                                                 ESDC 2010 - 30
Numbers
                    • Java numbers          byte b1 = 42; Byte b2 = 42
                                            short s1 = 20000; Short s2 = 20000
                     – But with primitive   int i1 = 1000000000
                       types autoboxed to   Integer i2 = 1000000000
                                            def i3 = 42
                       equivalent wrapper   long l1 = 1000000000000000000
                       types                Long l2 = 1000000000000000000
                                            def l3 = 42L
                     – Sizes supported:
© ASERT 2006-2010




                       Byte, Short,         float f1 = 3.5f; Float f2 = 3.5
                       Integer, Long,       def f3 = 3.5f
                                            double d1 = 3.5e40; Double d2 = 3.5e40
                       Float, Double,       def d3 = 3.5d
                       BigInteger,          BigInteger bi = 30g
                       BigDecimal           BigDecimal bd1 = 3.5g
                                            def bd2 = 3.5
                     – Some special
                       treatment when       assert   2 instanceof Integer
                                            assert   !2.equals(4)
                       handling arrays      assert   3.5 instanceof BigDecimal
                       and in Interfaces    assert   (7/2) instanceof BigDecimal
                                                                             ESDC 2010 - 31
Parsing Strings to Numbers
                    def string = "300"
                    assert string.isNumber() // check if string appears to be a number
                    // OK, now convert to number in different ways
                    def i4 = string.toInteger()
                    def i5 = string as int
                    def i6 = string as Integer
                    def i7 = new Integer(string)
                    def i8 = Integer.parseInt(string)
                    def i9 = (int) java.text.NumberFormat.instance.parse(string) // Long
© ASERT 2006-2010




                    string   =   "300.5"
                    def n1   =   java.text.NumberFormat.instance.parse(string) // Double
                    def n2   =   string.toFloat()
                    def n3   =   string.toDouble()
                    def n4   =   string.toBigDecimal()

                    integerPattern = /^[+-]?d+$/       // regex notation
                    assert '-36' ==~ integerPattern     // explained later
                    assert !('abc' =~ integerPattern)
                    decimalPattern = /^-?(?:d+(?:.d*)?|.d+)$/
                    assert '37.5' ==~ decimalPattern

                                                                                    ESDC 2010 - 32
Other 'primitive' types
                    • boolean and char
                      – Again replaced by wrapper counterparts
                        automatically
                      – We'll see a little bit more about chars under Strings
                      – There is a notion called 'Groovy Truth' whereby any
                        expression can be used where Java would require a
© ASERT 2006-2010




                        boolean and the expression will be evaluated
                         • The numbers 0 and 0.0 and null objects return false
                         • Empty Strings, Lists, Maps, Matchers, ... return false
                         • Other objects return true
                                                                        Found 4 vowels:
             def vowels = 'aeiou'                                       [e, i, o, u]
             def sentences = ['The quick brown fox', 'Flyby']           Nothing found
             sentences.each { sentence ->
                 def found = sentence.toList().intersect(vowels.toList())
                 if (found) println "Found ${found.size()} vowels: $found"
                 else println 'Nothing found'
             }                                                                      ESDC 2010 - 33
Strings...
                    • Several forms            // normal strings
                                               def firstname = 'Kate'
                     – Single quotes for       assert firstname instanceof String
                       simple strings          def surname = "Bush"
                                               assert firstname * 2 == 'KateKate'
                     – Double quotes for       def fullname =
                       GStrings which              firstname + ' ' + surname
                                               assert fullname == 'Kate Bush'
                       support variable
© ASERT 2006-2010




                       expansion               // GString
                                               fullname = "$firstname $surname"
                     – Slashy strings          assert fullname instanceof GString
                       behave like             assert fullname == 'Kate Bush'
                       GStrings but            assert fullname - firstname == ' Bush'
                                               assert fullname.padLeft(10) ==
                       preserve                                          ' Kate Bush'
                       backslashes (great
                       for regex and           // indexing (including ranges)
                                               assert fullname[0..3] == firstname
                       directory names)        assert fullname[-4..-1] == surname
                     – Multi-line versions     assert fullname[5, 3..1] == 'Beta'
                                                                              ESDC 2010 - 34
…Strings…
                    // Multi-line strings
                    def tt = '''                   def lines = tt.split('n')
                    She sells, sea shells           assert lines.size() == 2
                    By the sea shore'''             lines = address.readLines()
                                                    assert lines.size() == 3
                    assert   tt instanceof String   assert lines[-1] == 'New York'
                    assert   tt.startsWith('She')
                    assert   tt.endsWith('shore')   // slashy string: (almost) no escaping
                    assert   tt.contains('n')      def path = /C:WindowsSystem32/
© ASERT 2006-2010




                    def address = """               def plain = 'nrtbf$'
                    $fullname                       assert plain.size() == 7
                    123 First Ave                   def slashy = /nrtbf$/
                    New York                        assert slashy.size() == 14
                    """.trim()
                                                    // late binding trick with closures
                    println """                    fullname = "${-> firstname} $surname"
                     ---------------------          assert fullname == 'Kate Bush'
                    |    $fullname        |         firstname = 'George'
                    |    123 First Ave    |         surname = 'Clooney'
                    |    New York         |         assert fullname == 'George Bush'
                     --------------------- """
                                                                                     ESDC 2010 - 35
…Strings...
                    // more substrings (minus removes first occurrence)
                    string = 'hippopotamus'
                    assert string - 'hippo' - 'mus' + 'to' == 'potato'
                    assert string.replace('ppopotam','bisc') == 'hibiscus'

                    // processing characters (more on collections later)
                    def letters = 'apple'.toList()
                    assert letters == ['a', 'p', 'p', 'l', 'e']
© ASERT 2006-2010




                    assert letters[0] instanceof String

                    letters = 'apple'.toList()*.toCharacter()
                    def expected = ['a', 'p', 'p', 'l', 'e'] as char[]
                    assert letters == expected
                    assert letters[0] instanceof Character
                    assert letters instanceof List
                    assert expected instanceof char[]

                    string = "an apple a day"
                    assert string.toList().unique().sort().join() == ' adelnpy'
                                                                             ESDC 2010 - 36
…Strings...
                    // reversing chars/words
                    assert 'string'.reverse() == 'gnirts'
                    assert 'two words'.split().reverse().join(' ') == 'words two'

                    string = 'Yoda said, "can you see this?"'
                    revwords = string.split(' ').reverse().join(' ')
                    assert revwords == 'this?" see you "can said, Yoda'
© ASERT 2006-2010




                    revwords = string.replaceAll(/(w*)/) {
                        all, match -> match.reverse() }
                    assert revwords == 'adoY dias, "nac uoy ees siht?"'

                    revwords = string.replaceAll(/(w*) (w*)(W*)/ * 3,
                        '$2 $1$3$8 $7$6$5 $4$9')
                    assert revwords == 'said Yoda, "this see you can?"'


                    • Find out more through Javadoc, GDK doc
                       – Can also lookup GString but usually no need
                                                                           ESDC 2010 - 37
…Strings...
                    • javadoc
© ASERT 2006-2010




                                              ESDC 2010 - 38
…Strings
                    • groovy-jdk (just the additions)
© ASERT 2006-2010




                                                        ESDC 2010 - 39
Regular Expressions...
                    assert "Hello World!" =~ /Hello/       // Find operator
                    assert "Hello World!" ==~ /Hellob.*/ // Match operator
                    def p = ~/Hellob.*/                   // Pattern operator
                    assert p.class.name == 'java.util.regex.Pattern'

                    def input = "Voting is open between 01 Nov 2008 and 04 Nov 2008"
                    def dateFormat = /dd? ... d{4}/
                    def matches = (input =~ dateFormat)
© ASERT 2006-2010




                    assert matches[1] == '04 Nov 2008'
                                                                            01 Nov 2008
                    matches.each { m -> println m }                         04 Nov 2008

                    input.eachMatch(dateFormat) { m -> println m }

                    assert input.findAll(dateFormat) == ['01 Nov 2008', '04 Nov 2008']

                    println input.replaceAll(dateFormat, '?/?/?')

                                               Voting is open between ?/?/? and ?/?/?


                                                                                 ESDC 2010 - 40
...Regular Expressions
                    // "Voting is open between 01 Nov 2008 and 04 Nov 2008"
                    def dateFormatGroups = /(dd?) (...) (d{4})/
                    def matchingGroups = (input =~ dateFormatGroups)

                    assert matchingGroups[1][1] == '04'

                    matchingGroups.each { all, d, m, y -> println "$d/$m/$y" }
© ASERT 2006-2010




                    input.eachMatch(dateFormatGroups) { all, d, m, y ->
                        println "$d/$m/$y"
                    }                                                01/Nov/2008
                                                                         04/Nov/2008
                    assert input.findAll(dateFormatGroups) {
                        full, d, m, y -> "$m $d of $y"
                    } == ['Nov 01 of 2008', 'Nov 04 of 2008']

                    println input.replaceAll(dateFormatGroups) {
                        full, d, m, y -> "$m $d ????"
                    }               Voting is open between Nov 01 ???? and Nov 04 ????
                                                                              ESDC 2010 - 41
Abbreviated regex notation
                    Symbol      Meaning
                    .           Any character
                    ^           Start of line (or start of document, when in single-line mode)
                    $           End of line (or end of document, when in single-line mode)
                    d          Digit character
                    D          Any character except digits
                    s          Whitespace character
                    S          Any character except whitespace
                    w          Word character
© ASERT 2006-2010




                    W          Any character except word characters
                    b          Word boundary
                    ()          Grouping
                    (x|y)       x or y as in (Groovy|Java|Ruby)
                    x*          Zero or more occurrences of x
                    x+          One or more occurrences of x
                    x?          Zero or one occurrence of x
                    x{m,n}      At least m and at most n occurrences of x
                    x{m}        Exactly m occurrences of x
                    [a-f]       Character class containing the characters a, b, c, d, e, f
                    [^a]        Character class containing any character except a
                    (?=regex)   Positive lookahead
                    (?<=text)   Positive lookbehind
                                                                                                 ESDC 2010 - 42
Dates...
                    • Similar to Java
                      – Use java.util.Date, java.util.Calendar, java.sql.Date, ...
                      – Can use static imports to help
                      – Or 3rd party package like Joda Time
                    • Special support for changing times:
© ASERT 2006-2010




                      date2 = date1 + 1                // day
                      date2 = date1 + 1.week – 3.days + 6.hours
                    • Utility methods for date input and output
                      – Date.parse(formatString, dateString)
                      – date.format(formatString)
                      – date.timeString, date.dateString, date.dateTimeString
                    • Potentially will change with JSR 310
                                                                            ESDC 2010 - 43
... Dates...
                    import static java.util.Calendar.getInstance as now
                    import java.util.GregorianCalendar as D
                    import org.codehaus.groovy.runtime.TimeCategory

                    println new D(2007,11,25).time
                    println now().time             Tue Dec 25 00:00:00 EST   2007
                                                   Thu Jun 28 10:10:34 EST   2007
                    def date = new Date() + 1      Fri Jun 29 10:10:35 EST   2007
© ASERT 2006-2010




                    println date                   Tue Jul 17 11:10:35 EST   2007
                                                   Date was Jun/03/1998
                    use(TimeCategory) {
                        println new Date() + 1.hour + 3.weeks - 2.days
                    }

                    dateStr = "1998-06-03"
                    date = Date.parse("yyyy-MM-dd", dateStr)
                    println 'Date was ' + date.format("MMM/dd/yyyy")

                    def holidays = boxingDay..newYearsEve
                                                                          ESDC 2010 - 44
... Dates
                    import static java.util.Calendar.*
                    def nowCal = Calendar.instance
                    y = nowCal.get(YEAR)
                    Date nowDate = nowCal.time
                    def (m, d) = [nowDate[MONTH] + 1, nowDate[DATE]]
                    println "Today is $d $m $y"
                    nowCal.set DATE, 1
                    nowCal.set MONTH, FEBRUARY
                    println "Changed to $nowCal.time"
© ASERT 2006-2010




                      Today is 26 9 2008
                      Changed to Fri Feb 01 23:05:20 EST 2008

                    cal = Calendar.instance
                    cal.set 1988, APRIL, 4, 0, 0, 0
                    date = cal.time
                    def (doy, woy, y) = [DAY_OF_YEAR, WEEK_OF_YEAR,
                                         YEAR].collect{ date[it] }
                    println "$date is day $doy and week $woy of year $y"

      Mon Apr 04 00:00:00 EST 1988 is day 95 and week 15 of year 1988
                                                                           ESDC 2010 - 45
Operator Overloading...
© ASERT 2006-2010




                                              ESDC 2010 - 46
...Operator Overloading...
© ASERT 2006-2010




                                                 ESDC 2010 - 47
...Operator Overloading
© ASERT 2006-2010




                    • Can be used with your own types too
                           shoppingCart << clickedItem
                                                            ESDC 2010 - 48
Topics
                    • Introduction
                    • Simple Data Types
                     Collective Data Types
                    • Control Structures
                    • Closures and Builders
© ASERT 2006-2010




                    • OO
                    • GDK methods
                    • XML
                    • Database interaction
                    • Testing
                    • Metaprogramming

                                                 ESDC 2010 - 49
Better Lists, Maps, Ranges
                    • Lists/Collections
                      – Special literal syntax
                      – Additional common methods (operator overloading)
                             def list = [3, new Date(), 'Jan']
                             assert list + list == list * 2

                    • Maps
© ASERT 2006-2010




                      – Special literal syntax & GDK methods
                             def map = [a: 1, b: 2]
                             assert map['a'] == 1 && map.b == 2

                    • Ranges
                      – Special syntax for various kinds of ranges
                      def letters = 'a'..'z'
                      def numbers = 0..<10
                      assert letters.size() + numbers.size() == 36
                                                                     ESDC 2010 - 50
Topics
                    • Introduction
                    • Simple Data Types
                    • Collective Data Types
                     Control Structures
                    • Closures and Builders
© ASERT 2006-2010




                    • OO
                    • GDK methods
                    • XML
                    • Database interaction
                    • Testing
                    • Metaprogramming

                                                  ESDC 2010 - 51
Better Control Structures: Branching/Loops
                    • Branching and loops                • Loop-like Closures
                     for (int i = 0; i < n; i++) { }      myMap.each { key, value ->
                     for (Type item : iterable) { }           println "$key : $value"
                     for (item in iterable) { }           }

                     //   if (condition) ...              //   each, every, collect, any,
                     //   else if (condition) ...         //   inject, find, findAll,
                     //   else ...                        //   upto, downto, times, grep,
© ASERT 2006-2010




                     //   throw, try...catch...finally    //   reverseEach, eachMatch,
                     //   for, while                      //   eachWithIndex, eachLine
                     //   d = a ? b : c                   //   eachFile, eachFileMatch,
                     //   a = b ?: c                      //   eachByte, combinations ...
                     //   d = a?.b?.c

                    • Groovy Truth                words = ['bob', 'alpha', 'ehcache',
                     if   (1) // ...                  'rotator', 'omega', 'reviver']
                     if   (object) // ...         bigPalindromes = words.findAll{ w ->
                     if   (collection) // ...         w == w.reverse() && w.size() > 4}
                     if   (map) // ...            assert bigPalindromes ==
                     if   (matcher) // ...            ['ehcache', 'rotator', 'reviver']
                                                                                  ESDC 2010 - 52
Better Control Structures: Switch

                             switch (10) {
                                case 0           : assert   false   ;   break
                                case 0..9        : assert   false   ;   break
                                case [8,9,11]    : assert   false   ;   break
                                case Float       : assert   false   ;   break
                                case {it%3 == 0} : assert   false   ;   break
                                case ~/../       : assert   true    ;   break
© ASERT 2006-2010




                                default          : assert   false   ;   break
                             }




                    • Extensible
                      – Implement your own isCase() method



                                                                                ESDC 2010 - 53
Topics
                    • Introduction
                    • Simple Data Types
                    • Collective Data Types
                    • Control Structures
                     Closures and Builders
© ASERT 2006-2010




                    • OO
                    • GDK methods
                    • XML
                    • Database interaction
                    • Testing
                    • Metaprogramming

                                                ESDC 2010 - 54
Using Closures...
                    • Traditional mainstream languages
                      – Data can be stored in variables, passed around,
                        combined in structured ways to form more complex
                        data; code stays put where it is defined
                    • Languages supporting closures
                      – Data and code can be stored in variables, passed
© ASERT 2006-2010




                        around, combined in structured ways to form more
                        complex algorithms and data
                        doubleNum = { num -> num * 2 }
                        println doubleNum(3) // => 6

                        processThenPrint = { num, closure ->
                            num = closure(num); println "num is $num"
                        }
                        processThenPrint(3, doubleNum)    // => num is 6
                        processThenPrint(10) { it / 2 }   // => num is 5
                                                                           ESDC 2010 - 55
...Using Closures...
                    import static Math.*                Algorithm   piE   differs   by   1.0206946399193839E-11
                                                        Algorithm   piF   differs   by   1.0070735356748628E-9
                                                        Algorithm   piC   differs   by   2.668102068170697E-7
                    piA   =   {   22 / 7 }              Algorithm   piD   differs   by   4.813291008076703E-5
                    piB   =   {   333/106 }             Algorithm   piB   differs   by   8.321958979307098E-5
                    piC   =   {   355/113 }             Algorithm   piA   differs   by   0.001264489310206951
                    piD   =   {   0.6 * (3 + sqrt(5)) }
                    piE   =   {   22/17 + 37/47 + 88/83 }
                    piF   =   {   sqrt(sqrt(2143/22)) }
© ASERT 2006-2010




                    howCloseToPI = { abs(it.value() - PI) }

                    algorithms = [piA:piA, piB:piB, piC:piC,
                                  piD:piD, piE:piE, piF:piF]

                    findBestPI(algorithms)

                    def findBestPI(map) {
                        map.entrySet().sort(howCloseToPI).each { entry ->
                            def diff = howCloseToPI(entry)
                            println "Algorithm $entry.key differs by $diff"
                        }
                    }
                                                                                                     ESDC 2010 - 56
...Using Closures...
                    • Used for many things in Groovy:
                       •   Iterators                  new File('/x.txt').eachLine     {
                                                          println it
                       •   Callbacks                  }
                       •   Higher-order functions
                       •   Specialized control structures
                       •   Dynamic method definition
© ASERT 2006-2010




                       •   Resource allocation       3.times { println 'Hi' }
                       •   Threads
                                                     [0, 1, 2].each { number ->
                       •   Continuations                 println number
                                                       }
                    def houston(Closure doit) {
                        (10..1).each { count ->        [0, 1, 2].each { println it}
                            doit(count)
                        }                              def printit = { println it }
                    }                                  [0, 1, 2].each printit
                    houston { println it }
                                                                                ESDC 2010 - 57
...Using Closures...

                    map = ['a': 1, 'b': 2]
                    map.each {key, value -> map[key] = value * 2}
                    assert map == ['a': 2, 'b': 4]

                    doubler = {key, value -> map[key] = value * 2}
                    map.each(doubler)
© ASERT 2006-2010




                    assert map == ['a': 4, 'b': 8]

                    def doubleMethod(entry) {
                        map[entry.key] = entry.value * 2
                    }
                    doubler = this.&doubleMethod
                    map.each(doubler)
                    assert map == ['a': 8, 'b': 16]

                                                               ESDC 2010 - 58
...Using Closures...
                    assert [1, 2, 3].grep{ it < 3 } == [1, 2]
                    assert [1, 2, 3].any{ it % 2 == 0 }
                    assert [1, 2, 3].every{ it < 4 }
                    assert (1..9).collect{it}.join() == '123456789'
                    assert (1..4).collect{it * 2}.join() == '2468'
                    def add = { x, y -> x + y }
© ASERT 2006-2010




                    def mult = { x, y -> x * y }
                    assert add(1, 3) == 4
                    assert mult(1, 3) == 3
                    def min = { x, y -> [x, y].min() }
                    def max = { x, y -> [x, y].max() }
                    def triple = mult.curry(3); assert triple(2) == 6
                    def atLeastTen = max.curry(10)
                    assert atLeastTen(5) == 10
                    assert atLeastTen(15) == 15
                                                                 ESDC 2010 - 59
...Using Closures
                    def pairWise(list, Closure invoke) {
                        if (list.size() < 2) return []
                        def next = invoke(list[0], list[1])
                        return [next] + pairWise(list.tail(), invoke)
                    }
© ASERT 2006-2010




                    // using min, max, etc. From previous   slide
                    assert pairWise(1..5, add) == [3, 5,    7, 9]
                    assert pairWise(1..5, mult) == [2, 6,   12, 20]
                    assert pairWise(1..5, min) == [1, 2,    3, 4]
                    assert pairWise(1..5, max) == [2, 3,    4, 5]

                    assert 'cbaxabc' == ['a', 'b', 'c'].inject('x') {
                        result, item -> item + result + item
                    }
                                                                  ESDC 2010 - 60
Better Design Patterns: Builder
                    • Markup Builder

                                                     <html>
                    import groovy.xml.*
                                                       <head>
                    def page = new MarkupBuilder()
                                                         <title>Hello</title>
                    page.html {
                                                       </head>
                      head { title 'Hello' }
                                                       <body>
                      body {
© ASERT 2006-2010




                                                         <ul>
                        ul {
                                                            <li>world 1</li>
                          for (count in 1..5) {
                                                            <li>world 2</li>
                             li "world $count"
                                                            <li>world 3</li>
                    } } } }
                                                            <li>world 4</li>
                                                            <li>world 5</li>
                                                         </ul>
                                                       </body>
                                                     </html>


                                                                        ESDC 2010 - 61
SwingBuilder
                    import java.awt.FlowLayout
                    builder = new groovy.swing.SwingBuilder()
                    langs = ["Groovy", "Ruby", "Python", "Pnuts"]

                    gui = builder.frame(size: [290, 100],
                               title: 'Swinging with Groovy!') {
                        panel(layout: new FlowLayout()) {
                            panel(layout: new FlowLayout()) {
                                 for (lang in langs) {
© ASERT 2006-2010




                                     checkBox(text: lang)
                                 }
                            }
                            button(text: 'Groovy Button', actionPerformed: {
                                 builder.optionPane(message: 'Indubitably Groovy!').
                                     createDialog(null, 'Zen Message').show()
                            })
                            button(text: 'Groovy Quit',
                                     actionPerformed: {System.exit(0)})
                        }
                    }
                    gui.show()
                     Source: http://www.ibm.com/developerworks/java/library/j-pg04125/
                                                                                         ESDC 2010 - 62
SwingXBuilder




                    import groovy.swing.SwingXBuilder
© ASERT 2006-2010




                    import static java.awt.Color.*
                    import static java.lang.Math.*

                    def swing = new SwingXBuilder()
                    def frame = swing.frame(size: [300, 300]) {
                        graph(plots: [
                             [GREEN, {value -> sin(value)}],
                             [BLUE, {value -> cos(value)}],
                             [RED,   {value -> tan(value)}]
                        ])
                    }.show()
                                                                  ESDC 2010 - 63
GraphicsBuilder

                    def colors = ['red','darkOrange','blue','darkGreen']
                    (0..3).each { index ->
                      star( cx: 50 + (index*110), cy: 50, or: 40, ir: 15,
                        borderColor: 'black', count: 2+index, fill: colors[index] )
                      star( cx: 50 + (index*110), cy: 140, or: 40, ir: 15,
                        borderColor: 'black‘, count: 7+index, fill: colors[index] )
                    }
© ASERT 2006-2010




                                                                              ESDC 2010 - 64
AntBuilder...
                    def ant = new AntBuilder()

                    ant.echo("hello")    // let's just call one task

                    // create a block of Ant using the builder pattern
                    ant.sequential {
                        myDir = "target/AntTest/"
                        mkdir(dir: myDir)
© ASERT 2006-2010




                        copy(todir: myDir) {
                            fileset(dir: "src/test") {
                                include(name: "**/*.groovy")
                            }
                        }
                        echo("done")
                    }

                    // now let's do some normal Groovy again
                    file = new File("target/test/AntTest.groovy")
                    assert file.exists()
                                                                         ESDC 2010 - 65
...AntBuilder
                    def ant = new AntBuilder()
                    ant.echo(file:'Temp.java', '''
                    class Temp {
                       public static void main(String[] args) {
                         System.out.println("Hello");
                       }
                    }
© ASERT 2006-2010




                    ''')
                    ant.with {
                       javac(srcdir:'.', includes:'Temp.java', fork:'true')
                       java(classpath:'.', classname:'Temp', fork:'true')
                       echo('Done')
                    }
                    // =>
                    //     [javac] Compiling 1 source file
                    //      [java] Hello
                    //      [echo] Done

                                                                        ESDC 2010 - 66
Using AntLibs: Maven Ant Tasks & AntUnit
                     import static groovy.xml.NamespaceBuilder.newInstance as namespace
                     def ant = new AntBuilder()
                     def mvn = namespace(ant, 'antlib:org.apache.maven.artifact.ant')
                     def antunit = namespace(ant, 'antlib:org.apache.ant.antunit')

                     direct = [groupId:'jfree', artifactId:'jfreechart', version:'1.0.9']
                     indirect = [groupId:'jfree', artifactId:'jcommon', version:'1.0.12']

                     // download artifacts
© ASERT 2006-2010




                     mvn.dependencies(filesetId:'artifacts') { dependency(direct) }

                     // print out what we downloaded
                     ant.fileScanner { fileset(refid:'artifacts') }.each { println it }

                     // use AntUnit to confirm expected files were downloaded
                     def prefix = System.properties.'user.home' + '/.m2/repository'
                     [direct, indirect].each { item ->
                         def (g, a, v) = [item.groupId, item.artifactId, item.version]
                         antunit.assertFileExists(file:"$prefix/$g/$a/$v/$a-${v}.jar")
                     }
                    C:Userspaulk.m2repositoryjfreejcommon1.0.12jcommon-1.0.12.jar
                    C:Userspaulk.m2repositoryjfreejfreechart1.0.9jfreechart-1.0.9.jar
                                                                                                ESDC 2010 - 67
Topics
                    • Introduction
                    • Simple Data Types
                    • Collective Data Types
                    • Control Structures
                    • Closures and Builders
© ASERT 2006-2010




                     OO
                    • GDK methods
                    • XML
                    • Database interaction
                    • Testing
                    • Metaprogramming

                                                  ESDC 2010 - 68
Object Orientation
                    • Similar capabilities to Java
                      – Define classes, interfaces, enums, annotations
                    • Differences to Java
                      –   Classes (and interfaces etc.) public by default
                      –   Methods public by default
                      –
© ASERT 2006-2010




                          Property support within classes (auto-setters/getters)
                      –   Multimethods (runtime dispatch – "duck typing")

                       class BikeGroovyBean {
                           String manufacturer, model, serialNo, status
                           Integer frame
                           Double weight
                           BigDecimal cost
                       }


                                                                          ESDC 2010 - 69
Object Orientation – Runtime Interfaces
                     – Java has these methods in java.util.Collections:




                     – In Groovy, no need to create a class implementing
                       Comparator having a compare method, just use a map
© ASERT 2006-2010




                       of Closures instead (though Groovy has special support
                       for this example which is even more concise):
                    def animals = ['Antelope', 'Bee', 'Zebra']
                    def comparator = [
                        compare:{ a, b -> a.size() <=> b.size() }
                    ] as Comparator
                    assert comparator instanceof Comparator
                    assert Collections.min(animals, comparator) == 'Bee'
                    assert Collections.max(animals, comparator) == 'Antelope'
                                                                        ESDC 2010 - 70
Topics
                    • Introduction
                    • Simple Data Types
                    • Collective Data Types
                    • Control Structures
                    • Closures and Builders
© ASERT 2006-2010




                    • OO
                     GDK methods
                    • XML
                    • Database interaction
                    • Testing
                    • Metaprogramming

                                                  ESDC 2010 - 71
Better File Manipulation...
                    import   java.util.List;
                    import   java.util.ArrayList;
                    import   java.util.Arrays;
                    import   java.io.File;                                                   // ...
                    import   java.io.FileOutputStream;                                       private static void processFile(File file, PrintWriter out) {
                    import   java.io.PrintWriter;                                                FileInputStream fis = null;
                    import   java.io.FileNotFoundException;                                      InputStreamReader isr = null;
                    import   java.io.IOException;                                                BufferedReader reader = null;
                    import   java.io.BufferedReader;                                             try {
                    import   java.io.InputStreamReader;                                              fis = new FileInputStream(file);
                    import   java.io.FileInputStream;                                                isr = new InputStreamReader(fis);
                                                                                                     reader = new BufferedReader(isr);
                    public class PrintJavaSourceFileLinesThatContainTheWordJava {                    String nextline;
                        public static void main(String[] args) {                                     int count = 0;
                            File outfile = new File("result.txt");                                   while ((nextline = reader.readLine()) != null) {
                            outfile.delete();                                                            count++;
                            File basedir = new File("..");                                               if (nextline.toLowerCase().contains("java")) {
                            List<File> files = new ArrayList<File>();                                        out.println("File '" + file +
                            files.add(basedir);                                                                           "' on line " + count);
© ASERT 2006-2010




                            FileOutputStream fos = null;                                                     out.println(nextline);
                            PrintWriter out = null;                                                          out.println();
                            try {                                                                        }
                                fos = new FileOutputStream(outfile);                                 }
                                out = new PrintWriter(fos);                                      } catch (FileNotFoundException e) {
                                while (!files.isEmpty()) {                                           e.printStackTrace();
                                    File file = files.remove(0);                                 } catch (IOException e) {
                                    if (file.isDirectory()) {                                        e.printStackTrace();
                                        files.addAll(Arrays.asList(file.listFiles()));           } finally {
                                    } else {                                                         if (reader != null) {
                                        if (file.getName().endsWith(".java")) {                          try { reader.close(); }
                                             processFile(file, out);                                     catch (IOException e) { e.printStackTrace(); }
                                        }                                                            }
                                    }                                                                if (isr != null) {
                                }                                                                        try { isr.close(); }
                            } catch (FileNotFoundException e) {                                          catch (IOException e) { e.printStackTrace(); }
                                e.printStackTrace();                                                 }
                            } finally {                                                              if (fis != null) {
                                if (out != null) { out.close(); }                                        try { fis.close(); }
                                if (fos != null) {                                                       catch (IOException e) { e.printStackTrace(); }
                                    try { fos.close(); }                                             }
                                    catch (IOException e) { e.printStackTrace(); }               }
                                }                                                            }
                            }                                                            }
                        }
                        // ...
                                                                                                                                           ESDC 2010 - 72
...Better File Manipulation...
                    import   java.util.List;
                    import
                    import
                             java.util.ArrayList;
                             java.util.Arrays;
                                                                                                                                    boilerplate
                    import   java.io.File;                                                   // ...
                    import   java.io.FileOutputStream;                                       private static void processFile(File file, PrintWriter out) {
                    import   java.io.PrintWriter;                                                FileInputStream fis = null;
                    import   java.io.FileNotFoundException;                                      InputStreamReader isr = null;
                    import   java.io.IOException;                                                BufferedReader reader = null;
                    import   java.io.BufferedReader;                                             try {
                    import   java.io.InputStreamReader;                                              fis = new FileInputStream(file);
                    import   java.io.FileInputStream;                                                isr = new InputStreamReader(fis);
                                                                                                     reader = new BufferedReader(isr);
                    public class PrintJavaSourceFileLinesThatContainTheWordJava {                    String nextline;
                        public static void main(String[] args) {                                     int count = 0;
                            File outfile = new File("result.txt");                                   while ((nextline = reader.readLine()) != null) {
                            outfile.delete();                                                            count++;
                            File basedir = new File("..");                                               if (nextline.toLowerCase().contains("java")) {
                            List<File> files = new ArrayList<File>();                                        out.println("File '" + file +
                            files.add(basedir);                                                                           "' on line " + count);
© ASERT 2006-2010




                            FileOutputStream fos = null;                                                     out.println(nextline);
                            PrintWriter out = null;                                                          out.println();
                            try {                                                                        }
                                fos = new FileOutputStream(outfile);                                 }
                                out = new PrintWriter(fos);                                      } catch (FileNotFoundException e) {
                                while (!files.isEmpty()) {                                           e.printStackTrace();
                                    File file = files.remove(0);                                 } catch (IOException e) {
                                    if (file.isDirectory()) {                                        e.printStackTrace();
                                        files.addAll(Arrays.asList(file.listFiles()));           } finally {
                                    } else {                                                         if (reader != null) {
                                        if (file.getName().endsWith(".java")) {                          try { reader.close(); }
                                             processFile(file, out);                                     catch (IOException e) { e.printStackTrace(); }
                                        }                                                            }
                                    }                                                                if (isr != null) {
                                }                                                                        try { isr.close(); }
                            } catch (FileNotFoundException e) {                                          catch (IOException e) { e.printStackTrace(); }
                                e.printStackTrace();                                                 }
                            } finally {                                                              if (fis != null) {
                                if (out != null) { out.close(); }                                        try { fis.close(); }
                                if (fos != null) {                                                       catch (IOException e) { e.printStackTrace(); }
                                    try { fos.close(); }                                             }
                                    catch (IOException e) { e.printStackTrace(); }               }
                                }                                                            }
                            }                                                            }
                        }
                        // ...
                                                                                                                                           ESDC 2010 - 73
...Better File Manipulation
                    def out = new File('result.txt')
                    out.delete()
                    new File('..').eachFileRecurse {file ->
                      if (file.name.endsWith('.groovy')) {
                        file.eachLine { line, num ->
                          if (line.toLowerCase().contains('groovy'))
                             out <<
© ASERT 2006-2010




                                "File '$file' on line $numn$linenn"
                        }
                      }
                    } File '..filessrcPrintGroovySourceLines.groovy' on line 4
                          if (file.name.endsWith('.groovy')) {

                        File '..filessrcPrintGroovySourceLines.groovy' on line 6
                              if (line.toLowerCase().contains('groovy'))

                        File '..jdbcsrcJdbcGroovy.groovy' on line 1
                        import groovy.sql.Sql
                        …
                                                                                      ESDC 2010 - 74
Better Process Management...
                    // windows version (minimal error/output)
                    def p = "cmd /c dir *.xml".execute()
                    p.waitFor()
                    if (p.exitValue()) println p.err.text
                    else println p.text
                                                        ----- stdout -----
                                                        Volume in drive D is DATA
                                                        Volume Serial Number is FC5C-B39D
© ASERT 2006-2010




                                                        Directory of D:svntrunk-groovygroovy-core
                    // unix version
                                                  27/06/2009 10:13 AM          38,478 build.xml
                    def p = "ls *.xml".execute() 29/06/2009 06:53 PM           27,617 pom.xml
                    def err = new StringBuffer()           2 File(s)          66,095 bytes
                                                           0 Dir(s) 15,503,597,568 bytes free
                    def out = new StringBuffer()
                    // could ignore/use Stream below       ----- stderr -----
                                                           Return Code: 1
                    p.consumeProcessOutput(out, err)       ls: *.xml: No such file or directory
                    def exitValue = p.waitFor()
                    if (err) println """----- stderr -----
                    Return Code: $exitValue
                    $err"""
                    if (out) println "----- stdout -----n$out"
                                                                                            ESDC 2010 - 75
...Better Process Management
                                                      sout: tstfl.grvy
                                                      serr:

                    def sout = new StringBuffer()
                    def serr = new StringBuffer()
                    proc1 = 'tr -d o'.execute()
                    proc2 = 'tr -d e'.execute()
© ASERT 2006-2010




                    proc3 = 'tr -d i'.execute()
                    proc3.consumeProcessOutput(sout, serr)
                    proc1 | proc2 | proc3
                    [proc1, proc2].each{ it.consumeProcessErrorStream(serr) }
                    proc1.withWriter { writer ->
                        writer << 'testfile.groovy'
                    }
                    proc3.waitForOrKill(1000)
                    println 'sout: ' + sout
                    println 'serr: ' + serr

                                                                          ESDC 2010 - 76
Better Thread Management
                    Thread.start{                        Hello   from   thread 2
                      4.times {                          Hello   from   thread 1
                        println 'Hello from thread 1'    Hello   from   main thread
                        sleep 400                        Hello   from   main thread
                      }                                  Hello   from   thread 2
                    }                                    Hello   from   thread 1
                    Thread.start{                        Hello   from   main thread
© ASERT 2006-2010




                      5.times {                          Hello   from   thread 2
                        println 'Hello from thread 2'    Hello   from   main thread
                        sleep 300                        Hello   from   thread 1
                      }                                  Hello   from   main thread
                    }                                    Hello   from   thread 2
                    7.times {                            Hello   from   main thread
                      println 'Hello from main thread'   Hello   from   thread 2
                      sleep 200                          Hello   from   thread 1
                    }                                    Hello   from   main thread


                                                                             ESDC 2010 - 77
Topics
                    • Introduction
                    • Simple Data Types
                    • Collective Data Types
                    • Control Structures
                    • Closures and Builders
© ASERT 2006-2010




                    • OO
                    • GDK methods
                     XML
                    • Database interaction
                    • Testing
                    • Metaprogramming

                                                  ESDC 2010 - 78
Better XML Manipulation...


                    <records>                                                                     records.xml
                       <car name='HSV Maloo' make='Holden' year='2006'>
                         <country>Australia</country>
                         <record type='speed'>Production Pickup Truck with speed of 271kph</record>
                       </car>
© ASERT 2006-2010




                       <car name='P50' make='Peel' year='1962'>
                         <country>Isle of Man</country>
                         <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg weight</record>
                       </car>
                       <car name='Royale' make='Bugatti' year='1931'>
                         <country>France</country>
                         <record type='price'>Most Valuable Car at $15 million</record>
                       </car>
                    </records>




                                                                                                     ESDC 2010 - 79
...Better XML Manipulation...
                    import   org.w3c.dom.Document;
                    import   org.w3c.dom.NodeList;
                    import   org.w3c.dom.Node;
                    import   org.xml.sax.SAXException;

                    import   javax.xml.parsers.DocumentBuilderFactory;
                    import   javax.xml.parsers.DocumentBuilder;
                    import   javax.xml.parsers.ParserConfigurationException;
                    import   java.io.File;
                    import   java.io.IOException;

                    public class FindYearsJava {
                        public static void main(String[] args) {
© ASERT 2006-2010




                            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
                            try {
                                DocumentBuilder builder = builderFactory.newDocumentBuilder();
                                Document document = builder.parse(new File("records.xml"));
                                NodeList list = document.getElementsByTagName("car");
                                for (int i = 0; i < list.getLength(); i++) {
                                    Node n = list.item(i);
                                    Node year = n.getAttributes().getNamedItem("year");
                                    System.out.println("year = " + year.getTextContent());
                                }
                            } catch (ParserConfigurationException e) {
                                e.printStackTrace();
                            } catch (SAXException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                                                                                                            ESDC 2010 - 80
...Better XML Manipulation...
                    import   org.w3c.dom.Document;
                    import   org.w3c.dom.NodeList;
                    import   org.w3c.dom.Node;                                          boilerplate
                    import   org.xml.sax.SAXException;

                    import   javax.xml.parsers.DocumentBuilderFactory;
                    import   javax.xml.parsers.DocumentBuilder;
                    import   javax.xml.parsers.ParserConfigurationException;
                    import   java.io.File;
                    import   java.io.IOException;

                    public class FindYearsJava {
                        public static void main(String[] args) {
© ASERT 2006-2010




                            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
                            try {
                                DocumentBuilder builder = builderFactory.newDocumentBuilder();
                                Document document = builder.parse(new File("records.xml"));
                                NodeList list = document.getElementsByTagName("car");
                                for (int i = 0; i < list.getLength(); i++) {
                                    Node n = list.item(i);
                                    Node year = n.getAttributes().getNamedItem("year");
                                    System.out.println("year = " + year.getTextContent());
                                }
                            } catch (ParserConfigurationException e) {
                                e.printStackTrace();
                            } catch (SAXException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                                                                                                            ESDC 2010 - 81
...Better XML Manipulation



                    def records = new XmlParser().parse("records.xml")
                    records.car.each {
© ASERT 2006-2010




                        println "year = ${it.@year}"
                    }



                                                   year = 2006
                                                   year = 1962
                                                   year = 1931


                                                                 ESDC 2010 - 82
XML Processing Options
                    • Reading XML
                      – Special Groovy support: XmlParser, XmlSlurper, DOMCategory
                         • All support GPath, XmlSlurper features Lazy loading
                      – Or Groovy sugar for your current favorites: DOM, SAX, StAX,
                        DOM4J, JDom, XOM, XPath, XSLT, XQuery, etc.
                    • Creating XML
                      – Special Groovy support: MarkupBuilder and
© ASERT 2006-2010




                        StreamingMarkupBuilder
                      – Or again, enhanced syntax for your current favorites
                    • Updating XML
                      – Using above: read followed by create
                      – Can be done with XmlParser, XmlSlurper, DOMCategory
                      – Or with your Java favorites
                    • Verifying XML
                      – Also DTD, W3C XML Schema, Relax NG in a similar fashion to
                        Java mechanisms for these features
                                                                                 ESDC 2010 - 83
More Details: XmlSlurper
                    def records = new XmlSlurper().parse("records.xml")
                    assert 3 == records.car.size()                                          // 3 records in total
                    assert 10 == records.depthFirst().collect{ it }.size()              // 10 nested nodes
                    // test properties of the first record
                    def firstRecord = records.car[0]
                    assert 'car' == firstRecord.name()
                    assert 'Holden' == firstRecord.@make.toString() && 'Australia' == firstRecord.cou
                    // 2 cars have an 'e' in the make
                    assert 2 == records.car.findAll{ it.@make.toString().contains('e') }.size()
© ASERT 2006-2010




                    // 2 cars have an 'e' in the make
                    assert 2 == records.car.findAll{ it.@make =~ '.*e.*' }.size()
                    // makes of cars that have an 's' followed by an 'a' in the country
                    assert ['Holden', 'Peel'] == records.car.findAll{ it.country =~ '.*s.*a.*' }.@make.coll
                    // types of records
                    assert ['speed', 'size', 'price'] == records.depthFirst().grep{ it.@type != '' }.'@type'*
                    assert ['speed', 'size', 'price'] == records.'**'.grep{ it.@type != '' }.'@type'*.toString
                    // check parent() operator
                    def countryOne = records.car[1].country
                    assert 'Peel' == countryOne.parent().@make.toString() && 'Peel' == countryOne.'.
                    // names of cars with records sorted by year
                    def names = records.car.list().sort{ it.@year.toInteger() }.'@name'*.toString()
                    assert ['Royale', 'P50', 'HSV Maloo'] == names
                                                                                                    ESDC 2010 - 84
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial
Groovy Tutorial

Weitere ähnliche Inhalte

Was ist angesagt?

Leveraging Nexus Repository Manager at the Heart of DevOps
Leveraging Nexus Repository Manager at the Heart of DevOpsLeveraging Nexus Repository Manager at the Heart of DevOps
Leveraging Nexus Repository Manager at the Heart of DevOpsSeniorStoryteller
 
Weblogic Server Overview Weblogic Scripting Tool
Weblogic Server Overview Weblogic Scripting ToolWeblogic Server Overview Weblogic Scripting Tool
Weblogic Server Overview Weblogic Scripting ToolGokhan Fazli Celik
 
The Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native ApplicationsThe Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native ApplicationsVMware Tanzu
 
Custom Connector development using Mule SDK
Custom Connector development using Mule SDKCustom Connector development using Mule SDK
Custom Connector development using Mule SDKNavin Kare
 
JBoss Enterprise Application Platform 6 Troubleshooting
JBoss Enterprise Application Platform 6 TroubleshootingJBoss Enterprise Application Platform 6 Troubleshooting
JBoss Enterprise Application Platform 6 TroubleshootingAlexandre Cavalcanti
 
News And Development Update Of The CloudStack Tungsten Fabric SDN Plug-in
News And Development Update Of The CloudStack Tungsten Fabric SDN Plug-inNews And Development Update Of The CloudStack Tungsten Fabric SDN Plug-in
News And Development Update Of The CloudStack Tungsten Fabric SDN Plug-inShapeBlue
 
OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)Ian Choi
 
DevOps Meetup ansible
DevOps Meetup   ansibleDevOps Meetup   ansible
DevOps Meetup ansiblesriram_rajan
 
JBoss Application Server 7
JBoss Application Server 7JBoss Application Server 7
JBoss Application Server 7Ray Ploski
 
Shootout! Template engines for the JVM
Shootout! Template engines for the JVMShootout! Template engines for the JVM
Shootout! Template engines for the JVMJeroen Reijn
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesArun Gupta
 
Gradle - the Enterprise Automation Tool
Gradle  - the Enterprise Automation ToolGradle  - the Enterprise Automation Tool
Gradle - the Enterprise Automation ToolIzzet Mustafaiev
 
Introduction to laravel framework
Introduction to laravel frameworkIntroduction to laravel framework
Introduction to laravel frameworkAhmad Fatoni
 
Prometheus - basics
Prometheus - basicsPrometheus - basics
Prometheus - basicsJuraj Hantak
 

Was ist angesagt? (20)

Maven tutorial
Maven tutorialMaven tutorial
Maven tutorial
 
Leveraging Nexus Repository Manager at the Heart of DevOps
Leveraging Nexus Repository Manager at the Heart of DevOpsLeveraging Nexus Repository Manager at the Heart of DevOps
Leveraging Nexus Repository Manager at the Heart of DevOps
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
 
GraalVm and Quarkus
GraalVm and QuarkusGraalVm and Quarkus
GraalVm and Quarkus
 
Weblogic Server Overview Weblogic Scripting Tool
Weblogic Server Overview Weblogic Scripting ToolWeblogic Server Overview Weblogic Scripting Tool
Weblogic Server Overview Weblogic Scripting Tool
 
The Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native ApplicationsThe Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native Applications
 
Custom Connector development using Mule SDK
Custom Connector development using Mule SDKCustom Connector development using Mule SDK
Custom Connector development using Mule SDK
 
CloudInit Introduction
CloudInit IntroductionCloudInit Introduction
CloudInit Introduction
 
JBoss Enterprise Application Platform 6 Troubleshooting
JBoss Enterprise Application Platform 6 TroubleshootingJBoss Enterprise Application Platform 6 Troubleshooting
JBoss Enterprise Application Platform 6 Troubleshooting
 
News And Development Update Of The CloudStack Tungsten Fabric SDN Plug-in
News And Development Update Of The CloudStack Tungsten Fabric SDN Plug-inNews And Development Update Of The CloudStack Tungsten Fabric SDN Plug-in
News And Development Update Of The CloudStack Tungsten Fabric SDN Plug-in
 
Maven ppt
Maven pptMaven ppt
Maven ppt
 
OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)OpenStack DevStack Install - 2부 (Multi-nodes)
OpenStack DevStack Install - 2부 (Multi-nodes)
 
DevOps Meetup ansible
DevOps Meetup   ansibleDevOps Meetup   ansible
DevOps Meetup ansible
 
JBoss Application Server 7
JBoss Application Server 7JBoss Application Server 7
JBoss Application Server 7
 
Shootout! Template engines for the JVM
Shootout! Template engines for the JVMShootout! Template engines for the JVM
Shootout! Template engines for the JVM
 
Introduction to Maven
Introduction to MavenIntroduction to Maven
Introduction to Maven
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
 
Gradle - the Enterprise Automation Tool
Gradle  - the Enterprise Automation ToolGradle  - the Enterprise Automation Tool
Gradle - the Enterprise Automation Tool
 
Introduction to laravel framework
Introduction to laravel frameworkIntroduction to laravel framework
Introduction to laravel framework
 
Prometheus - basics
Prometheus - basicsPrometheus - basics
Prometheus - basics
 

Andere mochten auch

Gr8conf - The Groovy Ecosystem Revisited
Gr8conf - The Groovy Ecosystem RevisitedGr8conf - The Groovy Ecosystem Revisited
Gr8conf - The Groovy Ecosystem RevisitedAndres Almiray
 
awesome groovy
awesome groovyawesome groovy
awesome groovyPaul King
 
Short history of time - Confitura 2013
Short history of time - Confitura 2013Short history of time - Confitura 2013
Short history of time - Confitura 2013nurkiewicz
 
A Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity ServicesA Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity ServicesForgeRock
 
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through ScriptingWebinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through ScriptingForgeRock
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovytomaslin
 
Dev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock PlatformDev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock PlatformForgeRock
 
Customer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital ServicesCustomer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital ServicesForgeRock
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
Java 8 Date and Time API
Java 8 Date and Time APIJava 8 Date and Time API
Java 8 Date and Time APISualeh Fatehi
 
DSSH: Innovation in SSH
DSSH: Innovation in SSHDSSH: Innovation in SSH
DSSH: Innovation in SSHJuraj Bednar
 

Andere mochten auch (14)

Gr8conf - The Groovy Ecosystem Revisited
Gr8conf - The Groovy Ecosystem RevisitedGr8conf - The Groovy Ecosystem Revisited
Gr8conf - The Groovy Ecosystem Revisited
 
awesome groovy
awesome groovyawesome groovy
awesome groovy
 
Short history of time - Confitura 2013
Short history of time - Confitura 2013Short history of time - Confitura 2013
Short history of time - Confitura 2013
 
groovy
groovygroovy
groovy
 
A Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity ServicesA Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity Services
 
Java 8 Date and Time API
Java 8 Date and Time APIJava 8 Date and Time API
Java 8 Date and Time API
 
Practical Groovy DSL
Practical Groovy DSLPractical Groovy DSL
Practical Groovy DSL
 
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through ScriptingWebinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovy
 
Dev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock PlatformDev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock Platform
 
Customer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital ServicesCustomer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital Services
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Java 8 Date and Time API
Java 8 Date and Time APIJava 8 Date and Time API
Java 8 Date and Time API
 
DSSH: Innovation in SSH
DSSH: Innovation in SSHDSSH: Innovation in SSH
DSSH: Innovation in SSH
 

Ähnlich wie Groovy Tutorial

Groovy Power Features
Groovy Power FeaturesGroovy Power Features
Groovy Power FeaturesPaul King
 
Paulking groovy
Paulking groovyPaulking groovy
Paulking groovyd0nn9n
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrencyPaul King
 
RESTful Services and Distributed OSGi - 04/2009
RESTful Services and Distributed OSGi - 04/2009RESTful Services and Distributed OSGi - 04/2009
RESTful Services and Distributed OSGi - 04/2009Roland Tritsch
 
XML and Web Services with Groovy
XML and Web Services with GroovyXML and Web Services with Groovy
XML and Web Services with GroovyPaul King
 
Introducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template EngineIntroducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template EngineJames Strachan
 
make builds groovy
make builds groovymake builds groovy
make builds groovyguest88884d
 
Make Your Builds More Groovy
Make Your Builds More GroovyMake Your Builds More Groovy
Make Your Builds More GroovyPaul King
 
Groovy Testing Sep2009
Groovy Testing Sep2009Groovy Testing Sep2009
Groovy Testing Sep2009Paul King
 
Dynamic Language Practices
Dynamic Language PracticesDynamic Language Practices
Dynamic Language PracticesPaul King
 
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012Arun Gupta
 
WebSocket Perspectives and Vision for the Future
WebSocket Perspectives and Vision for the FutureWebSocket Perspectives and Vision for the Future
WebSocket Perspectives and Vision for the FutureFrank Greco
 
Groovy Testing Aug2009
Groovy Testing Aug2009Groovy Testing Aug2009
Groovy Testing Aug2009guest4a266c
 
HTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun GuptaHTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun GuptaJAX London
 
Project Avatar (Lyon JUG & Alpes JUG - March 2014)
Project Avatar (Lyon JUG & Alpes JUG  - March 2014)Project Avatar (Lyon JUG & Alpes JUG  - March 2014)
Project Avatar (Lyon JUG & Alpes JUG - March 2014)David Delabassee
 
Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur!
Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur! Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur!
Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur! David Delabassee
 
Isomorphic JS - new silver bullet
Isomorphic JS - new silver bulletIsomorphic JS - new silver bullet
Isomorphic JS - new silver bulletimevs
 

Ähnlich wie Groovy Tutorial (20)

Groovy Power Features
Groovy Power FeaturesGroovy Power Features
Groovy Power Features
 
Paulking groovy
Paulking groovyPaulking groovy
Paulking groovy
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrency
 
RESTful Services and Distributed OSGi - 04/2009
RESTful Services and Distributed OSGi - 04/2009RESTful Services and Distributed OSGi - 04/2009
RESTful Services and Distributed OSGi - 04/2009
 
XML and Web Services with Groovy
XML and Web Services with GroovyXML and Web Services with Groovy
XML and Web Services with Groovy
 
Introducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template EngineIntroducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template Engine
 
make builds groovy
make builds groovymake builds groovy
make builds groovy
 
Make Your Builds More Groovy
Make Your Builds More GroovyMake Your Builds More Groovy
Make Your Builds More Groovy
 
Groovy Testing Sep2009
Groovy Testing Sep2009Groovy Testing Sep2009
Groovy Testing Sep2009
 
Dynamic Language Practices
Dynamic Language PracticesDynamic Language Practices
Dynamic Language Practices
 
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
 
WebSocket Perspectives and Vision for the Future
WebSocket Perspectives and Vision for the FutureWebSocket Perspectives and Vision for the Future
WebSocket Perspectives and Vision for the Future
 
Groovy.Tutorial
Groovy.TutorialGroovy.Tutorial
Groovy.Tutorial
 
Groovy Testing Aug2009
Groovy Testing Aug2009Groovy Testing Aug2009
Groovy Testing Aug2009
 
HTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun GuptaHTML5 Websockets and Java - Arun Gupta
HTML5 Websockets and Java - Arun Gupta
 
Websocket 1.0
Websocket 1.0Websocket 1.0
Websocket 1.0
 
Project Avatar (Lyon JUG & Alpes JUG - March 2014)
Project Avatar (Lyon JUG & Alpes JUG  - March 2014)Project Avatar (Lyon JUG & Alpes JUG  - March 2014)
Project Avatar (Lyon JUG & Alpes JUG - March 2014)
 
Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur!
Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur! Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur!
Java EE 7 et ensuite pourquoi pas JavaScript sur le serveur!
 
Isomorphic JS - new silver bullet
Isomorphic JS - new silver bulletIsomorphic JS - new silver bullet
Isomorphic JS - new silver bullet
 
Java Cloud and Container Ready
Java Cloud and Container ReadyJava Cloud and Container Ready
Java Cloud and Container Ready
 

Mehr von Paul King

groovy databases
groovy databasesgroovy databases
groovy databasesPaul King
 
groovy transforms
groovy transformsgroovy transforms
groovy transformsPaul King
 
concurrency gpars
concurrency gparsconcurrency gpars
concurrency gparsPaul King
 
tictactoe groovy
tictactoe groovytictactoe groovy
tictactoe groovyPaul King
 
groovy rules
groovy rulesgroovy rules
groovy rulesPaul King
 
functional groovy
functional groovyfunctional groovy
functional groovyPaul King
 
Make Testing Groovy
Make Testing GroovyMake Testing Groovy
Make Testing GroovyPaul King
 
Agile Testing Practices
Agile Testing PracticesAgile Testing Practices
Agile Testing PracticesPaul King
 
groovy DSLs from beginner to expert
groovy DSLs from beginner to expertgroovy DSLs from beginner to expert
groovy DSLs from beginner to expertPaul King
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GParsPaul King
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy PluginsPaul King
 
Make Your Testing Groovy
Make Your Testing GroovyMake Your Testing Groovy
Make Your Testing GroovyPaul King
 
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...Paul King
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Paul King
 

Mehr von Paul King (15)

groovy databases
groovy databasesgroovy databases
groovy databases
 
groovy transforms
groovy transformsgroovy transforms
groovy transforms
 
concurrency gpars
concurrency gparsconcurrency gpars
concurrency gpars
 
tictactoe groovy
tictactoe groovytictactoe groovy
tictactoe groovy
 
groovy rules
groovy rulesgroovy rules
groovy rules
 
functional groovy
functional groovyfunctional groovy
functional groovy
 
Make Testing Groovy
Make Testing GroovyMake Testing Groovy
Make Testing Groovy
 
Agile Testing Practices
Agile Testing PracticesAgile Testing Practices
Agile Testing Practices
 
groovy DSLs from beginner to expert
groovy DSLs from beginner to expertgroovy DSLs from beginner to expert
groovy DSLs from beginner to expert
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GPars
 
GroovyDSLs
GroovyDSLsGroovyDSLs
GroovyDSLs
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 
Make Your Testing Groovy
Make Your Testing GroovyMake Your Testing Groovy
Make Your Testing Groovy
 
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...Craig Smith & Paul King   Agile Tool Hacking   Taking Your Agile Development ...
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
 

Kürzlich hochgeladen

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 

Kürzlich hochgeladen (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 

Groovy Tutorial

  • 1. © ASERT 2006-2010 Groovy Tutorial Scripting on the JVM Dr Paul King paulk@asert.com.au @paulk_asert ASERT, Australia
  • 2. Topics  Introduction • Simple Data Types • Collective Data Types • Control Structures • Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 2
  • 3. What is Groovy? • “Groovy is like a super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, DSL support, builders and dynamic typing.” © ASERT 2006-2010 Groovy = Java – boiler plate code + mostly dynamic typing + closures + domain specific languages + builders + metaprogramming + GDK library ESDC 2010 - 3
  • 4. Groovy Goodies Overview • Fully object oriented • Closures: reusable and assignable pieces of code • Operators can be • GPath: efficient overloaded © ASERT 2006-2010 object navigation • Multimethods • GroovyBeans • Literal declaration for • grep and switch lists (arrays), maps, ranges and regular • Templates, builder, expressions swing, Ant, markup, XML, SQL, XML-RPC, Scriptom, Grails, tests, Mocks ESDC 2010 - 4
  • 5. Growing Acceptance … A slow and steady start but now gaining in momentum, maturity and mindshare Now free
  • 6. … Growing Acceptance … © ASERT 2006-2010 ESDC 2010 - 6
  • 7. … Growing Acceptance … © ASERT 2006-2010 Groovy and Grails downloads: 70-90K per month and growing ESDC 2010 - 7
  • 8. … Growing Acceptance … © ASERT 2006-2010 Source: http://www.micropoll.com/akira/mpresult/501697-116746 Source: http://www.grailspodcast.com/ ESDC 2010 - 8
  • 9. … Growing Acceptance … © ASERT 2006-2010 http://www.jroller.com/scolebourne/entry/devoxx_2008_whiteboard_votes http://www.java.net ESDC 2010 - 9
  • 10. … Growing Acceptance … What alternative JVM language are you using or intending to use © ASERT 2006-2010 http://www.leonardoborges.com/writings ESDC 2010 - 10
  • 11. … Growing Acceptance … © ASERT 2006-2010 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo.com) ESDC 2010 - 11
  • 12. … Growing Acceptance … © ASERT 2006-2010 http://pollpigeon.com/jsf-grails-wicket/r/25665/ ESDC 2010 - 12
  • 13. … Growing Acceptance © ASERT 2006-2010 ESDC 2010 - 13
  • 14. The Landscape of JVM Languages mostly dynamic typing © ASERT 2006-2010 Dynamic features call for dynamic types Java bytecode calls for static types The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform. ESDC 2010 - 14
  • 15. Groovy Starter System.out.println("Hello, World!"); // optional semicolon, println 'Hello, World!' // System.out, brackets, // main() method, class defn def name = 'Guillaume' // dynamic typing println "$name, I'll get the car." // GString String longer = """${name}, the car is in the next row.""" // multi-line string © ASERT 2006-2010 // with static typing assert 0.5 == 1/2 // BigDecimal equals() def printSize(obj) { // optional duck typing print obj?.size() // safe dereferencing } def pets = ['ant', 'bee', 'cat'] // native list syntax pets.each { pet -> // closure support assert pet < 'dog' // overloading '<' on String } // or: for (pet in pets)... ESDC 2010 - 15
  • 16. A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { This code List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { is valid String s = (String) strings.get(i); Java and if (s.length() <= length) { result.add(s); valid Groovy } } © ASERT 2006-2010 return result; } public static void main(String[] args) { List names = new ArrayList(); names.add("Ted"); names.add("Fred"); names.add("Jed"); names.add("Ned"); System.out.println(names); Based on an Erase e = new Erase(); example by List shortNames = e.removeLongerThan(names, 3); Jim Weirich System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { & Ted Leung String s = (String) shortNames.get(i); System.out.println(s); } } } ESDC 2010 - 16
  • 17. ...A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { Do the List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { semicolons String s = (String) strings.get(i); add anything? if (s.length() <= length) { result.add(s); And shouldn‟t } } we us more © ASERT 2006-2010 } return result; modern list public static void main(String[] args) { notation? List names = new ArrayList(); names.add("Ted"); names.add("Fred"); Why not names.add("Jed"); names.add("Ned"); System.out.println(names); import common Erase e = new Erase(); libraries? List shortNames = e.removeLongerThan(names, 3); System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { String s = (String) shortNames.get(i); System.out.println(s); } } } ESDC 2010 - 17
  • 18. ...A Better Java... class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) } } return result } public static void main(String[] args) { © ASERT 2006-2010 List names = new ArrayList() names.add("Ted"); names.add("Fred") names.add("Jed"); names.add("Ned") System.out.println(names) Erase e = new Erase() List shortNames = e.removeLongerThan(names, 3) System.out.println(shortNames.size()) for (String s in shortNames) { System.out.println(s) } } } ESDC 2010 - 18
  • 19. ...A Better Java... class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) Do we need } the static types? } return result Must we always } have a main public static void main(String[] args) { method and © ASERT 2006-2010 List names = new ArrayList() names.add("Ted"); names.add("Fred") class definition? names.add("Jed"); names.add("Ned") System.out.println(names) How about Erase e = new Erase() List shortNames = e.removeLongerThan(names, 3) improved System.out.println(shortNames.size()) consistency? for (String s in shortNames) { System.out.println(s) } } } ESDC 2010 - 19
  • 20. ...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) } } return result } © ASERT 2006-2010 names = new ArrayList() names.add("Ted") names.add("Fred") names.add("Jed") names.add("Ned") System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } ESDC 2010 - 20
  • 21. ...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) Shouldn‟t we } } have special return result notation for lists? } And special © ASERT 2006-2010 names = new ArrayList() facilities for names.add("Ted") names.add("Fred") list processing? names.add("Jed") Is „return‟ names.add("Ned") System.out.println(names) needed at end? shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } ESDC 2010 - 21
  • 22. ...A Better Java... def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } names = ["Ted", "Fred", "Jed", "Ned"] System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) shortNames.each{ System.out.println(s) } © ASERT 2006-2010 ESDC 2010 - 22
  • 23. ...A Better Java... def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } Is the method names = ["Ted", "Fred", "Jed", "Ned"] now needed? System.out.println(names) shortNames = removeLongerThan(names, 3) Easier ways to System.out.println(shortNames.size()) use common shortNames.each{ System.out.println(s) } methods? © ASERT 2006-2010 Are brackets required here? ESDC 2010 - 23
  • 24. ...A Better Java... names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2006-2010 ESDC 2010 - 24
  • 25. ...A Better Java names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2006-2010 [Ted, Fred, Jed, Ned] 3 Ted Jed Ned ESDC 2010 - 25
  • 26. Better JavaBeans... import java.math.BigDecimal; ... public class BikeJavaBean { public void setModel(String model) { private String manufacturer; this.model = model; private String model; } private int frame; private String serialNo; public int getFrame() { private double weight; return frame; private String status; } private BigDecimal cost; public String getSerialNo() { public BikeJavaBean(String manufacturer, String model, return serialNo; int frame, String serialNo, } double weight, String status) { this.manufacturer = manufacturer; public void setSerialNo(String serialNo) { this.model = model; this.serialNo = serialNo; this.frame = frame; } this.serialNo = serialNo; © ASERT 2006-2010 this.weight = weight; public double getWeight() { this.status = status; return weight; } } public String toString() { public void setWeight(double weight) { return "Bike:“ + this.weight = weight; “n manufacturer -- " + manufacturer + } "n model -- " + model + "n frame -- " + frame + public String getStatus() { "n serialNo -- " + serialNo + return status; "n"; } } public void setStatus(String status) { public String getManufacturer() { this.status = status; return manufacturer; } } public BigDecimal getCost() { public void setManufacturer(String manufacturer) { return cost; this.manufacturer = manufacturer; } } public void setCost(BigDecimal cost) { public String getModel() { this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP); return model; } } } ... Modified example from: http://www.ibm.com/developerworks/library/j-pg09196.html ESDC 2010 - 26
  • 27. ...Better JavaBeans... import java.math.BigDecimal; ... public class BikeJavaBean { public void setModel(String model) { Auto private String manufacturer; this.model = model; private String model; private int frame; } getters? private String serialNo; private double weight; private String status; public int getFrame() { } return frame; Auto private BigDecimal cost; public String getSerialNo() { setters? public BikeJavaBean(String manufacturer, String model, return serialNo; int frame, String serialNo, double weight, String status) { } Auto this.manufacturer = manufacturer; this.model = model; this.frame = frame; } this.serialNo = serialNo; construction? public void setSerialNo(String serialNo) { this.serialNo = serialNo; © ASERT 2006-2010 this.weight = weight; public double getWeight() { this.status = status; return weight; } } public String toString() { public void setWeight(double weight) { return "Bike:“ + this.weight = weight; “n manufacturer -- " + manufacturer + } "n model -- " + model + "n frame -- " + frame + public String getStatus() { "n serialNo -- " + serialNo + return status; "n"; } } public void setStatus(String status) { public String getManufacturer() { this.status = status; return manufacturer; } } public BigDecimal getCost() { public void setManufacturer(String manufacturer) { return cost; this.manufacturer = manufacturer; } } public void setCost(BigDecimal cost) { public String getModel() { this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP); return model; } } } ... ESDC 2010 - 27
  • 28. ... Better JavaBeans ... class BikeGroovyBean { String manufacturer, model, serialNo, status final Integer frame Double weight BigDecimal cost public void setCost(BigDecimal newCost) { cost = newCost.setScale(3, BigDecimal.ROUND_HALF_UP) © ASERT 2006-2010 } public String toString() { return """Bike: manufacturer -- $manufacturer model -- $model More complicated than frame -- $frame normal because we want: serialNo -- $serialNo * Read only frame """ * Custom setter for cost } * Custom toString() } ESDC 2010 - 28
  • 29. ... Better JavaBeans class BikeGroovyBean { String manufacturer, model, serialNo, status Integer frame Double weight BigDecimal cost } © ASERT 2006-2010 In more typical cases it is often as simple as this. ESDC 2010 - 29
  • 30. Topics • Introduction  Simple Data Types  Numbers, Other 'Primitives', Strings, Regexs, Dates & Times • Collective Data Types • Control Structures • © ASERT 2006-2010 Closures and Builders • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 30
  • 31. Numbers • Java numbers byte b1 = 42; Byte b2 = 42 short s1 = 20000; Short s2 = 20000 – But with primitive int i1 = 1000000000 types autoboxed to Integer i2 = 1000000000 def i3 = 42 equivalent wrapper long l1 = 1000000000000000000 types Long l2 = 1000000000000000000 def l3 = 42L – Sizes supported: © ASERT 2006-2010 Byte, Short, float f1 = 3.5f; Float f2 = 3.5 Integer, Long, def f3 = 3.5f double d1 = 3.5e40; Double d2 = 3.5e40 Float, Double, def d3 = 3.5d BigInteger, BigInteger bi = 30g BigDecimal BigDecimal bd1 = 3.5g def bd2 = 3.5 – Some special treatment when assert 2 instanceof Integer assert !2.equals(4) handling arrays assert 3.5 instanceof BigDecimal and in Interfaces assert (7/2) instanceof BigDecimal ESDC 2010 - 31
  • 32. Parsing Strings to Numbers def string = "300" assert string.isNumber() // check if string appears to be a number // OK, now convert to number in different ways def i4 = string.toInteger() def i5 = string as int def i6 = string as Integer def i7 = new Integer(string) def i8 = Integer.parseInt(string) def i9 = (int) java.text.NumberFormat.instance.parse(string) // Long © ASERT 2006-2010 string = "300.5" def n1 = java.text.NumberFormat.instance.parse(string) // Double def n2 = string.toFloat() def n3 = string.toDouble() def n4 = string.toBigDecimal() integerPattern = /^[+-]?d+$/ // regex notation assert '-36' ==~ integerPattern // explained later assert !('abc' =~ integerPattern) decimalPattern = /^-?(?:d+(?:.d*)?|.d+)$/ assert '37.5' ==~ decimalPattern ESDC 2010 - 32
  • 33. Other 'primitive' types • boolean and char – Again replaced by wrapper counterparts automatically – We'll see a little bit more about chars under Strings – There is a notion called 'Groovy Truth' whereby any expression can be used where Java would require a © ASERT 2006-2010 boolean and the expression will be evaluated • The numbers 0 and 0.0 and null objects return false • Empty Strings, Lists, Maps, Matchers, ... return false • Other objects return true Found 4 vowels: def vowels = 'aeiou' [e, i, o, u] def sentences = ['The quick brown fox', 'Flyby'] Nothing found sentences.each { sentence -> def found = sentence.toList().intersect(vowels.toList()) if (found) println "Found ${found.size()} vowels: $found" else println 'Nothing found' } ESDC 2010 - 33
  • 34. Strings... • Several forms // normal strings def firstname = 'Kate' – Single quotes for assert firstname instanceof String simple strings def surname = "Bush" assert firstname * 2 == 'KateKate' – Double quotes for def fullname = GStrings which firstname + ' ' + surname assert fullname == 'Kate Bush' support variable © ASERT 2006-2010 expansion // GString fullname = "$firstname $surname" – Slashy strings assert fullname instanceof GString behave like assert fullname == 'Kate Bush' GStrings but assert fullname - firstname == ' Bush' assert fullname.padLeft(10) == preserve ' Kate Bush' backslashes (great for regex and // indexing (including ranges) assert fullname[0..3] == firstname directory names) assert fullname[-4..-1] == surname – Multi-line versions assert fullname[5, 3..1] == 'Beta' ESDC 2010 - 34
  • 35. …Strings… // Multi-line strings def tt = ''' def lines = tt.split('n') She sells, sea shells assert lines.size() == 2 By the sea shore''' lines = address.readLines() assert lines.size() == 3 assert tt instanceof String assert lines[-1] == 'New York' assert tt.startsWith('She') assert tt.endsWith('shore') // slashy string: (almost) no escaping assert tt.contains('n') def path = /C:WindowsSystem32/ © ASERT 2006-2010 def address = """ def plain = 'nrtbf$' $fullname assert plain.size() == 7 123 First Ave def slashy = /nrtbf$/ New York assert slashy.size() == 14 """.trim() // late binding trick with closures println """ fullname = "${-> firstname} $surname" --------------------- assert fullname == 'Kate Bush' | $fullname | firstname = 'George' | 123 First Ave | surname = 'Clooney' | New York | assert fullname == 'George Bush' --------------------- """ ESDC 2010 - 35
  • 36. …Strings... // more substrings (minus removes first occurrence) string = 'hippopotamus' assert string - 'hippo' - 'mus' + 'to' == 'potato' assert string.replace('ppopotam','bisc') == 'hibiscus' // processing characters (more on collections later) def letters = 'apple'.toList() assert letters == ['a', 'p', 'p', 'l', 'e'] © ASERT 2006-2010 assert letters[0] instanceof String letters = 'apple'.toList()*.toCharacter() def expected = ['a', 'p', 'p', 'l', 'e'] as char[] assert letters == expected assert letters[0] instanceof Character assert letters instanceof List assert expected instanceof char[] string = "an apple a day" assert string.toList().unique().sort().join() == ' adelnpy' ESDC 2010 - 36
  • 37. …Strings... // reversing chars/words assert 'string'.reverse() == 'gnirts' assert 'two words'.split().reverse().join(' ') == 'words two' string = 'Yoda said, "can you see this?"' revwords = string.split(' ').reverse().join(' ') assert revwords == 'this?" see you "can said, Yoda' © ASERT 2006-2010 revwords = string.replaceAll(/(w*)/) { all, match -> match.reverse() } assert revwords == 'adoY dias, "nac uoy ees siht?"' revwords = string.replaceAll(/(w*) (w*)(W*)/ * 3, '$2 $1$3$8 $7$6$5 $4$9') assert revwords == 'said Yoda, "this see you can?"' • Find out more through Javadoc, GDK doc – Can also lookup GString but usually no need ESDC 2010 - 37
  • 38. …Strings... • javadoc © ASERT 2006-2010 ESDC 2010 - 38
  • 39. …Strings • groovy-jdk (just the additions) © ASERT 2006-2010 ESDC 2010 - 39
  • 40. Regular Expressions... assert "Hello World!" =~ /Hello/ // Find operator assert "Hello World!" ==~ /Hellob.*/ // Match operator def p = ~/Hellob.*/ // Pattern operator assert p.class.name == 'java.util.regex.Pattern' def input = "Voting is open between 01 Nov 2008 and 04 Nov 2008" def dateFormat = /dd? ... d{4}/ def matches = (input =~ dateFormat) © ASERT 2006-2010 assert matches[1] == '04 Nov 2008' 01 Nov 2008 matches.each { m -> println m } 04 Nov 2008 input.eachMatch(dateFormat) { m -> println m } assert input.findAll(dateFormat) == ['01 Nov 2008', '04 Nov 2008'] println input.replaceAll(dateFormat, '?/?/?') Voting is open between ?/?/? and ?/?/? ESDC 2010 - 40
  • 41. ...Regular Expressions // "Voting is open between 01 Nov 2008 and 04 Nov 2008" def dateFormatGroups = /(dd?) (...) (d{4})/ def matchingGroups = (input =~ dateFormatGroups) assert matchingGroups[1][1] == '04' matchingGroups.each { all, d, m, y -> println "$d/$m/$y" } © ASERT 2006-2010 input.eachMatch(dateFormatGroups) { all, d, m, y -> println "$d/$m/$y" } 01/Nov/2008 04/Nov/2008 assert input.findAll(dateFormatGroups) { full, d, m, y -> "$m $d of $y" } == ['Nov 01 of 2008', 'Nov 04 of 2008'] println input.replaceAll(dateFormatGroups) { full, d, m, y -> "$m $d ????" } Voting is open between Nov 01 ???? and Nov 04 ???? ESDC 2010 - 41
  • 42. Abbreviated regex notation Symbol Meaning . Any character ^ Start of line (or start of document, when in single-line mode) $ End of line (or end of document, when in single-line mode) d Digit character D Any character except digits s Whitespace character S Any character except whitespace w Word character © ASERT 2006-2010 W Any character except word characters b Word boundary () Grouping (x|y) x or y as in (Groovy|Java|Ruby) x* Zero or more occurrences of x x+ One or more occurrences of x x? Zero or one occurrence of x x{m,n} At least m and at most n occurrences of x x{m} Exactly m occurrences of x [a-f] Character class containing the characters a, b, c, d, e, f [^a] Character class containing any character except a (?=regex) Positive lookahead (?<=text) Positive lookbehind ESDC 2010 - 42
  • 43. Dates... • Similar to Java – Use java.util.Date, java.util.Calendar, java.sql.Date, ... – Can use static imports to help – Or 3rd party package like Joda Time • Special support for changing times: © ASERT 2006-2010 date2 = date1 + 1 // day date2 = date1 + 1.week – 3.days + 6.hours • Utility methods for date input and output – Date.parse(formatString, dateString) – date.format(formatString) – date.timeString, date.dateString, date.dateTimeString • Potentially will change with JSR 310 ESDC 2010 - 43
  • 44. ... Dates... import static java.util.Calendar.getInstance as now import java.util.GregorianCalendar as D import org.codehaus.groovy.runtime.TimeCategory println new D(2007,11,25).time println now().time Tue Dec 25 00:00:00 EST 2007 Thu Jun 28 10:10:34 EST 2007 def date = new Date() + 1 Fri Jun 29 10:10:35 EST 2007 © ASERT 2006-2010 println date Tue Jul 17 11:10:35 EST 2007 Date was Jun/03/1998 use(TimeCategory) { println new Date() + 1.hour + 3.weeks - 2.days } dateStr = "1998-06-03" date = Date.parse("yyyy-MM-dd", dateStr) println 'Date was ' + date.format("MMM/dd/yyyy") def holidays = boxingDay..newYearsEve ESDC 2010 - 44
  • 45. ... Dates import static java.util.Calendar.* def nowCal = Calendar.instance y = nowCal.get(YEAR) Date nowDate = nowCal.time def (m, d) = [nowDate[MONTH] + 1, nowDate[DATE]] println "Today is $d $m $y" nowCal.set DATE, 1 nowCal.set MONTH, FEBRUARY println "Changed to $nowCal.time" © ASERT 2006-2010 Today is 26 9 2008 Changed to Fri Feb 01 23:05:20 EST 2008 cal = Calendar.instance cal.set 1988, APRIL, 4, 0, 0, 0 date = cal.time def (doy, woy, y) = [DAY_OF_YEAR, WEEK_OF_YEAR, YEAR].collect{ date[it] } println "$date is day $doy and week $woy of year $y" Mon Apr 04 00:00:00 EST 1988 is day 95 and week 15 of year 1988 ESDC 2010 - 45
  • 46. Operator Overloading... © ASERT 2006-2010 ESDC 2010 - 46
  • 47. ...Operator Overloading... © ASERT 2006-2010 ESDC 2010 - 47
  • 48. ...Operator Overloading © ASERT 2006-2010 • Can be used with your own types too shoppingCart << clickedItem ESDC 2010 - 48
  • 49. Topics • Introduction • Simple Data Types  Collective Data Types • Control Structures • Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 49
  • 50. Better Lists, Maps, Ranges • Lists/Collections – Special literal syntax – Additional common methods (operator overloading) def list = [3, new Date(), 'Jan'] assert list + list == list * 2 • Maps © ASERT 2006-2010 – Special literal syntax & GDK methods def map = [a: 1, b: 2] assert map['a'] == 1 && map.b == 2 • Ranges – Special syntax for various kinds of ranges def letters = 'a'..'z' def numbers = 0..<10 assert letters.size() + numbers.size() == 36 ESDC 2010 - 50
  • 51. Topics • Introduction • Simple Data Types • Collective Data Types  Control Structures • Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 51
  • 52. Better Control Structures: Branching/Loops • Branching and loops • Loop-like Closures for (int i = 0; i < n; i++) { } myMap.each { key, value -> for (Type item : iterable) { } println "$key : $value" for (item in iterable) { } } // if (condition) ... // each, every, collect, any, // else if (condition) ... // inject, find, findAll, // else ... // upto, downto, times, grep, © ASERT 2006-2010 // throw, try...catch...finally // reverseEach, eachMatch, // for, while // eachWithIndex, eachLine // d = a ? b : c // eachFile, eachFileMatch, // a = b ?: c // eachByte, combinations ... // d = a?.b?.c • Groovy Truth words = ['bob', 'alpha', 'ehcache', if (1) // ... 'rotator', 'omega', 'reviver'] if (object) // ... bigPalindromes = words.findAll{ w -> if (collection) // ... w == w.reverse() && w.size() > 4} if (map) // ... assert bigPalindromes == if (matcher) // ... ['ehcache', 'rotator', 'reviver'] ESDC 2010 - 52
  • 53. Better Control Structures: Switch switch (10) { case 0 : assert false ; break case 0..9 : assert false ; break case [8,9,11] : assert false ; break case Float : assert false ; break case {it%3 == 0} : assert false ; break case ~/../ : assert true ; break © ASERT 2006-2010 default : assert false ; break } • Extensible – Implement your own isCase() method ESDC 2010 - 53
  • 54. Topics • Introduction • Simple Data Types • Collective Data Types • Control Structures  Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 54
  • 55. Using Closures... • Traditional mainstream languages – Data can be stored in variables, passed around, combined in structured ways to form more complex data; code stays put where it is defined • Languages supporting closures – Data and code can be stored in variables, passed © ASERT 2006-2010 around, combined in structured ways to form more complex algorithms and data doubleNum = { num -> num * 2 } println doubleNum(3) // => 6 processThenPrint = { num, closure -> num = closure(num); println "num is $num" } processThenPrint(3, doubleNum) // => num is 6 processThenPrint(10) { it / 2 } // => num is 5 ESDC 2010 - 55
  • 56. ...Using Closures... import static Math.* Algorithm piE differs by 1.0206946399193839E-11 Algorithm piF differs by 1.0070735356748628E-9 Algorithm piC differs by 2.668102068170697E-7 piA = { 22 / 7 } Algorithm piD differs by 4.813291008076703E-5 piB = { 333/106 } Algorithm piB differs by 8.321958979307098E-5 piC = { 355/113 } Algorithm piA differs by 0.001264489310206951 piD = { 0.6 * (3 + sqrt(5)) } piE = { 22/17 + 37/47 + 88/83 } piF = { sqrt(sqrt(2143/22)) } © ASERT 2006-2010 howCloseToPI = { abs(it.value() - PI) } algorithms = [piA:piA, piB:piB, piC:piC, piD:piD, piE:piE, piF:piF] findBestPI(algorithms) def findBestPI(map) { map.entrySet().sort(howCloseToPI).each { entry -> def diff = howCloseToPI(entry) println "Algorithm $entry.key differs by $diff" } } ESDC 2010 - 56
  • 57. ...Using Closures... • Used for many things in Groovy: • Iterators new File('/x.txt').eachLine { println it • Callbacks } • Higher-order functions • Specialized control structures • Dynamic method definition © ASERT 2006-2010 • Resource allocation 3.times { println 'Hi' } • Threads [0, 1, 2].each { number -> • Continuations println number } def houston(Closure doit) { (10..1).each { count -> [0, 1, 2].each { println it} doit(count) } def printit = { println it } } [0, 1, 2].each printit houston { println it } ESDC 2010 - 57
  • 58. ...Using Closures... map = ['a': 1, 'b': 2] map.each {key, value -> map[key] = value * 2} assert map == ['a': 2, 'b': 4] doubler = {key, value -> map[key] = value * 2} map.each(doubler) © ASERT 2006-2010 assert map == ['a': 4, 'b': 8] def doubleMethod(entry) { map[entry.key] = entry.value * 2 } doubler = this.&doubleMethod map.each(doubler) assert map == ['a': 8, 'b': 16] ESDC 2010 - 58
  • 59. ...Using Closures... assert [1, 2, 3].grep{ it < 3 } == [1, 2] assert [1, 2, 3].any{ it % 2 == 0 } assert [1, 2, 3].every{ it < 4 } assert (1..9).collect{it}.join() == '123456789' assert (1..4).collect{it * 2}.join() == '2468' def add = { x, y -> x + y } © ASERT 2006-2010 def mult = { x, y -> x * y } assert add(1, 3) == 4 assert mult(1, 3) == 3 def min = { x, y -> [x, y].min() } def max = { x, y -> [x, y].max() } def triple = mult.curry(3); assert triple(2) == 6 def atLeastTen = max.curry(10) assert atLeastTen(5) == 10 assert atLeastTen(15) == 15 ESDC 2010 - 59
  • 60. ...Using Closures def pairWise(list, Closure invoke) { if (list.size() < 2) return [] def next = invoke(list[0], list[1]) return [next] + pairWise(list.tail(), invoke) } © ASERT 2006-2010 // using min, max, etc. From previous slide assert pairWise(1..5, add) == [3, 5, 7, 9] assert pairWise(1..5, mult) == [2, 6, 12, 20] assert pairWise(1..5, min) == [1, 2, 3, 4] assert pairWise(1..5, max) == [2, 3, 4, 5] assert 'cbaxabc' == ['a', 'b', 'c'].inject('x') { result, item -> item + result + item } ESDC 2010 - 60
  • 61. Better Design Patterns: Builder • Markup Builder <html> import groovy.xml.* <head> def page = new MarkupBuilder() <title>Hello</title> page.html { </head> head { title 'Hello' } <body> body { © ASERT 2006-2010 <ul> ul { <li>world 1</li> for (count in 1..5) { <li>world 2</li> li "world $count" <li>world 3</li> } } } } <li>world 4</li> <li>world 5</li> </ul> </body> </html> ESDC 2010 - 61
  • 62. SwingBuilder import java.awt.FlowLayout builder = new groovy.swing.SwingBuilder() langs = ["Groovy", "Ruby", "Python", "Pnuts"] gui = builder.frame(size: [290, 100], title: 'Swinging with Groovy!') { panel(layout: new FlowLayout()) { panel(layout: new FlowLayout()) { for (lang in langs) { © ASERT 2006-2010 checkBox(text: lang) } } button(text: 'Groovy Button', actionPerformed: { builder.optionPane(message: 'Indubitably Groovy!'). createDialog(null, 'Zen Message').show() }) button(text: 'Groovy Quit', actionPerformed: {System.exit(0)}) } } gui.show() Source: http://www.ibm.com/developerworks/java/library/j-pg04125/ ESDC 2010 - 62
  • 63. SwingXBuilder import groovy.swing.SwingXBuilder © ASERT 2006-2010 import static java.awt.Color.* import static java.lang.Math.* def swing = new SwingXBuilder() def frame = swing.frame(size: [300, 300]) { graph(plots: [ [GREEN, {value -> sin(value)}], [BLUE, {value -> cos(value)}], [RED, {value -> tan(value)}] ]) }.show() ESDC 2010 - 63
  • 64. GraphicsBuilder def colors = ['red','darkOrange','blue','darkGreen'] (0..3).each { index -> star( cx: 50 + (index*110), cy: 50, or: 40, ir: 15, borderColor: 'black', count: 2+index, fill: colors[index] ) star( cx: 50 + (index*110), cy: 140, or: 40, ir: 15, borderColor: 'black‘, count: 7+index, fill: colors[index] ) } © ASERT 2006-2010 ESDC 2010 - 64
  • 65. AntBuilder... def ant = new AntBuilder() ant.echo("hello") // let's just call one task // create a block of Ant using the builder pattern ant.sequential { myDir = "target/AntTest/" mkdir(dir: myDir) © ASERT 2006-2010 copy(todir: myDir) { fileset(dir: "src/test") { include(name: "**/*.groovy") } } echo("done") } // now let's do some normal Groovy again file = new File("target/test/AntTest.groovy") assert file.exists() ESDC 2010 - 65
  • 66. ...AntBuilder def ant = new AntBuilder() ant.echo(file:'Temp.java', ''' class Temp { public static void main(String[] args) { System.out.println("Hello"); } } © ASERT 2006-2010 ''') ant.with { javac(srcdir:'.', includes:'Temp.java', fork:'true') java(classpath:'.', classname:'Temp', fork:'true') echo('Done') } // => // [javac] Compiling 1 source file // [java] Hello // [echo] Done ESDC 2010 - 66
  • 67. Using AntLibs: Maven Ant Tasks & AntUnit import static groovy.xml.NamespaceBuilder.newInstance as namespace def ant = new AntBuilder() def mvn = namespace(ant, 'antlib:org.apache.maven.artifact.ant') def antunit = namespace(ant, 'antlib:org.apache.ant.antunit') direct = [groupId:'jfree', artifactId:'jfreechart', version:'1.0.9'] indirect = [groupId:'jfree', artifactId:'jcommon', version:'1.0.12'] // download artifacts © ASERT 2006-2010 mvn.dependencies(filesetId:'artifacts') { dependency(direct) } // print out what we downloaded ant.fileScanner { fileset(refid:'artifacts') }.each { println it } // use AntUnit to confirm expected files were downloaded def prefix = System.properties.'user.home' + '/.m2/repository' [direct, indirect].each { item -> def (g, a, v) = [item.groupId, item.artifactId, item.version] antunit.assertFileExists(file:"$prefix/$g/$a/$v/$a-${v}.jar") } C:Userspaulk.m2repositoryjfreejcommon1.0.12jcommon-1.0.12.jar C:Userspaulk.m2repositoryjfreejfreechart1.0.9jfreechart-1.0.9.jar ESDC 2010 - 67
  • 68. Topics • Introduction • Simple Data Types • Collective Data Types • Control Structures • Closures and Builders © ASERT 2006-2010  OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 68
  • 69. Object Orientation • Similar capabilities to Java – Define classes, interfaces, enums, annotations • Differences to Java – Classes (and interfaces etc.) public by default – Methods public by default – © ASERT 2006-2010 Property support within classes (auto-setters/getters) – Multimethods (runtime dispatch – "duck typing") class BikeGroovyBean { String manufacturer, model, serialNo, status Integer frame Double weight BigDecimal cost } ESDC 2010 - 69
  • 70. Object Orientation – Runtime Interfaces – Java has these methods in java.util.Collections: – In Groovy, no need to create a class implementing Comparator having a compare method, just use a map © ASERT 2006-2010 of Closures instead (though Groovy has special support for this example which is even more concise): def animals = ['Antelope', 'Bee', 'Zebra'] def comparator = [ compare:{ a, b -> a.size() <=> b.size() } ] as Comparator assert comparator instanceof Comparator assert Collections.min(animals, comparator) == 'Bee' assert Collections.max(animals, comparator) == 'Antelope' ESDC 2010 - 70
  • 71. Topics • Introduction • Simple Data Types • Collective Data Types • Control Structures • Closures and Builders © ASERT 2006-2010 • OO  GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 71
  • 72. Better File Manipulation... import java.util.List; import java.util.ArrayList; import java.util.Arrays; import java.io.File; // ... import java.io.FileOutputStream; private static void processFile(File file, PrintWriter out) { import java.io.PrintWriter; FileInputStream fis = null; import java.io.FileNotFoundException; InputStreamReader isr = null; import java.io.IOException; BufferedReader reader = null; import java.io.BufferedReader; try { import java.io.InputStreamReader; fis = new FileInputStream(file); import java.io.FileInputStream; isr = new InputStreamReader(fis); reader = new BufferedReader(isr); public class PrintJavaSourceFileLinesThatContainTheWordJava { String nextline; public static void main(String[] args) { int count = 0; File outfile = new File("result.txt"); while ((nextline = reader.readLine()) != null) { outfile.delete(); count++; File basedir = new File(".."); if (nextline.toLowerCase().contains("java")) { List<File> files = new ArrayList<File>(); out.println("File '" + file + files.add(basedir); "' on line " + count); © ASERT 2006-2010 FileOutputStream fos = null; out.println(nextline); PrintWriter out = null; out.println(); try { } fos = new FileOutputStream(outfile); } out = new PrintWriter(fos); } catch (FileNotFoundException e) { while (!files.isEmpty()) { e.printStackTrace(); File file = files.remove(0); } catch (IOException e) { if (file.isDirectory()) { e.printStackTrace(); files.addAll(Arrays.asList(file.listFiles())); } finally { } else { if (reader != null) { if (file.getName().endsWith(".java")) { try { reader.close(); } processFile(file, out); catch (IOException e) { e.printStackTrace(); } } } } if (isr != null) { } try { isr.close(); } } catch (FileNotFoundException e) { catch (IOException e) { e.printStackTrace(); } e.printStackTrace(); } } finally { if (fis != null) { if (out != null) { out.close(); } try { fis.close(); } if (fos != null) { catch (IOException e) { e.printStackTrace(); } try { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } } } } } } // ... ESDC 2010 - 72
  • 73. ...Better File Manipulation... import java.util.List; import import java.util.ArrayList; java.util.Arrays; boilerplate import java.io.File; // ... import java.io.FileOutputStream; private static void processFile(File file, PrintWriter out) { import java.io.PrintWriter; FileInputStream fis = null; import java.io.FileNotFoundException; InputStreamReader isr = null; import java.io.IOException; BufferedReader reader = null; import java.io.BufferedReader; try { import java.io.InputStreamReader; fis = new FileInputStream(file); import java.io.FileInputStream; isr = new InputStreamReader(fis); reader = new BufferedReader(isr); public class PrintJavaSourceFileLinesThatContainTheWordJava { String nextline; public static void main(String[] args) { int count = 0; File outfile = new File("result.txt"); while ((nextline = reader.readLine()) != null) { outfile.delete(); count++; File basedir = new File(".."); if (nextline.toLowerCase().contains("java")) { List<File> files = new ArrayList<File>(); out.println("File '" + file + files.add(basedir); "' on line " + count); © ASERT 2006-2010 FileOutputStream fos = null; out.println(nextline); PrintWriter out = null; out.println(); try { } fos = new FileOutputStream(outfile); } out = new PrintWriter(fos); } catch (FileNotFoundException e) { while (!files.isEmpty()) { e.printStackTrace(); File file = files.remove(0); } catch (IOException e) { if (file.isDirectory()) { e.printStackTrace(); files.addAll(Arrays.asList(file.listFiles())); } finally { } else { if (reader != null) { if (file.getName().endsWith(".java")) { try { reader.close(); } processFile(file, out); catch (IOException e) { e.printStackTrace(); } } } } if (isr != null) { } try { isr.close(); } } catch (FileNotFoundException e) { catch (IOException e) { e.printStackTrace(); } e.printStackTrace(); } } finally { if (fis != null) { if (out != null) { out.close(); } try { fis.close(); } if (fos != null) { catch (IOException e) { e.printStackTrace(); } try { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } } } } } } // ... ESDC 2010 - 73
  • 74. ...Better File Manipulation def out = new File('result.txt') out.delete() new File('..').eachFileRecurse {file -> if (file.name.endsWith('.groovy')) { file.eachLine { line, num -> if (line.toLowerCase().contains('groovy')) out << © ASERT 2006-2010 "File '$file' on line $numn$linenn" } } } File '..filessrcPrintGroovySourceLines.groovy' on line 4 if (file.name.endsWith('.groovy')) { File '..filessrcPrintGroovySourceLines.groovy' on line 6 if (line.toLowerCase().contains('groovy')) File '..jdbcsrcJdbcGroovy.groovy' on line 1 import groovy.sql.Sql … ESDC 2010 - 74
  • 75. Better Process Management... // windows version (minimal error/output) def p = "cmd /c dir *.xml".execute() p.waitFor() if (p.exitValue()) println p.err.text else println p.text ----- stdout ----- Volume in drive D is DATA Volume Serial Number is FC5C-B39D © ASERT 2006-2010 Directory of D:svntrunk-groovygroovy-core // unix version 27/06/2009 10:13 AM 38,478 build.xml def p = "ls *.xml".execute() 29/06/2009 06:53 PM 27,617 pom.xml def err = new StringBuffer() 2 File(s) 66,095 bytes 0 Dir(s) 15,503,597,568 bytes free def out = new StringBuffer() // could ignore/use Stream below ----- stderr ----- Return Code: 1 p.consumeProcessOutput(out, err) ls: *.xml: No such file or directory def exitValue = p.waitFor() if (err) println """----- stderr ----- Return Code: $exitValue $err""" if (out) println "----- stdout -----n$out" ESDC 2010 - 75
  • 76. ...Better Process Management sout: tstfl.grvy serr: def sout = new StringBuffer() def serr = new StringBuffer() proc1 = 'tr -d o'.execute() proc2 = 'tr -d e'.execute() © ASERT 2006-2010 proc3 = 'tr -d i'.execute() proc3.consumeProcessOutput(sout, serr) proc1 | proc2 | proc3 [proc1, proc2].each{ it.consumeProcessErrorStream(serr) } proc1.withWriter { writer -> writer << 'testfile.groovy' } proc3.waitForOrKill(1000) println 'sout: ' + sout println 'serr: ' + serr ESDC 2010 - 76
  • 77. Better Thread Management Thread.start{ Hello from thread 2 4.times { Hello from thread 1 println 'Hello from thread 1' Hello from main thread sleep 400 Hello from main thread } Hello from thread 2 } Hello from thread 1 Thread.start{ Hello from main thread © ASERT 2006-2010 5.times { Hello from thread 2 println 'Hello from thread 2' Hello from main thread sleep 300 Hello from thread 1 } Hello from main thread } Hello from thread 2 7.times { Hello from main thread println 'Hello from main thread' Hello from thread 2 sleep 200 Hello from thread 1 } Hello from main thread ESDC 2010 - 77
  • 78. Topics • Introduction • Simple Data Types • Collective Data Types • Control Structures • Closures and Builders © ASERT 2006-2010 • OO • GDK methods  XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 78
  • 79. Better XML Manipulation... <records> records.xml <car name='HSV Maloo' make='Holden' year='2006'> <country>Australia</country> <record type='speed'>Production Pickup Truck with speed of 271kph</record> </car> © ASERT 2006-2010 <car name='P50' make='Peel' year='1962'> <country>Isle of Man</country> <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg weight</record> </car> <car name='Royale' make='Bugatti' year='1931'> <country>France</country> <record type='price'>Most Valuable Car at $15 million</record> </car> </records> ESDC 2010 - 79
  • 80. ...Better XML Manipulation... import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import java.io.File; import java.io.IOException; public class FindYearsJava { public static void main(String[] args) { © ASERT 2006-2010 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document document = builder.parse(new File("records.xml")); NodeList list = document.getElementsByTagName("car"); for (int i = 0; i < list.getLength(); i++) { Node n = list.item(i); Node year = n.getAttributes().getNamedItem("year"); System.out.println("year = " + year.getTextContent()); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ESDC 2010 - 80
  • 81. ...Better XML Manipulation... import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; boilerplate import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import java.io.File; import java.io.IOException; public class FindYearsJava { public static void main(String[] args) { © ASERT 2006-2010 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document document = builder.parse(new File("records.xml")); NodeList list = document.getElementsByTagName("car"); for (int i = 0; i < list.getLength(); i++) { Node n = list.item(i); Node year = n.getAttributes().getNamedItem("year"); System.out.println("year = " + year.getTextContent()); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ESDC 2010 - 81
  • 82. ...Better XML Manipulation def records = new XmlParser().parse("records.xml") records.car.each { © ASERT 2006-2010 println "year = ${it.@year}" } year = 2006 year = 1962 year = 1931 ESDC 2010 - 82
  • 83. XML Processing Options • Reading XML – Special Groovy support: XmlParser, XmlSlurper, DOMCategory • All support GPath, XmlSlurper features Lazy loading – Or Groovy sugar for your current favorites: DOM, SAX, StAX, DOM4J, JDom, XOM, XPath, XSLT, XQuery, etc. • Creating XML – Special Groovy support: MarkupBuilder and © ASERT 2006-2010 StreamingMarkupBuilder – Or again, enhanced syntax for your current favorites • Updating XML – Using above: read followed by create – Can be done with XmlParser, XmlSlurper, DOMCategory – Or with your Java favorites • Verifying XML – Also DTD, W3C XML Schema, Relax NG in a similar fashion to Java mechanisms for these features ESDC 2010 - 83
  • 84. More Details: XmlSlurper def records = new XmlSlurper().parse("records.xml") assert 3 == records.car.size() // 3 records in total assert 10 == records.depthFirst().collect{ it }.size() // 10 nested nodes // test properties of the first record def firstRecord = records.car[0] assert 'car' == firstRecord.name() assert 'Holden' == firstRecord.@make.toString() && 'Australia' == firstRecord.cou // 2 cars have an 'e' in the make assert 2 == records.car.findAll{ it.@make.toString().contains('e') }.size() © ASERT 2006-2010 // 2 cars have an 'e' in the make assert 2 == records.car.findAll{ it.@make =~ '.*e.*' }.size() // makes of cars that have an 's' followed by an 'a' in the country assert ['Holden', 'Peel'] == records.car.findAll{ it.country =~ '.*s.*a.*' }.@make.coll // types of records assert ['speed', 'size', 'price'] == records.depthFirst().grep{ it.@type != '' }.'@type'* assert ['speed', 'size', 'price'] == records.'**'.grep{ it.@type != '' }.'@type'*.toString // check parent() operator def countryOne = records.car[1].country assert 'Peel' == countryOne.parent().@make.toString() && 'Peel' == countryOne.'. // names of cars with records sorted by year def names = records.car.list().sort{ it.@year.toInteger() }.'@name'*.toString() assert ['Royale', 'P50', 'HSV Maloo'] == names ESDC 2010 - 84