Javaone2008 Bof 5102 Groovybuilders

24
Cooking your own Groovy Builder: A step forward into Domain-Specific Languages Ixchel Ruiz, PSE CCA Andres Almiray, PSE Oracle BOF-5102

Transcript of Javaone2008 Bof 5102 Groovybuilders

Page 1: Javaone2008 Bof 5102 Groovybuilders

Cooking your own Groovy Builder: A step forward into Domain-Specific Languages

Ixchel Ruiz, PSE CCAAndres Almiray, PSE Oracle

BOF-5102

Page 2: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 2

Learn to empower your code with the expressiveness of Groovy’s Builders

Page 3: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 3

Agenda

Builders and GroovyLife without builders• Swing demo• Java2D demo

FactoryBuilderSupportResources

Page 4: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 4

Why Groovy?

It is so Cool!

No impedance mismatch with JavaGroovy is JavaFlat learning curve

If you are a Java programmer, congratulations! you are also a Groovy programmer

Page 5: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 5

Builders

Provide an abstraction layerIncrease ExpressivenessBetter suited to express hierarchical dataSimplify Development

Page 6: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 6

Why builders for DSLs?

Domain-Specific Languages can be written with Groovy in many ways.• Metaprogramming• Fluent Interface, static imports, closures• Builders

Page 7: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 7

Builders for DSLs

Builders are a great choice to begin with• Pretty straight forward structure• No heavy metaprogramming required• Groovy provides 2 base classes to get you started

• BuilderSupport• FactoryBuilderSupport

Page 8: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 8

The Dark Side

Life without builders

Page 9: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 9

Swing

How many lines of code may this little program require in plain Java?

Page 10: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 10

Groovy’s answer

import groovy.swing.SwingBuilderimport java.awt.BorderLayout as BLimport javax.swing.JOptionPane

SwingBuilder.build { frame( id: 'frame', title: 'Hello World', show: true,

pack: true ){ borderLayout() label( 'Enter a message:', constraints: BL.WEST ) textField( id: 'name', columns: 20, constraints:

BL.CENTER ) button( 'Click', constraints: BL.EAST, actionPerformed:

{ e -> if( !name.text ) return JOptionPane.showMessageDialog( frame, name.text ) }) }}

Page 11: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 11

Java2D

This is a Java2D drawing that started as a rounded rectangle

Page 12: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 12

How many lines of code would it take in plain Java?

Short answer: didn’t even bother to measure themThe complete example has a little animation, applying each filter at a time, wonder how much code would be needed

Page 13: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 13

Groovy’s answer

antialias on rect( x: 20, y: 20, width: 180, height: 160, arcWidth: 50, arcHeight: 50, borderColor: no, id: 'base' ){

linearGradient { stop( offset: 0.5, color: 'white' ) stop( offset: 1, color: 'blue' ) } filters( offset: 50 ){ weave() kaleidoscope( sides: 4 ) shapeBurst( merge: true, type: 'circle up' ) lights(){ ambientLight( color: color('lime').rgb(), centreX: 0, centreY: 0 ) } dropShadow() } }

Page 14: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 14

What is going on?

As with other builders, each node is actually a “pretended” methodPretended methods are routed through the build cycle, any other methods are handled as usualSwingBuilder node names are easy to remember, most of the time just remove the leading ‘J’ from a Swing class and that’s itBoth SwingBuilder and GraphicsBuilder extend from FactoryBuilderSupport

Page 15: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 15

FactoryBuilderSupport at a glance

Factories have the responsibility to handle pretended methodsEach factory hooks into the build cycleThe builder will notify the current building factory whenever an action on the node should be takenEach factory has it own context for storing useful information while building nodes

Page 16: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 16

What factories may control

Node creationSetting attributes on the nodeIf the node accepts childrenAdding the node to its parent nodeProcessing the closure by themselves or let the builder handle itNode completion

Page 17: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 17

Available context properties (1)

context : retrieves the current contextcurrent : reference to the current nodecurrentName : the “pretended” method namecurrentFactory : reference to the factory that built the current node

Page 18: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 18

Available context properties (2)

Similar properties if a parent node is available

parentContext : retrieves the parent’s contextparentNode : reference to the parent nodeparentName : the parent’s node nameparentFactory : reference to the parent’s factory

Page 19: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 19

Extension Points

FactoryBuilderSupport exposes the following extension points via closure delegates• Pre node creation• Post node creation• Attribute handling• Node completion• End of build cycle

Page 20: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 20

Adding css to Swing, how?

We can’t extend every swing component available, that’s overkillWe can’t also extend every factory for the same reasonBut we can use an attribute delegate that handles css attributes

Page 21: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 21

This is one way to do it

import groovy.swing.*import com.u2d.css4swing.CSSEngineimport com.u2d.css4swing.style.ComponentStyle

CSSEngine.initialize()SwingBuilder.build { addAttributeDelegate { builder, node, attributes -> def cssClass = attributes.remove("cssClass") if( cssClass ) ComponentStyle.addClass( node, cssClass ) }

frame( id: 'fame', size: [300,100], locationRelativeTo: null, title: 'CSS+ Swing + Groovy', show: true ){ gridLayout( cols: 1, rows: 2 ) label( 'This is not important' ) label( 'This is really important', cssClass: 'important' ) }}

Page 22: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 22

Live code session

Page 23: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 23

For More Information

http://groovy.codehaus.orgThe builders

• http://groovy.codehaus.org/FactoryBuilderSupport• http://groovy.codehaus.org/ObjectGraphBuilder• http://groovy.codehaus.org/Swing+Builder• http://groovy.codehaus.org/SwingXBuilder• http://groovy.codehaus.org/JideBuilder• http://groovy.codehaus.org/GraphicsBuilder

• http://groovy.codehaus.org/Using+Ant+from+Groovy• http://groovy.codehaus.org/Creating+XML+using+Groovy's+MarkupBuilder

http://jroller.com/aalmiray

Page 24: Javaone2008 Bof 5102 Groovybuilders

2008 JavaOneSM Conference | java.com.sun/javaone | 24

Andres Almiray, PSE OracleIxchel Ruiz, PSE CCA

BOF-5102