+ All Categories
Home > Technology > Groovy ecosystem: efficient & friendly

Groovy ecosystem: efficient & friendly

Date post: 20-Jan-2017
Category:
Upload: aestas-it
View: 1,693 times
Download: 0 times
Share this document with a friend
103
01
Transcript

01

About me02

Andrey AdamovichBio: Developer, coach, speaker, author

Company: Aestas/IT (http://aestasit.com)

E­mail: [email protected]

Linkedin: http://www.linkedin.com/in/andreyadamovich

Lanyrd: http://lanyrd.com/profile/andrey­adamovich

GitHub: https://github.com/aadamovich

SO: http://stackoverflow.com/users/162792/andrey­adamovich

Twitter: @codingandrey, @aestasit

••••••••

03

What is Groovy?Groovy is a dynamic language for the JVM.

It is built upon features of Java langauge, but adds more goodies

derived from languages like Python, Ruby and SmallTalk.

••

04

History2003: inception

2007: 1.0 released

2012: 2.0 released

2016: 3.0 planned

••••

05

Who is using Groovy?

06

InstallingGroovy

07

Groovy consoleAfter Groovy is installed you can launch a  groovyConsole :•

08

Groovy shellor  groovySh  if you prefer command­line:•

09

Languagebasics

10

Hello, Groovy!println "Hello, World!"01.

11

Variablesdef title = "Groovy is cool!"

def year = 2015

def rate = 0.702

String name = "John"

def isExecuted = true

test = new Object()

01.

02.

03.

04.

05.

06.

12

TypesAll Java types are available:

int ,  long ,  double ,  float ,  boolean ,  char ,  byte ,  short ,

String ,  Date ,  Calendar ,  File ,...

13

Groovy = Java + Groovy extensionsGroovy is built on top of Java.

All classes that are part of Java can be used in Groovy.

Groovy adds additional functionality to some Java classes.

•••

14

StringsThis is Java's String API:

http://docs.oracle.com/javase/8/docs/api/java/lang/String.html.

This is Groovy's extensions to String API: http://docs.groovy­

lang.org/latest/html/groovy­jdk/java/lang/String.html.

15

String interpolationdef name = "John"

def greeting = "Hello, $name"

01.

02.

16

Multi­line stringsWithout string interpolation:

def POEM = '''Two households, both alike in dignity,

In fair Verona, where we lay our scene,

From ancient grudge break to new mutiny,

Where civil blood makes civil hands unclean.'''

```

01.

02.

03.

04.

05.

17

Multi­line stringsWith string interpolation:

def city = 'Verona'

def POEM2 = """Two households, both alike in dignity,

In fair ${city}, where we lay our scene,

From ancient grudge break to new mutiny,

Where civil blood makes civil hands unclean."""

01.

02.

03.

04.

05.

18

OperatorsNumbers:  a + b ,  a ‐ b ,  a * b ,  a ** b ,  a / b ,  a % b ,

a++ ,  ++a ,  a‐‐ ,  ‐‐a ,  ‐a ,  +a

Bits:  a | b ,  a & b ,  a ^ b ,  a << b ,  a >> b

Booleans:  a || b ,  a && b ,  a ^^ b ,  ~a

Comparison:  a == b ,  a != b ,  a <=> b ,  a > b ,  a >= b ,  a <

b ,  a <= b

Regular expressions:  str =~ pattern ,  str ==~ pattern

Objects:  obj?.child ,  obj*.children ,  obj.@field ,

obj.&method

•••

••

19

ConditionalsNo surprises:

if (condition) {

  ... some code ...

} else {

  ... some code ...

}

01.

02.

03.

04.

05.

20

Groovy truthAny expression can be mapped to a boolean value according to

Groovy's truth:

0  is  false , all other numbers are  true

empty  String  is false, all other  String s are  true

empty collection is  false , non­empty collections are  true

null  is  false , all other objects are  true

••••

21

Elvis operator (?:)Shorthand for  if  statements:

def result = condition ? true_result : false_result

or in short:

def result = true_result ?: false_result

01.

01.

22

Elvis operator (?:)This one:

def userName = user.name ? user.name : "none"

is the same as this one:

def userName = user.name ?: "none"

01.

01.

23

Safe navigation operator (?.)If you have nested object structure that may have missing

components, then safe navigation operator can save you from

NullPointerException s.

24

Safe navigation operator (?.)For example, this expression is risky:

def cityName = person.address.city.name01.

25

Safe navigation operator (?.)But this one will return  null  in case at least one of the expression

components is  null :

def cityName = person?.address?.city?.name01.

26

Functionsdef calculate(int a, String str) {

  return a + str.length

}

01.

02.

03.

27

Function's resultIf return statement is absent then last expression value is considered

the result of a function:

def calculate(int a, String str) { a + str.length }01.

28

CollectionsLists:

def numbers = [5, 32, 21, 22]

println numbers[0]

01.

02.

29

CollectionsMaps:

def chars = [a: 11, b: 2, c: 73]

println chars['b']

println chars.c

01.

02.

03.

30

Collection typesYou can define collection type you want to have:

def numbers = [1, 2, 3, 3, 4] as Set01.

31

Useful typesList  ­ the default collection type ­ list of elements stored in insertion

order.

Set  ­ a collection of unique elements stored in no particular order.

SortedSet  ­ a collection of unique elements stored in sorted order.

LinkedHashSet  ­ a collection of unique elements stored in insertion

order.

Map  ­ a collection of key/value pairs stored in no particular order.

TreeMap  ­ a map stored in order sorted by the key.

LinkedHashMap  ­ a map stored in insertion order.

•••

••• 32

LoopsNo surprises:

def x = 0

for (i in 0..9)  {

  x += i

}

01.

02.

03.

04.

33

Loopsdef numbers = [1, 2, 3, 3, 4] as Set

for (n in numbers)  { 

  println n

}

01.

02.

03.

04.

34

Loopsdef x = 0

def y = 5

while ( y‐‐ > 0 ) {

  x++

}

01.

02.

03.

04.

05.

35

ClosuresClosure in Groovy is an anonymous function that can be called and

passed to other functions.

def square = { it * it }

println square(9)

def squares = [ 1, 2, 3, 4 ].collect(square)

println squares

01.

02.

03.

04.

36

IteratorsGroovy's collection API is coming with many closure­based methods

for collection iteration:

numbers.each { n ‐>

  prinln n

}

01.

02.

03.

37

Finders... and collection searching and filtering:

println numbers.findAll { it > 5 }01.

38

Collection APIJava API:

http://docs.oracle.com/javase/8/docs/api/java/util/Collection.html

http://docs.oracle.com/javase/8/docs/api/java/util/List.html

http://docs.oracle.com/javase/8/docs/api/java/util/Map.html

•••

39

Collection APIGroovy API:

http://docs.groovy­lang.org/latest/html/groovy­

jdk/java/util/Collection.html

http://docs.groovy­lang.org/latest/html/groovy­jdk/java/util/List.html

http://docs.groovy­lang.org/latest/html/groovy­jdk/java/util/Set.html

http://docs.groovy­lang.org/latest/html/groovy­jdk/java/util/Map.html

•••

40

Using closures to define a DSLClosures can be used to "wrap" around some code.

def safeResource(Closure closure) {

  def resource = new ExpensiveResource()

  try {

    resource.open()

    closure(resource)

  } finally {

    resource?.close()

  }

}

01.

02.

03.

04.

05.

06.

07.

08.

09.41

Using closures to define a DSLsafeResource { it ‐> 

  it.writeData("hello world!") 

}

01.

02.

03.

42

Regular expressionsdef input = "The Groovy Cook Book contains Groovy recipes"

if (input =~ /^.*?Groovy.*$/) {

  println "Found Groovy"

}

01.

02.

03.

04.

43

Group matchingdef input = "The Groovy Cook Book contains Groovy recipes"

def matcher = input =~ /^.*?(Groovy).*$/

println matcher[0][1]

01.

02.

03.

44

String splittingdef input = "name;address;city"

def fields = input.split(';')

01.

02.

45

Search and replacedef input = "The Groovy Cook Book contains Groovy recipes"

input.replaceAll('.oo..', 'DROOPY')

println input.replaceAll(/.oo../) { match ‐>

  match.toUpperCase()

}

01.

02.

03.04.

05.

06.

46

FilesFile  object represents abstract path of a file or directory e.g.:

def configFile = new File('config.xml')

def dataDir = new File('data')

01.

02.

47

File APIJava API: http://docs.oracle.com/javase/8/docs/api/java/io/File.html

Groovy extensions: http://docs.groovy­lang.org/latest/html/groovy­

jdk/java/io/File.html

48

Reading from a fileString textContent = file.text

byte[] binaryContent = file.bytes

01.

02.

49

Reading from a filedef lines = file.readLines()

lines.each { String line ‐>

  println line

}

01.

02.03.

04.

05.

50

Reading from a filefile.eachByte { int byte ‐>

  // do something with byte

}

01.

02.

03.

51

Writing to a filefile.text = '''What's in a name? That which we call a rose

By any other name would smell as sweet.'''

01.

02.

52

Writing to a filefile << "What's in a name? That which we call a rose\n"

file << "By any other name would smell as sweet."

01.

02.

53

Writing to a filefile.bytes = [ 65, 66, 67, 68 ] as byte[]01.

54

Useful utilitiesJsonSlurper

JsonBuilder

XmlSlurper

MarkupBuilder

HttpBuilder

ConfigSlurper

••••••

55

Ecosystem56

Grape57

SDKMAN!58

Automation59

Gradle60

Projects and tasksMain concepts in Gradle are Project and Task.

Project consists of a set of tasks and settings.

Task is a logical action performing certain things within project context.

It has access to project information and settings.

Tasks may depend on other tasks.

Project can consist of several sub­projects.

In this case, it is called multi­project build.

•••••••

61

Gradle's DSLGradle's build language is a Groovy­based DSL that is built around

Project and Task API.

Extensive documentation can be found here:

http://gradle.org/docs/current/dsl/index.html.

62

Hello, Gradle!build.gradle :

task hello << {

  println 'Hello, World'

}

01.

02.

03.

63

Hello, Gradle!Console output:

>gradle hello

:hello

Hello, World!

BUILD SUCCESSFUL

Total time: 0.401 secs

01.

02.

03.

04.

05.

64

Task configuration & executionbuild.gradle :

task hello

ext.message = "What's up?"

hello {

  println "Configuring hello task."

  ext.message = 'Hello, World!'

}

01.

02.

03.

04.

05.

06.

65

Task configuration & executionhello << {

  println message 

}

hello << {

  println project.message

}

01.

02.

03.

04.05.

06.

07.

66

Task configuration & executionConsole output:

>gradle hello

Configuring hello task.

:hello

Hello, World!

What's up?

BUILD SUCCESSFUL

Total time: 0.058 secs

01.

02.

03.

04.

05.

06.

07.

67

Gradle is Groovy, Groovy is JavaJava:

import java.io.File;

...

String parentDir = new File('test.txt')

                    .getAbsoluteFile()

                    .getParentPath();

01.

02.

03.

04.

05.

68

Gradle is Groovy, Groovy is JavaGroovy:

def parentDir = new File('test.txt')

                  .absoluteFile

                  .parentPath

01.

02.

03.

69

Gradle is Groovy, Groovy is JavaGradle:

parentDir = file('test.txt').absoluteFile.parentPath01.

70

Task dependenciesbuild.gradle :

task hello << {

  print 'Hello, '

}

task world(dependsOn: hello) << {

  println 'World!'

}

01.

02.

03.

04.

05.

06.

71

Task dependenciesConsole output:

>gradle ‐q hello world

Hello, World!

>gradle ‐q world

Hello, World!

01.

02.

03.04.

05.

72

Dynamic tasks4.times { counter ‐>

  task "task$counter" << {

    println "I'm task number $counter"

  }

}

01.

02.

03.

04.

05.

73

Task rulestasks.addRule("Pattern: ping<ID>") { String taskName ‐>

  if (taskName.startsWith("ping")) {

    task(taskName) << {

      println "Pinging: " + (taskName ‐ 'ping')

    }

  }

}

01.

02.

03.

04.

05.

06.

07.

74

Task rulestask groupPing {

  dependsOn pingServer1, pingServer2

}

01.

02.

03.

75

Failing the buildTo fail the build you can just throw an exception with descriptive

message:

throw new GradleException("Failed because of ....")01.

76

Functions and variablesYou can define local variables and functions inside your build script

like you would do in Groovy ( def ).

Those variables and functions will only be visible within that script.

77

Default tasksIf you run Gradle command with no tasks specified, then it will fall back

to the list of default tasks if they are defined:

defaultTasks 'build'01.

78

Task graphgradle.taskGraph.whenReady { taskGraph ‐>

  if (taskGraph.hasTask(release)) {

    version = '1.0'

  } else {

    version = '1.0‐SNAPSHOT'

  }

}

01.

02.

03.

04.

05.

06.

07.

79

Task graphgradle.taskGraph.beforeTask { Task task ‐>

  println "executing $task ..."

}

01.

02.

03.

80

Task graphgradle.taskGraph.afterTask { Task task, TaskState state ‐>

  if (state.failure) {

    println "FAILED"

  } else {

    println "done"

  }

}

01.

02.

03.

04.

05.

06.

07.

81

WebDevelopment

82

Grails83

Ratpack84

Testing85

Spock86

Cucumber87

Geb88

DesktopApplication89

Griffon90

Groovyshines atDSLs!

91

Let's build aDSL!

92

Readingmaterial

93

Groovy 2 Cookbook

94

Groovy in action

95

Groovy for DSLs

96

Making Java Groovy

97

Programming Groovy 2

98

Building & testing with Gradle

99

Gradle: effective implementation guide

100

Q & A101

Let the forcebe with you!

102

Thank you!103


Recommended