G*

JJUG CCC 2011 Spring
           @kiy0taka
※ kiy0taka 0
G*
Groovy?
HelloWorld.java

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}
HelloWorld.groovy

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}


    Java
HelloWorld.groovy

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!")
  }
}
HelloWorld.groovy

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println "Hello, World!"
  }
}
HelloWorld.groovy

public static void main(String[] args) {
  System.out.println "Hello, World!"
}
HelloWorld.groovy


System.out.println "Hello, World!"




          main
HelloWorld.groovy


   println "Hello, World!"




   System.out.println → println
One-Liner


groovy -e "println 'Hello, World!'"
Java



 def file = new File("./hoge.txt")
def text = new File("./hoge.txt").text
Web



new URL('http://www.java-users.jp/contents/').getText('UTF-8')
String

println 'ls -la /opt/local'.execute().text

total 8
drwxr-xr-x    12   root    admin     408   11   23   19:32   .
drwxr-xr-x     3   root    admin     102   11    7   14:34   ..
drwxr-xr-x     5   root    wheel     170   11   24   13:02   Library
drwxr-xr-x   686   root    admin   23324   11   27   18:06   bin
drwxr-xr-x    25   root    admin     850   11   24   17:01   etc
drwxr-xr-x   177   root    admin    6018   11   24   17:01   include
drwxr-xr-x   988   root    admin   33592   11   24   17:01   lib
drwxr-xr-x    22   root    admin     748   11   24   16:17   libexec
lrwxr-xr-x     1   65534   wheel       9   11   23   18:42   man -> share/man
drwxr-xr-x     5   root    admin     170   11   24   13:37   sbin
drwxr-xr-x    76   root    admin    2584   11   27   18:06   share
drwxr-xr-x     8   root    admin     272   11   24   13:02   var
import

  import   java.lang
  import   java.math
  import   java.io
  import   java.net
  import   java.util
  import   groovy.lang
  import   groovy.util
Java


import org.apache.poi.hssf.usermodel.*

def workBook = new HSSFWorkbook(new File('./foo.xls')
workBook.newInputStream()).sheets.each { sheet ->
    sheet.firstRowNum.upto(sheet.lastRowNum) {
        sheet.getRow(it).with { row ->
            row.firstCellNum.upto(row.lastCellNum - 1) {
                println row.getCell(it).stringCellValue
            }
        }
    }
}
jar

@Grab('org.apache.poi:poi:3.2-FINAL')
import org.apache.poi.hssf.usermodel.*

def workBook = new HSSFWorkbook(new File('./foo.xls')
workBook.newInputStream()).sheets.each { sheet ->
    sheet.firstRowNum.upto(sheet.lastRowNum) {
        sheet.getRow(it).with { row ->
            row.firstCellNum.upto(row.lastCellNum - 1) {
                println row.getCell(it).stringCellValue
            }
        }
    }
}
Ant
 def ant = new AntBuilder()

 ant.unzip(src: 'xxx.zip', dest:'dest')

 ant.mail(mailhost:'hostname', subject:'hello',
   charset:'utf-8',
   user:user,
   password:password) {
     from address:'xxx@example.com'
     to address:'kiy0taka333@gmail.com'
     message 'Hello World!'
 }
// Groovy
$ time groovy -e "println 'Hello'"
Hello

real!0m1.292s
user!0m1.283s
sys! 0m0.192s


// GroovyServ
$ time groovyclient -e "println 'Hello'"
Hello

real!0m0.036s
user!0m0.001s
sys! 0m0.003s
Swing(Java)
                                                                       contentPane.add(button);
package sample;
                                                                       setDefaultCloseOperation(EXIT_ON_CLOSE);
import   java.awt.Container;                                           pack();
import   java.awt.GridLayout;                                          setVisible(true);
import   java.awt.event.ActionEvent;                               }
import   java.awt.event.ActionListener;
                                                                   public static void main(String[] args) {
import   javax.swing.JButton;                                          SwingUtilities.invokeLater(new Runnable() {
import   javax.swing.JFrame;                                               public void run() {
import   javax.swing.JLabel;                                                   new Hello();
import   javax.swing.JTextArea;                                            }
import   javax.swing.SwingUtilities;                                   });
                                                                   }
