SlideShare a Scribd company logo
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
SPRINGONE2GX
WASHINGTON, DC
Grooscript in Action
By Jorge Franco Leza
@jfrancoleza
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
About me
2
Developer
jorge.franco.leza@gmail.com
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Thank you!
3
3 years since first commit
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Agenda
• Introduction to grooscript
• Convert your groovy code to javascript
• Support
• PhantomJs and tools
• Gradle plugin
• Demo
• Grails plugin
• Working with javascript
• Require.js
• Future
4
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Introduction to grooscript
• Library (jar)
• Groovy 2.0+ to javascript ECMA 5
• Apache 2 license
• Source code http://github.com/chiquitinxx/grooscript
• Converted code needs grooscript.js to run
• Tools around: gradle and grails plugins, npm and bower packages
• Documentation http://grooscript.org/doc.html
• Demos http://github.com/chiquitinxx/grooscript-demos
• Try live! http://grooscript.org/conversions.html
5
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Why grooscript?
• You have all java / groovy tools to create code in the client side.
• Javascript is fast.
• Enjoy javascript! Create your own magic.
• Don’t repeat code in two languages, isomorphic code.
• Use groovy templates everywhere.
• Single development environment.
• Stop learning “to javascript” things.
• Static type if you want to.
• But… mainly… because it is…
6
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Groovy
7
Readable
Concise
Expressive
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
ASTS
8
@Component

class Counter implements Colorable {



Integer number



void init() {

number = null

}



void render() {

div(class: "widget bg-${randomColor()}") {

if (number) {

p 'Number of books'

em number.toString()

a(href:"#", class:"button",
onclick: 'bookPresenter.showBooks()') {

yield 'Show'

}

} else {

p 'Counting books...'

}

}

}

}
AST’s
Getter / Setters
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
List and maps
9
def start() {
def countries = loadCountries().
findAll { it.population > 100000}.
unique { it.alpha3Code }
countries.each { country ->
customSigma.addNode id: country.alpha3Code,
x: country.latlng[1], color: ‘purple’
}
countries.each { country ->
country.borders?.each { border ->
this.&hello(border)
}
}
updateNumberCountries countries.size()
customSigma.refresh()
}
Lists and maps
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
DSL's
10
server {
get('/') {
render Templates.applyTemplate('index.gtpl')
}
on('login') { data, socket ->
if (data.name && !socket.login) {
socket.login = data.name
socket.emit 'loginok', [name: data.name]
socket.broadcast.emit 'loginok', [name: data.name]
}
}
on('msg') { data, socket ->
if (data.msg && socket.login) {
socket.broadcast.emit 'msg', [msg: data.msg]
}
}
on('disconnect') { socket ->
if (socket.login) {
socket.broadcast.emit 'off', [name: socket.login]
}
}
}.start()
Dsl’s
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Metaprogramming
11
class Hello {
def methodMissing(String name, args) {
println "Hello ${name}!"
}
}
def hello = new Hello()
hello.Groovy()
hello.Javascript()
hello.grooscript()
Metaprogramming
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Functional
12
def plus2 = { it + 2 }
def times3 = { it * 3 }
def times3plus2 = plus2 << times3
assert times3plus2(3) == 11
def plus2times3 = times3 << plus2
assert plus2times3.curry(5)() == 21
Functional
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Convert your groovy code to javascript
13
@Grab('org.grooscript:grooscript:1.2.0')
import org.grooscript.GrooScript
String result = GrooScript.convert '''
def sayHello = { println "Hello ${it}!" }
['Groovy','JavaScript','GrooScript'].each sayHello
'''
new File(‘out.js’) << result
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Convert your groovy code to javascript
14
Let’s see it in action
http://grooscript.org/doc.html
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Conversion options
• classpath
• customization { -> ast(TypeChecked)}
• initialText, finalText
• recursive
• mainContextScope [''$'', ‘'window'', ''myFunction'']
• addGsLib
• requireJsModule
• consoleInfo
• includeDependencies
15
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Support
• Groovy core
• Classes, numbers, lists, maps, sets, date, ranges, closures, (g)strings, operators,
groovy truth, Expando, categories, traits, beans, switch, metaprogramming,
enum, equals, multiple assignment, optional params, default constructor, pointer
methods, operator overload, regular expressions, @Delegate, @Category, …
• Dsl’s. (@DelegatesTo)
• Ast’s at semantic analysis phase.
• Packaging in js with require.js.
• Be groovier!
16
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Not supported
• Not groovy-core (json, builders, I/O, …)
• Java / Groovy Types (Thread, LinkedHashMap, Stack, Optional, …)
• Super except constructors.
• Methods with same name (overload), classes with same name.
• Java 8 stuff not supported by groovy
• Module extensions, complex metaprogramming, groovy AST’s after Semantic
Phase
17
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Annotations
18
import org.grooscript.asts.GsNotConvert
@GsNotConvert
class ClassNotConvert {
def a
}
class A {
@GsNotConvert
def methodNoConvert() {
‘No!’
}
def hello() {
println ‘Hello!’
}
}
import org.grooscript.asts.GsNative
class Data {
@GsNative
void saySomething(String smt) {/*
console.log(smt);
*/}
@GsNative
def five() {/*
return 5;
*/ 1 + 1 + 3
}
}
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
PhantomJs test
19
@GrabConfig(systemClassLoader = true)
@Grab(‘org.grooscript:grooscript:1.2.0’)
import org.grooscript.asts.PhantomJsTest
//Need phantomjs installed
System.setProperty(‘PHANTOMJS_HOME’, ‘path/to/phantomjs’)
@PhantomJsTest(url = 'http://beta.groovy-lang.org/')
void testCountLinks() {
def links = $('a')
assert links.size() > 40, "Number of links: ${links.size()}"
links.toArray().collect { it.toString() }.each { link ->
println link
}
}
testCountLinks()
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Javascript libs
• grooscript.js (87 kb) (8 kb minified and gziped)
• grooscript.min.js (33 kb)
• grooscript-tools.js (14 kb) (GQuery, HtmlBuilder, Observable)
20
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
HtmlBuilder
21
given:
def result = HtmlBuilder.build {
body {
ul(class: 'list', id: 'mainList') {
2.times { number ->
li number + 'Hello!'
}
}
}
}
expect:
result == "<body><ul class='list' id=‘mainList'>
<li>0Hello!</li><li>1Hello!</li></ul></body>"
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
GQuery
22
import org.grooscript.jquery.GQueryImpl
def result = new Result()
def gQuery = new GQueryImpl()
gQuery.onReady {
gQuery.doRemoteCall(“${JSON_ADDRESS}”, 'GET', null, { res ->
gQuery('.result').html('OK')
result = res
}, {
result = 'FAIL!'
}, Result)
}
https://github.com/chiquitinxx/grooscript/blob/master/src/
main/groovy/org/grooscript/jquery/GQuery.groovy
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Observable
23
given:
def result = []
Observable.from([1, 5, 9, 12, 3, 8]).
filter { it < 5 }.
map { 'H' * it }.
subscribe { event ->
result << event
}
expect:
result == ['H', 'HHH']
https://github.com/chiquitinxx/grooscript/blob/master/src/
test/groovy/org/grooscript/rx/ObservableSpec.groovy
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Gradle plugin
• Starting guide http://grooscript.org/starting_gradle.html
• Listen to changes and does conversions in background.
• Groovy templates in the client side.
• Can use with your grails 3+ application.
• Create require.js modules.
• Notification of changes using websockets.
• Thread tasks can block execution.
• Info about tasks http://grooscript.org/gradle/tasks.html
24
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
task convert
Convert groovy files to javascript. Can add conversion options.
25
grooscript {
source = ['src/main/groovy']
destination = 'js'
}
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 26
task convertThread
grooscript {
source = [‘src/main/groovy/presenters']
destination = 'js'
classpath = ['src/groovy']
initialText = '//Converted file'
recursive = true
blockExecution = true
}
Listen to changes in groovy files, and convert them to javascript when modified. Can
block gradle execution.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 27
task initStaticWeb
"## build.gradle
$## src
$## main
"## groovy
% $## Presenter.groovy
$## webapp
"## index.html
$## js
"## app
$## lib
"## grooscript-tools.js
"## grooscript.min.js
$## jquery.min.js
Creates a static web project to starting play with grooscript.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 28
task templatesJs
class Templates {
static Map<String, Closure> templates
static String applyTemplate(String name, model = [:]) {
Closure cl = templates[name]
cl.delegate = model
cl(model)
}
}
Convert groovy templates to a javascript file.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 29
task templatesThread
templates {
templatesPath = 'templates'
templates = ['main.gtpl', 'little/small.tpl']
destinationFile = 'js/Templates.js'
classpath = ['src/groovy']
customTypeChecker = 'aCustomTypeCheckerFile.groovy'
}
Listen to changes in groovy templates and generate a new javascript template file
when something changes. Can block gradle execution.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 30
task spyChanges
spy {
files = ['Templates.js']
onChanges = { list ->
springWebsocketTo 'http://localhost:8080/demo' data
'templates' onChannel '/app/reload'
}
}
Listen to file changes and execute groovy code when files change. Can send a
message using websockets.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 31
task requireJs
requireJs {
sourceFile = 'src/main/groovy/MyApp.groovy'
destinationFolder = 'src/main/resources/web/js/app'
}
Convert groovy file to require.js javascript module. Also all dependencies are
converted.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
task requireJsThread
32
requireJs {
sourceFile = ‘starting/InitialFile.groovy'
classpath = ['src/main/groovy']
destinationFolder = ‘js/app'
blockExecution = true
}
Listen to changes in groovy file or any dependency file, and generate require.js
javascript modules when files change. Also can block execution.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 33
Demo gradle books
More action
https://github.com/chiquitinxx/books-demo
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Grails plugin
• A grails 2 version, 0.8 https://grails.org/plugin/grooscript.
• Grails 3 version, version 1.1.2, documentation http://grooscript.org/grails3-plugin.
• Adding tags for your gsp’s.
• Converting files with gradle plugin in grails 3+.
• Using your domain classes in your gsp’s. *experimental*
• Uses asset pipeline and cache plugins, also jquery for some tags.
• Requires <asset:javascript src="grooscript-grails.js"/>
• Events in your gsp's with groovy.
• Websockets support using spring websockets.
• Templating in your gsp’s with HtmlBuilder.
34
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
grooscript:code
35
<grooscript:code>
[‘groovy’, ‘javascript’].each {
println “Hello $it”
}
</grooscript:code>
<asset:script>
… js code …
</asset:script>
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
grooscript:template
36
<grooscript:template onLoad=“false" functionName=“refreshList">
ul {
data.each { book ->
li {
p 'Id: ' + book.id + ' Name: ' + book.title
}
}
}
</grooscript:template>
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
websockets
37
<grooscript:initSpringWebsocket>
println 'Connected! Websocket is up!’
GrooscriptGrails.sendWebsocketMessage("/app/hello", “Hello!")
</grooscript:initSpringWebsocket>
<grooscript:onServerEvent path="/topic/books" type="Book">
data.each { book ->
$("#helloDiv").append '<p>'+book.coolFormat()+'</p>'
}
</grooscript:onServerEvent>
Use spring websockets in your gsp’s. Have to include client libraries.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
events
38
<grooscript:code>
$(document).ready {
def eventData = 'Application started.'
gsEvents.sendMessage('newEvent', eventData)
gsEvents.onEvent('delete', { book ->
$('#deleteEvent').html 'Deleted ' + book.title
})
}
</grooscript:code>
<grooscript:onEvent name="newEvent">
console.log event
</grooscript:onEvent>
Manage events in the client using groovy.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
grooscript:remoteModel
39
<grooscript:remoteModel domainClass="Book"/>
<grooscript:code>
import rest.Book
Book.list().then { list ->
$('#bookList').html ''
list.each addBook
}
</grooscript:code>
Use your domain classes from your gsp’s. Domain classes annotated with
@Resource, using json.
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Demo grails 3
40
Final action
https://github.com/chiquitinxx/circles
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Working with javascript
41
class MyClass {} function MyClass() { … }
var myClass = MyClass();
// NO var myClass = new MyClass();
var myClass = MyClass({prop1: ‘value’, prop2: 12 });
myClass.method();
// NO myClass.metaprogrammingMethod();
myClass.method(numberOrStringOrList);
// beware maps! myClass.method({ a: 1, b: 2 });
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Combine both worlds
42
import static org.grooscript.GrooScript.toJavascript
import static org.grooscript.GrooScript.toGroovy
def map = [x: 1, y: 2]
//point is a javascript object
point.init(map) //[BAD] Passing a groovy object to javascript, can fail
point.init(toJavascript(map)) //[GOOD] You now are passing {x: 1, y: 2}
//point has a method info() that returns a javascript object
def badData = point.info() //[BAD] You will have a 'javascript' object
def goodData = toGroovy(point.info()) //[GOOD] goodData as a 'groovy' object
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Tips
• Keep your groovy code tested.
• If you use @GsNative, keep that code in isolated classes, that can be easy to
mock them.
• Don’t abuse @GsNative, is untested code.
• You can activate debug console info in javascript with gs.consoleInfo = true;
• You can test dom manipulation with jsoup.
• Try to stay functional, don’t abuse ‘this’ or variables from other contexts.
• Curry functions to inject variables rather than expecting them to be available
after callbacks hell.
43
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Require.js
• Javascript file and module loader.
• Can be used in browser, rhino and Node.js environments.
• Optimization using google closure compiler.
44
requirejs.config({
baseUrl: 'jsModules',
paths: {
lib: 'js/lib'
}
});
requirejs(['lib/grooscript.min'], function() {
requirejs(['Initial']);
});
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Require.js
45
import org.grooscript.GrooScript
Map conversionOptions = [classpath: 'src/main/groovy']
GrooScript.convertRequireJs('src/main/groovy/Initial.groovy',
'jsModules', conversionOptions)
define(function() {
function Initial() { … }
return Initial;
});
class Initial {
}
src/main/groovy/Initial.groovy jsModules/Initial.js
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Require.js
46
define(['lib/data'], function (data) {
function Require() {
//..
gSobject.data = data;
//..
return gSobject;
};
return Require;
});
package files
import org.grooscript.asts.RequireJsModule
class Require {
@RequireJsModule(path = 'lib/data')
def data
}
src/main/groovy/files/Require.groovy jsModules/files/Require.js
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Future
47
ECMAScript 2015
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 48
Q & A
Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
Thank you!
49
Waiting for your feedback and questions from now to Thursday
Ad

Recommended

Grooscript greach
Grooscript greach
Jorge Franco Leza
 
Grooscript gr8conf 2015
Grooscript gr8conf 2015
Jorge Franco Leza
 
Grooscript greach 2015
Grooscript greach 2015
Jorge Franco Leza
 
Grooscript and Grails 3
Grooscript and Grails 3
Jorge Franco Leza
 
Creating ASTTs The painful truth
Creating ASTTs The painful truth
Mario García
 
NetBeans Support for EcmaScript 6
NetBeans Support for EcmaScript 6
Kostas Saidis
 
Groovy shell scripting
Groovy shell scripting
Georg Berky
 
GroovyFX - groove JavaFX Gr8Conf EU 2017
GroovyFX - groove JavaFX Gr8Conf EU 2017
sascha_klein
 
Embedding Groovy in a Java Application
Embedding Groovy in a Java Application
Paolo Predonzani
 
Rest, sockets em golang
Rest, sockets em golang
jefferson Otoni Lima
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystem
Kostas Saidis
 
Groovy on the shell
Groovy on the shell
sascha_klein
 
GraphQL IN Golang
GraphQL IN Golang
Bo-Yi Wu
 
Introduction to Griffon
Introduction to Griffon
James Williams
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
Fwdays
 
Golang
Golang
Michael Blake
 
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
César Hernández
 
Griffon @ Svwjug
Griffon @ Svwjug
Andres Almiray
 
PyCon Korea 2019 REST API Document Generation
PyCon Korea 2019 REST API Document Generation
용선 이
 
Golang Project Layout and Practice
Golang Project Layout and Practice
Bo-Yi Wu
 
Gradle in 45min
Gradle in 45min
Schalk Cronjé
 
Build microservice with gRPC in golang
Build microservice with gRPC in golang
Ting-Li Chou
 
Groovy And Grails Introduction
Groovy And Grails Introduction
Eric Weimer
 
Understanding how concurrency work in os
Understanding how concurrency work in os
GenchiLu1
 
really really really awesome php application with bdd behat and iterfaces
really really really awesome php application with bdd behat and iterfaces
Giulio De Donato
 
Go at Openprovider
Go at Openprovider
Elena Grahovac
 
When third parties stop being polite... and start getting real
When third parties stop being polite... and start getting real
Charles Vazac
 
Ratpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web Apps
James Williams
 
Grooscript gr8conf
Grooscript gr8conf
GR8Conf
 
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf
 

More Related Content

What's hot (20)

Embedding Groovy in a Java Application
Embedding Groovy in a Java Application
Paolo Predonzani
 
Rest, sockets em golang
Rest, sockets em golang
jefferson Otoni Lima
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystem
Kostas Saidis
 
Groovy on the shell
Groovy on the shell
sascha_klein
 
GraphQL IN Golang
GraphQL IN Golang
Bo-Yi Wu
 
Introduction to Griffon
Introduction to Griffon
James Williams
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
Fwdays
 
Golang
Golang
Michael Blake
 
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
César Hernández
 
Griffon @ Svwjug
Griffon @ Svwjug
Andres Almiray
 
PyCon Korea 2019 REST API Document Generation
PyCon Korea 2019 REST API Document Generation
용선 이
 
Golang Project Layout and Practice
Golang Project Layout and Practice
Bo-Yi Wu
 
Gradle in 45min
Gradle in 45min
Schalk Cronjé
 
Build microservice with gRPC in golang
Build microservice with gRPC in golang
Ting-Li Chou
 
Groovy And Grails Introduction
Groovy And Grails Introduction
Eric Weimer
 
Understanding how concurrency work in os
Understanding how concurrency work in os
GenchiLu1
 
really really really awesome php application with bdd behat and iterfaces
really really really awesome php application with bdd behat and iterfaces
Giulio De Donato
 
Go at Openprovider
Go at Openprovider
Elena Grahovac
 
When third parties stop being polite... and start getting real
When third parties stop being polite... and start getting real
Charles Vazac
 
Ratpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web Apps
James Williams
 
Embedding Groovy in a Java Application
Embedding Groovy in a Java Application
Paolo Predonzani
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystem
Kostas Saidis
 
Groovy on the shell
Groovy on the shell
sascha_klein
 
GraphQL IN Golang
GraphQL IN Golang
Bo-Yi Wu
 
Introduction to Griffon
Introduction to Griffon
James Williams
 
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
"How to Use Bazel to Manage Monorepos: The Grammarly Front-End Team’s Experie...
Fwdays
 
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
2018 (codeone) Graal VM and MicroProfile a polyglot microservices solution [d...
César Hernández
 
PyCon Korea 2019 REST API Document Generation
PyCon Korea 2019 REST API Document Generation
용선 이
 
Golang Project Layout and Practice
Golang Project Layout and Practice
Bo-Yi Wu
 
Build microservice with gRPC in golang
Build microservice with gRPC in golang
Ting-Li Chou
 
Groovy And Grails Introduction
Groovy And Grails Introduction
Eric Weimer
 
Understanding how concurrency work in os
Understanding how concurrency work in os
GenchiLu1
 
really really really awesome php application with bdd behat and iterfaces
really really really awesome php application with bdd behat and iterfaces
Giulio De Donato
 
When third parties stop being polite... and start getting real
When third parties stop being polite... and start getting real
Charles Vazac
 
Ratpack - Classy and Compact Groovy Web Apps
Ratpack - Classy and Compact Groovy Web Apps
James Williams
 

Similar to Grooscript in Action SpringOne2gx 2015 (20)

Grooscript gr8conf
Grooscript gr8conf
GR8Conf
 
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf
 
Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast Lane
Andres Almiray
 
Groovy presentation
Groovy presentation
Manav Prasad
 
Introduction to Groovy (Serbian Developer Conference 2013)
Introduction to Groovy (Serbian Developer Conference 2013)
Joachim Baumann
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
Jonathan Felch
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Schalk Cronjé
 
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf
 
An Introduction to Groovy for Java Developers
An Introduction to Groovy for Java Developers
Kostas Saidis
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
Schalk Cronjé
 
Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007
Guillaume Laforge
 
Introduction to Grails
Introduction to Grails
Avi Perez
 
Groovy Programming Language
Groovy Programming Language
Aniruddha Chakrabarti
 
Groovy.pptx
Groovy.pptx
Giancarlo Frison
 
Introduction to Groovy
Introduction to Groovy
Kevin H.A. Tan
 
Learning groovy -EU workshop
Learning groovy -EU workshop
adam1davis
 
Groovy intro
Groovy intro
NexThoughts Technologies
 
Practical Domain-Specific Languages in Groovy
Practical Domain-Specific Languages in Groovy
Guillaume Laforge
 
Practical Groovy DSL
Practical Groovy DSL
Guillaume Laforge
 
Introductionto fp with groovy
Introductionto fp with groovy
Isuru Samaraweera
 
Grooscript gr8conf
Grooscript gr8conf
GR8Conf
 
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf
 
Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast Lane
Andres Almiray
 
Groovy presentation
Groovy presentation
Manav Prasad
 
Introduction to Groovy (Serbian Developer Conference 2013)
Introduction to Groovy (Serbian Developer Conference 2013)
Joachim Baumann
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
Jonathan Felch
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Schalk Cronjé
 
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf
 
An Introduction to Groovy for Java Developers
An Introduction to Groovy for Java Developers
Kostas Saidis
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
Schalk Cronjé
 
Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007
Guillaume Laforge
 
Introduction to Grails
Introduction to Grails
Avi Perez
 
Introduction to Groovy
Introduction to Groovy
Kevin H.A. Tan
 
Learning groovy -EU workshop
Learning groovy -EU workshop
adam1davis
 
Practical Domain-Specific Languages in Groovy
Practical Domain-Specific Languages in Groovy
Guillaume Laforge
 
Introductionto fp with groovy
Introductionto fp with groovy
Isuru Samaraweera
 
Ad

Recently uploaded (20)

Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Josef Weingand
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Mastering AI Workflows with FME by Mark Döring
Mastering AI Workflows with FME by Mark Döring
Safe Software
 
Daily Lesson Log MATATAG ICT TEchnology 8
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
Cyber Defense Matrix Workshop - RSA Conference
Cyber Defense Matrix Workshop - RSA Conference
Priyanka Aash
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Josef Weingand
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Mastering AI Workflows with FME by Mark Döring
Mastering AI Workflows with FME by Mark Döring
Safe Software
 
Daily Lesson Log MATATAG ICT TEchnology 8
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
Cyber Defense Matrix Workshop - RSA Conference
Cyber Defense Matrix Workshop - RSA Conference
Priyanka Aash
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
Ad

Grooscript in Action SpringOne2gx 2015

  • 1. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ SPRINGONE2GX WASHINGTON, DC Grooscript in Action By Jorge Franco Leza @jfrancoleza
  • 2. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ About me 2 Developer [email protected]
  • 3. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thank you! 3 3 years since first commit
  • 4. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Agenda • Introduction to grooscript • Convert your groovy code to javascript • Support • PhantomJs and tools • Gradle plugin • Demo • Grails plugin • Working with javascript • Require.js • Future 4
  • 5. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Introduction to grooscript • Library (jar) • Groovy 2.0+ to javascript ECMA 5 • Apache 2 license • Source code http://github.com/chiquitinxx/grooscript • Converted code needs grooscript.js to run • Tools around: gradle and grails plugins, npm and bower packages • Documentation http://grooscript.org/doc.html • Demos http://github.com/chiquitinxx/grooscript-demos • Try live! http://grooscript.org/conversions.html 5
  • 6. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Why grooscript? • You have all java / groovy tools to create code in the client side. • Javascript is fast. • Enjoy javascript! Create your own magic. • Don’t repeat code in two languages, isomorphic code. • Use groovy templates everywhere. • Single development environment. • Stop learning “to javascript” things. • Static type if you want to. • But… mainly… because it is… 6
  • 7. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Groovy 7 Readable Concise Expressive
  • 8. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ ASTS 8 @Component
 class Counter implements Colorable {
 
 Integer number
 
 void init() {
 number = null
 }
 
 void render() {
 div(class: "widget bg-${randomColor()}") {
 if (number) {
 p 'Number of books'
 em number.toString()
 a(href:"#", class:"button", onclick: 'bookPresenter.showBooks()') {
 yield 'Show'
 }
 } else {
 p 'Counting books...'
 }
 }
 }
 } AST’s Getter / Setters
  • 9. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ List and maps 9 def start() { def countries = loadCountries(). findAll { it.population > 100000}. unique { it.alpha3Code } countries.each { country -> customSigma.addNode id: country.alpha3Code, x: country.latlng[1], color: ‘purple’ } countries.each { country -> country.borders?.each { border -> this.&hello(border) } } updateNumberCountries countries.size() customSigma.refresh() } Lists and maps
  • 10. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ DSL's 10 server { get('/') { render Templates.applyTemplate('index.gtpl') } on('login') { data, socket -> if (data.name && !socket.login) { socket.login = data.name socket.emit 'loginok', [name: data.name] socket.broadcast.emit 'loginok', [name: data.name] } } on('msg') { data, socket -> if (data.msg && socket.login) { socket.broadcast.emit 'msg', [msg: data.msg] } } on('disconnect') { socket -> if (socket.login) { socket.broadcast.emit 'off', [name: socket.login] } } }.start() Dsl’s
  • 11. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Metaprogramming 11 class Hello { def methodMissing(String name, args) { println "Hello ${name}!" } } def hello = new Hello() hello.Groovy() hello.Javascript() hello.grooscript() Metaprogramming
  • 12. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Functional 12 def plus2 = { it + 2 } def times3 = { it * 3 } def times3plus2 = plus2 << times3 assert times3plus2(3) == 11 def plus2times3 = times3 << plus2 assert plus2times3.curry(5)() == 21 Functional
  • 13. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Convert your groovy code to javascript 13 @Grab('org.grooscript:grooscript:1.2.0') import org.grooscript.GrooScript String result = GrooScript.convert ''' def sayHello = { println "Hello ${it}!" } ['Groovy','JavaScript','GrooScript'].each sayHello ''' new File(‘out.js’) << result
  • 14. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Convert your groovy code to javascript 14 Let’s see it in action http://grooscript.org/doc.html
  • 15. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Conversion options • classpath • customization { -> ast(TypeChecked)} • initialText, finalText • recursive • mainContextScope [''$'', ‘'window'', ''myFunction''] • addGsLib • requireJsModule • consoleInfo • includeDependencies 15
  • 16. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Support • Groovy core • Classes, numbers, lists, maps, sets, date, ranges, closures, (g)strings, operators, groovy truth, Expando, categories, traits, beans, switch, metaprogramming, enum, equals, multiple assignment, optional params, default constructor, pointer methods, operator overload, regular expressions, @Delegate, @Category, … • Dsl’s. (@DelegatesTo) • Ast’s at semantic analysis phase. • Packaging in js with require.js. • Be groovier! 16
  • 17. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Not supported • Not groovy-core (json, builders, I/O, …) • Java / Groovy Types (Thread, LinkedHashMap, Stack, Optional, …) • Super except constructors. • Methods with same name (overload), classes with same name. • Java 8 stuff not supported by groovy • Module extensions, complex metaprogramming, groovy AST’s after Semantic Phase 17
  • 18. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Annotations 18 import org.grooscript.asts.GsNotConvert @GsNotConvert class ClassNotConvert { def a } class A { @GsNotConvert def methodNoConvert() { ‘No!’ } def hello() { println ‘Hello!’ } } import org.grooscript.asts.GsNative class Data { @GsNative void saySomething(String smt) {/* console.log(smt); */} @GsNative def five() {/* return 5; */ 1 + 1 + 3 } }
  • 19. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ PhantomJs test 19 @GrabConfig(systemClassLoader = true) @Grab(‘org.grooscript:grooscript:1.2.0’) import org.grooscript.asts.PhantomJsTest //Need phantomjs installed System.setProperty(‘PHANTOMJS_HOME’, ‘path/to/phantomjs’) @PhantomJsTest(url = 'http://beta.groovy-lang.org/') void testCountLinks() { def links = $('a') assert links.size() > 40, "Number of links: ${links.size()}" links.toArray().collect { it.toString() }.each { link -> println link } } testCountLinks()
  • 20. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Javascript libs • grooscript.js (87 kb) (8 kb minified and gziped) • grooscript.min.js (33 kb) • grooscript-tools.js (14 kb) (GQuery, HtmlBuilder, Observable) 20
  • 21. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ HtmlBuilder 21 given: def result = HtmlBuilder.build { body { ul(class: 'list', id: 'mainList') { 2.times { number -> li number + 'Hello!' } } } } expect: result == "<body><ul class='list' id=‘mainList'> <li>0Hello!</li><li>1Hello!</li></ul></body>"
  • 22. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ GQuery 22 import org.grooscript.jquery.GQueryImpl def result = new Result() def gQuery = new GQueryImpl() gQuery.onReady { gQuery.doRemoteCall(“${JSON_ADDRESS}”, 'GET', null, { res -> gQuery('.result').html('OK') result = res }, { result = 'FAIL!' }, Result) } https://github.com/chiquitinxx/grooscript/blob/master/src/ main/groovy/org/grooscript/jquery/GQuery.groovy
  • 23. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Observable 23 given: def result = [] Observable.from([1, 5, 9, 12, 3, 8]). filter { it < 5 }. map { 'H' * it }. subscribe { event -> result << event } expect: result == ['H', 'HHH'] https://github.com/chiquitinxx/grooscript/blob/master/src/ test/groovy/org/grooscript/rx/ObservableSpec.groovy
  • 24. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Gradle plugin • Starting guide http://grooscript.org/starting_gradle.html • Listen to changes and does conversions in background. • Groovy templates in the client side. • Can use with your grails 3+ application. • Create require.js modules. • Notification of changes using websockets. • Thread tasks can block execution. • Info about tasks http://grooscript.org/gradle/tasks.html 24
  • 25. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ task convert Convert groovy files to javascript. Can add conversion options. 25 grooscript { source = ['src/main/groovy'] destination = 'js' }
  • 26. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 26 task convertThread grooscript { source = [‘src/main/groovy/presenters'] destination = 'js' classpath = ['src/groovy'] initialText = '//Converted file' recursive = true blockExecution = true } Listen to changes in groovy files, and convert them to javascript when modified. Can block gradle execution.
  • 27. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 27 task initStaticWeb "## build.gradle $## src $## main "## groovy % $## Presenter.groovy $## webapp "## index.html $## js "## app $## lib "## grooscript-tools.js "## grooscript.min.js $## jquery.min.js Creates a static web project to starting play with grooscript.
  • 28. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 28 task templatesJs class Templates { static Map<String, Closure> templates static String applyTemplate(String name, model = [:]) { Closure cl = templates[name] cl.delegate = model cl(model) } } Convert groovy templates to a javascript file.
  • 29. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 29 task templatesThread templates { templatesPath = 'templates' templates = ['main.gtpl', 'little/small.tpl'] destinationFile = 'js/Templates.js' classpath = ['src/groovy'] customTypeChecker = 'aCustomTypeCheckerFile.groovy' } Listen to changes in groovy templates and generate a new javascript template file when something changes. Can block gradle execution.
  • 30. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 30 task spyChanges spy { files = ['Templates.js'] onChanges = { list -> springWebsocketTo 'http://localhost:8080/demo' data 'templates' onChannel '/app/reload' } } Listen to file changes and execute groovy code when files change. Can send a message using websockets.
  • 31. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 31 task requireJs requireJs { sourceFile = 'src/main/groovy/MyApp.groovy' destinationFolder = 'src/main/resources/web/js/app' } Convert groovy file to require.js javascript module. Also all dependencies are converted.
  • 32. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ task requireJsThread 32 requireJs { sourceFile = ‘starting/InitialFile.groovy' classpath = ['src/main/groovy'] destinationFolder = ‘js/app' blockExecution = true } Listen to changes in groovy file or any dependency file, and generate require.js javascript modules when files change. Also can block execution.
  • 33. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 33 Demo gradle books More action https://github.com/chiquitinxx/books-demo
  • 34. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Grails plugin • A grails 2 version, 0.8 https://grails.org/plugin/grooscript. • Grails 3 version, version 1.1.2, documentation http://grooscript.org/grails3-plugin. • Adding tags for your gsp’s. • Converting files with gradle plugin in grails 3+. • Using your domain classes in your gsp’s. *experimental* • Uses asset pipeline and cache plugins, also jquery for some tags. • Requires <asset:javascript src="grooscript-grails.js"/> • Events in your gsp's with groovy. • Websockets support using spring websockets. • Templating in your gsp’s with HtmlBuilder. 34
  • 35. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ grooscript:code 35 <grooscript:code> [‘groovy’, ‘javascript’].each { println “Hello $it” } </grooscript:code> <asset:script> … js code … </asset:script>
  • 36. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ grooscript:template 36 <grooscript:template onLoad=“false" functionName=“refreshList"> ul { data.each { book -> li { p 'Id: ' + book.id + ' Name: ' + book.title } } } </grooscript:template>
  • 37. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ websockets 37 <grooscript:initSpringWebsocket> println 'Connected! Websocket is up!’ GrooscriptGrails.sendWebsocketMessage("/app/hello", “Hello!") </grooscript:initSpringWebsocket> <grooscript:onServerEvent path="/topic/books" type="Book"> data.each { book -> $("#helloDiv").append '<p>'+book.coolFormat()+'</p>' } </grooscript:onServerEvent> Use spring websockets in your gsp’s. Have to include client libraries.
  • 38. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ events 38 <grooscript:code> $(document).ready { def eventData = 'Application started.' gsEvents.sendMessage('newEvent', eventData) gsEvents.onEvent('delete', { book -> $('#deleteEvent').html 'Deleted ' + book.title }) } </grooscript:code> <grooscript:onEvent name="newEvent"> console.log event </grooscript:onEvent> Manage events in the client using groovy.
  • 39. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ grooscript:remoteModel 39 <grooscript:remoteModel domainClass="Book"/> <grooscript:code> import rest.Book Book.list().then { list -> $('#bookList').html '' list.each addBook } </grooscript:code> Use your domain classes from your gsp’s. Domain classes annotated with @Resource, using json.
  • 40. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Demo grails 3 40 Final action https://github.com/chiquitinxx/circles
  • 41. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Working with javascript 41 class MyClass {} function MyClass() { … } var myClass = MyClass(); // NO var myClass = new MyClass(); var myClass = MyClass({prop1: ‘value’, prop2: 12 }); myClass.method(); // NO myClass.metaprogrammingMethod(); myClass.method(numberOrStringOrList); // beware maps! myClass.method({ a: 1, b: 2 });
  • 42. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Combine both worlds 42 import static org.grooscript.GrooScript.toJavascript import static org.grooscript.GrooScript.toGroovy def map = [x: 1, y: 2] //point is a javascript object point.init(map) //[BAD] Passing a groovy object to javascript, can fail point.init(toJavascript(map)) //[GOOD] You now are passing {x: 1, y: 2} //point has a method info() that returns a javascript object def badData = point.info() //[BAD] You will have a 'javascript' object def goodData = toGroovy(point.info()) //[GOOD] goodData as a 'groovy' object
  • 43. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Tips • Keep your groovy code tested. • If you use @GsNative, keep that code in isolated classes, that can be easy to mock them. • Don’t abuse @GsNative, is untested code. • You can activate debug console info in javascript with gs.consoleInfo = true; • You can test dom manipulation with jsoup. • Try to stay functional, don’t abuse ‘this’ or variables from other contexts. • Curry functions to inject variables rather than expecting them to be available after callbacks hell. 43
  • 44. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Require.js • Javascript file and module loader. • Can be used in browser, rhino and Node.js environments. • Optimization using google closure compiler. 44 requirejs.config({ baseUrl: 'jsModules', paths: { lib: 'js/lib' } }); requirejs(['lib/grooscript.min'], function() { requirejs(['Initial']); });
  • 45. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Require.js 45 import org.grooscript.GrooScript Map conversionOptions = [classpath: 'src/main/groovy'] GrooScript.convertRequireJs('src/main/groovy/Initial.groovy', 'jsModules', conversionOptions) define(function() { function Initial() { … } return Initial; }); class Initial { } src/main/groovy/Initial.groovy jsModules/Initial.js
  • 46. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Require.js 46 define(['lib/data'], function (data) { function Require() { //.. gSobject.data = data; //.. return gSobject; }; return Require; }); package files import org.grooscript.asts.RequireJsModule class Require { @RequireJsModule(path = 'lib/data') def data } src/main/groovy/files/Require.groovy jsModules/files/Require.js
  • 47. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Future 47 ECMAScript 2015
  • 48. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 48 Q & A
  • 49. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a
 Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Thank you! 49 Waiting for your feedback and questions from now to Thursday