public class Hello extends JFrame {                            }

    public Hello() {
        super("Hello");

          Container contentPane = getContentPane();
          contentPane.setLayout(new GridLayout(3, 1));

          JLabel label = new JLabel("Label");
          contentPane.add(label);

          JTextArea textArea = new JTextArea("Text Area");
          textArea.setColumns(20);
          textArea.setRows(2);
          contentPane.add(textArea);

          JButton button = new JButton("Button");
          button.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent evt) {
                  ...
              }
          });
Groovy
import groovy.swing.SwingBuilder

new SwingBuilder().edt {
    frame(title:'Hello', show:true, pack:true) {
        gridLayout(cols:1, rows:3)
        label 'Label'
        textArea('Text Area', rows:2, columns:20)
        button('Button', actionPerformed:{ evt ->
            ...
        })
    }
}
SwingBuilder
import groovy.swing.SwingBuilder

new SwingBuilder().edt {
    frame(show:true, pack:true) {
        tableLayout {
            tr {
                 td { label 'UserName: ' }
                 td { textField columns:20 }
            }
            tr {
                 td { label 'Password: ' }
                 td { passwordField columns:20 }
            }
            tr {
                 td(colspan:2) { button 'Login' }
            }
        }
    }
}
https://gist.github.com/913279
h2console.groovy
@Grab('org.mortbay.jetty:jetty-embedded:6.1.25')
@Grab('com.h2database:h2:1.2.144')
@Grab('mysql:mysql-connector-java:5.1.13')
import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.Context
import org.h2.server.web.WebServlet

def server = new Server(8080)
new Context(server, "/", Context.SESSIONS)
  .addServlet(WebServlet, "/*")
server.start()



        https://gist.github.com/717932
please show the
square_root of 100
show = { println it }
square_root = { Math.sqrt(it) }

def please(action) {
  [the: { what ->
     [of: { n -> action(what(n)) }]
  }]
}

please(show).the(square_root).of(100)
show = { println it }
square_root = { Math.sqrt(it) }

def please(action) {
  [the: { what ->
     [of: { n -> action(what(n)) }]
  }]
}

please show the square_root of 100
Object.metaClass.     =
Object.metaClass.     =
{ clos -> clos(delegate) }

    = { it }
          = { println it }
     = { Math.sqrt(it) }

    100
import static groovyx.gpars.GParsPool.withPool

def list = [1, 2, 3, 4, 5]

withPool {
  def result = list.collectParallel { it * 2 }
  assert result == [2, 4, 6, 8, 10]
}
import groovy.json.*       def slurper = new JsonSlurper()
                           def json = slurper.parseText(text)

def text = '''[            assert json == [
  ["aaa", "bbb", "ccc"],     ["aaa", "bbb", "ccc"],
  {                          [
     "key1" : "value1",         "key1" : "value1",
     "key2" : "value2",         "key2" : "value2",
     "key3" : "value3",         "key3" : "value3",
     "key4" : ""                "key4" : ""
  },                         ],
  ["ddd", "eee", "fff"]      ["ddd", "eee", "fff"]
]                          ]
'''
import groovy.json.*

def json = new JsonBuilder()
json (
  ["aaa", "bbb", "ccc"],
  [
     "key1" : "value1",
     "key2" : "value2",
     "key3" : "value3",
     "key4" : ""
  ],
  ["ddd", "eee", "fff"]
)

println json
import org.gcontracts.annotations.*

@Invariant({ speed() >= 0 })
class Rocket {

    @Requires({ isStarted() })
    @Ensures({ old.speed < speed })
    def accelerate() { ... }

    boolean isStarted() { ... }
    def speed() { ... }

}
def plus2 = { it + 2 }
def times3 = { it * 3 }

def times3plus2 = plus2 << times3
assert times3plus2(3) == 11
assert times3plus2(4) == plus2(times3(4))

def plus2times3 = times3 << plus2
assert plus2times3(3) == 15
assert plus2times3(5) == times3(plus2(5))

assert times3plus2(3) == (times3 >> plus2)(3)
@Log
import groovy.util.logging.*

@Log
class Car {
     Car() {
         log.info 'Car constructed'
     }
}

def c = new Car()



  @Commons     @Log4j   @Slf4j
@Log    @Commons     @Log4j    @Slf4j
          @Field    @PackageScope
   @AutoClone      @AutoExternalizable
  @ThreadInterrupt      @TimedInterrupt
  @ConditionalInterrupt          @ToString
@EqualsAndHashCode      @TupleConstructor
  @Canonical       @InheritConstructors
    @WithReadLock      @WithWriteLock
               @ListenerList
Grails
create-app            generate-all
create-controller     generate-controller
create-domain-class   generate-views
create-script         package
create-service        run-app
create-tag-lib        run-war
create-unit-test      test-app
package myapp

class Message {

    String text

    static constraints = {
        text blank:false, maxSize:500
    }
}
package myapp

class MessageController {

    static scaffold = true
}
Gaelyk:Controller

 log.info "Setting attribute datetime"

 request.datetime = new Date().toString()

 log.info "Forwarding to the template"

 forward '/datetime.gtpl'
Gaelyk:View
<% include '/WEB-INF/includes/header.gtpl' %>

<h1>Date / time</h1>

<p>
       <% log.info "outputing the datetime attribute" %>
       The current date and time:
       ${request.datetime}
</p>

<% include '/WEB-INF/includes/footer.gtpl' %>
Gaelyk:Datastore

import com.google.appengine.api.datastore.Entity

def entity = new Entity("person")
entity.name = "Kiyotaka Oku"
entity.age = 31

entity.save()
datastore      blobstore
  memcache        oauth
  urlFetch      namespace
    mail       capabilities
   images        channel
   users          files
    user         backends
defaultQueue    lifecycle
   queues       localMode
    xmpp           app
Gaelyk:Datastore
import   com.google.appengine.api.datastore.*
import   static com.google.appengine.api.datastore.FetchOptions.Builder.*
import   static com.google.appengine.api.datastore.Query.FilterOperator.*
import   static com.google.appengine.api.datastore.Query.SortDirection.*

def query = new Query('person').with {
    addFilter 'age', GREATER_THAN_OR_EQUAL, 30
    addSort 'name', ASCENDING
}

def persons = datastore.prepare(query).asList(withLimit(21))
Gaelyk:Mail

mail.send sender: "kiy0taka333@gmail.com",
    to: "xxx@example.com",
    subject: "Hello",
    textBody: "Hello, how are you doing?"
Gaelyk:TaskQueue

defaultQueue << [
     countdownMillis: 1000, url: "/task/dailyEmail",
     taskName: "Send daily email newsletter",
     method: 'PUT', params: [date: '20090914'],
     payload: content
]
Griffon
Getting Started
$ griffon create-app myapp
$ cd myapp
$ griffon run-app
Griffon   MVC




MVC
Gradle
apply plugin: 'groovy'

repositories {
    mavenCentral()
}

dependencies {
    groovy 'org.codehaus.groovy:groovy:1.8.0'
    compile 'junit:junit:4.8.2'
}
$ gradle clean build
:clean
:compileJava
:compileGroovy
:processResources
:classes
:jar
:assemble
:compileTestJava
:compileTestGroovy
:processTestResources
:testClasses
:test
:check
:build

BUILD SUCCESSFUL

Total time: 13.766 secs
task checksum << {
    fileList('../antLoadfileResources').each {File file ->
        ant.checksum(file: file, property: "cs_$file.name")
        println "$file.name Checksum: ${ant.properties["cs_$file.name"]}"
    }
}

task loadfile << {
    fileList('../antLoadfileResources').each {File file ->
        ant.loadfile(srcFile: file, property: file.name)
        println "I'm fond of $file.name"
    }
}

File[] fileList(String dir) {
    file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()
}
G*Magazine
G*
JJUG CCC 2011 Spring

JJUG CCC 2011 Spring

  • 1.
    G* JJUG CCC 2011Spring @kiy0taka
  • 2.
  • 3.
  • 4.
  • 5.
    HelloWorld.java public class HelloWorld{ public static void main(String[] args) { System.out.println("Hello, World!"); } }
  • 6.
    HelloWorld.groovy public class HelloWorld{ public static void main(String[] args) { System.out.println("Hello, World!"); } } Java
  • 7.
    HelloWorld.groovy public class HelloWorld{ public static void main(String[] args) { System.out.println("Hello, World!") } }
  • 8.
    HelloWorld.groovy public class HelloWorld{ public static void main(String[] args) { System.out.println "Hello, World!" } }
  • 9.
    HelloWorld.groovy public static voidmain(String[] args) { System.out.println "Hello, World!" }
  • 10.
  • 11.
    HelloWorld.groovy println "Hello, World!" System.out.println → println
  • 12.
  • 14.
    Java def file= new File("./hoge.txt")
  • 15.
    def text =new File("./hoge.txt").text
  • 16.
  • 17.
    String println 'ls -la/opt/local'.execute().text total 8 drwxr-xr-x 12 root admin 408 11 23 19:32 . drwxr-xr-x 3 root admin 102 11 7 14:34 .. drwxr-xr-x 5 root wheel 170 11 24 13:02 Library drwxr-xr-x 686 root admin 23324 11 27 18:06 bin drwxr-xr-x 25 root admin 850 11 24 17:01 etc drwxr-xr-x 177 root admin 6018 11 24 17:01 include drwxr-xr-x 988 root admin 33592 11 24 17:01 lib drwxr-xr-x 22 root admin 748 11 24 16:17 libexec lrwxr-xr-x 1 65534 wheel 9 11 23 18:42 man -> share/man drwxr-xr-x 5 root admin 170 11 24 13:37 sbin drwxr-xr-x 76 root admin 2584 11 27 18:06 share drwxr-xr-x 8 root admin 272 11 24 13:02 var
  • 18.
    import import java.lang import java.math import java.io import java.net import java.util import groovy.lang import groovy.util
  • 19.
    Java import org.apache.poi.hssf.usermodel.* def workBook= new HSSFWorkbook(new File('./foo.xls') workBook.newInputStream()).sheets.each { sheet -> sheet.firstRowNum.upto(sheet.lastRowNum) { sheet.getRow(it).with { row -> row.firstCellNum.upto(row.lastCellNum - 1) { println row.getCell(it).stringCellValue } } } }
  • 20.
    jar @Grab('org.apache.poi:poi:3.2-FINAL') import org.apache.poi.hssf.usermodel.* def workBook= new HSSFWorkbook(new File('./foo.xls') workBook.newInputStream()).sheets.each { sheet -> sheet.firstRowNum.upto(sheet.lastRowNum) { sheet.getRow(it).with { row -> row.firstCellNum.upto(row.lastCellNum - 1) { println row.getCell(it).stringCellValue } } } }
  • 21.
    Ant def ant= new AntBuilder() ant.unzip(src: 'xxx.zip', dest:'dest') ant.mail(mailhost:'hostname', subject:'hello', charset:'utf-8', user:user, password:password) { from address:'xxx@example.com' to address:'kiy0taka333@gmail.com' message 'Hello World!' }
  • 24.
    // Groovy $ timegroovy -e "println 'Hello'" Hello real!0m1.292s user!0m1.283s sys! 0m0.192s // GroovyServ $ time groovyclient -e "println 'Hello'" Hello real!0m0.036s user!0m0.001s sys! 0m0.003s
  • 26.
    Swing(Java) contentPane.add(button); package sample; setDefaultCloseOperation(EXIT_ON_CLOSE); import java.awt.Container; pack(); import java.awt.GridLayout; setVisible(true); import java.awt.event.ActionEvent; } import java.awt.event.ActionListener; public static void main(String[] args) { import javax.swing.JButton; SwingUtilities.invokeLater(new Runnable() { import javax.swing.JFrame; public void run() { import javax.swing.JLabel; new Hello(); import javax.swing.JTextArea; } import javax.swing.SwingUtilities; }); } public class Hello extends JFrame { } public Hello() { super("Hello"); Container contentPane = getContentPane(); contentPane.setLayout(new GridLayout(3, 1)); JLabel label = new JLabel("Label"); contentPane.add(label); JTextArea textArea = new JTextArea("Text Area"); textArea.setColumns(20); textArea.setRows(2); contentPane.add(textArea); JButton button = new JButton("Button"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { ... } });
  • 27.
    Groovy import groovy.swing.SwingBuilder new SwingBuilder().edt{ frame(title:'Hello', show:true, pack:true) { gridLayout(cols:1, rows:3) label 'Label' textArea('Text Area', rows:2, columns:20) button('Button', actionPerformed:{ evt -> ... }) } }
  • 28.
    SwingBuilder import groovy.swing.SwingBuilder new SwingBuilder().edt{ frame(show:true, pack:true) { tableLayout { tr { td { label 'UserName: ' } td { textField columns:20 } } tr { td { label 'Password: ' } td { passwordField columns:20 } } tr { td(colspan:2) { button 'Login' } } } } }
  • 29.
  • 31.
    h2console.groovy @Grab('org.mortbay.jetty:jetty-embedded:6.1.25') @Grab('com.h2database:h2:1.2.144') @Grab('mysql:mysql-connector-java:5.1.13') import org.mortbay.jetty.Server import org.mortbay.jetty.servlet.Context importorg.h2.server.web.WebServlet def server = new Server(8080) new Context(server, "/", Context.SESSIONS) .addServlet(WebServlet, "/*") server.start() https://gist.github.com/717932
  • 33.
  • 34.
    show = {println it } square_root = { Math.sqrt(it) } def please(action) { [the: { what -> [of: { n -> action(what(n)) }] }] } please(show).the(square_root).of(100)
  • 35.
    show = {println it } square_root = { Math.sqrt(it) } def please(action) { [the: { what -> [of: { n -> action(what(n)) }] }] } please show the square_root of 100
  • 36.
    Object.metaClass. = Object.metaClass. = { clos -> clos(delegate) } = { it } = { println it } = { Math.sqrt(it) } 100
  • 39.
    import static groovyx.gpars.GParsPool.withPool deflist = [1, 2, 3, 4, 5] withPool { def result = list.collectParallel { it * 2 } assert result == [2, 4, 6, 8, 10] }
  • 41.
    import groovy.json.* def slurper = new JsonSlurper() def json = slurper.parseText(text) def text = '''[ assert json == [ ["aaa", "bbb", "ccc"], ["aaa", "bbb", "ccc"], { [ "key1" : "value1", "key1" : "value1", "key2" : "value2", "key2" : "value2", "key3" : "value3", "key3" : "value3", "key4" : "" "key4" : "" }, ], ["ddd", "eee", "fff"] ["ddd", "eee", "fff"] ] ] '''
  • 42.
    import groovy.json.* def json= new JsonBuilder() json ( ["aaa", "bbb", "ccc"], [ "key1" : "value1", "key2" : "value2", "key3" : "value3", "key4" : "" ], ["ddd", "eee", "fff"] ) println json
  • 44.
    import org.gcontracts.annotations.* @Invariant({ speed()>= 0 }) class Rocket { @Requires({ isStarted() }) @Ensures({ old.speed < speed }) def accelerate() { ... } boolean isStarted() { ... } def speed() { ... } }
  • 45.
    def plus2 ={ it + 2 } def times3 = { it * 3 } def times3plus2 = plus2 << times3 assert times3plus2(3) == 11 assert times3plus2(4) == plus2(times3(4)) def plus2times3 = times3 << plus2 assert plus2times3(3) == 15 assert plus2times3(5) == times3(plus2(5)) assert times3plus2(3) == (times3 >> plus2)(3)
  • 48.
    @Log import groovy.util.logging.* @Log class Car{ Car() { log.info 'Car constructed' } } def c = new Car() @Commons @Log4j @Slf4j
  • 49.
    @Log @Commons @Log4j @Slf4j @Field @PackageScope @AutoClone @AutoExternalizable @ThreadInterrupt @TimedInterrupt @ConditionalInterrupt @ToString @EqualsAndHashCode @TupleConstructor @Canonical @InheritConstructors @WithReadLock @WithWriteLock @ListenerList
  • 51.
  • 52.
    create-app generate-all create-controller generate-controller create-domain-class generate-views create-script package create-service run-app create-tag-lib run-war create-unit-test test-app
  • 54.
    package myapp class Message{ String text static constraints = { text blank:false, maxSize:500 } }
  • 55.
    package myapp class MessageController{ static scaffold = true }
  • 63.
    Gaelyk:Controller log.info "Settingattribute datetime" request.datetime = new Date().toString() log.info "Forwarding to the template" forward '/datetime.gtpl'
  • 64.
    Gaelyk:View <% include '/WEB-INF/includes/header.gtpl'%> <h1>Date / time</h1> <p> <% log.info "outputing the datetime attribute" %> The current date and time: ${request.datetime} </p> <% include '/WEB-INF/includes/footer.gtpl' %>
  • 65.
    Gaelyk:Datastore import com.google.appengine.api.datastore.Entity def entity= new Entity("person") entity.name = "Kiyotaka Oku" entity.age = 31 entity.save()
  • 66.
    datastore blobstore memcache oauth urlFetch namespace mail capabilities images channel users files user backends defaultQueue lifecycle queues localMode xmpp app
  • 67.
    Gaelyk:Datastore import com.google.appengine.api.datastore.* import static com.google.appengine.api.datastore.FetchOptions.Builder.* import static com.google.appengine.api.datastore.Query.FilterOperator.* import static com.google.appengine.api.datastore.Query.SortDirection.* def query = new Query('person').with { addFilter 'age', GREATER_THAN_OR_EQUAL, 30 addSort 'name', ASCENDING } def persons = datastore.prepare(query).asList(withLimit(21))
  • 68.
    Gaelyk:Mail mail.send sender: "kiy0taka333@gmail.com", to: "xxx@example.com", subject: "Hello", textBody: "Hello, how are you doing?"
  • 69.
    Gaelyk:TaskQueue defaultQueue << [ countdownMillis: 1000, url: "/task/dailyEmail", taskName: "Send daily email newsletter", method: 'PUT', params: [date: '20090914'], payload: content ]
  • 71.
  • 72.
    Getting Started $ griffoncreate-app myapp $ cd myapp $ griffon run-app
  • 73.
    Griffon MVC MVC
  • 77.
  • 78.
    apply plugin: 'groovy' repositories{ mavenCentral() } dependencies { groovy 'org.codehaus.groovy:groovy:1.8.0' compile 'junit:junit:4.8.2' }
  • 79.
    $ gradle cleanbuild :clean :compileJava :compileGroovy :processResources :classes :jar :assemble :compileTestJava :compileTestGroovy :processTestResources :testClasses :test :check :build BUILD SUCCESSFUL Total time: 13.766 secs
  • 80.
    task checksum <<{ fileList('../antLoadfileResources').each {File file -> ant.checksum(file: file, property: "cs_$file.name") println "$file.name Checksum: ${ant.properties["cs_$file.name"]}" } } task loadfile << { fileList('../antLoadfileResources').each {File file -> ant.loadfile(srcFile: file, property: file.name) println "I'm fond of $file.name" } } File[] fileList(String dir) { file(dir).listFiles({file -> file.isFile() } as FileFilter).sort() }
  • 83.
  • 84.