0
Groovy XML ProcessingVladimir Forfutdinov
Outline•   Java vs Groovy short cuts•   XML parsing with Groovy•   XML generating with Groovy•   How to access EO inside G...
Java vs Groovy•   Java Virtual Machine thinks Groovy is Java•   Inspired by Python, Ruby and Smalltalk•   Java developers ...
Setup•   Easy to find and learn at: http://groovy.codehaus.org/•   Eclipse plug-in at: http://groovy.codehaus.org/Eclipse+P...
Hello World!//JAVAclass myfirstjavaprog{        public static void main(String args[])        {           System.out.print...
Method call on a Null Object//JAVAMyObject obj = nullif (obj != null){   return obj.getChildren().getFirst()} else {   ret...
ClosuresFunctions that are first class objects - a chunk of code that can be passed around as if itwere a string or an int...
Meta Class - MethodsIntercepting Method Callsclass MyClass{  def hello(){ invoked hello directly }  def invokeMethod(Strin...
Meta Class - PropertiesIntercepting Property Accessesclass MyClass{  def greeting = accessed greeting directly  Object get...
Meta Class - At Run-timeAdding new property and method to a class during Run-timeclass A{}//add new property ‘hi’A.metaCla...
XML Parsing•   XmlParser - supports GPath expressions for XML documents•   XmlSlurper - lower overheads than XmlParser due...
XML Input sampleclass XmlExamples {  static def CAR_RECORDS =     <records>      <car name=HSV Maloo make=Holden year=2006...
XmlParser vs XmlSlurperdef records_p = new XmlParser().parseText(XmlExamples.CAR_RECORDS)def records_s = new XmlSlurper()....
XmlParser vs XmlSlurper// 2 cars have an e in the makeassert records_p.car.findAll{ it.@make.contains(e) }.size() == 2// o...
XmlSlurperprintln records.depthFirst().grep{ it.@type !=  }.@type*.text()//Result[speed, size, price]println records.**.gr...
XmlSlurperclass XmlExamples {  static def CF_MESSAGE =     <cf:Message xmlns:cf=http://controlsforce.com/schema/message.xs...
XML Generation•   Building XML using simple Java•   StreamingMarkupBuilder - A builder class for creating XML markup
Java//assuming we have a Writer created alreadywriter.write("<root>");  writer.write(“<a a1=‘one’>”);    writer.write("<b>...
StreamingMarkupBuilderimport groovy.xml.StreamingMarkupBuildernew StreamingMarkupBuilder().bind {   root {                ...
StreamingMarkupBuilderimport groovy.xml.StreamingMarkupBuilderdef dic = [a:123, b:456, c:949]new StreamingMarkupBuilder()....
StreamingMarkupBuilderimport groovy.xml.StreamingMarkupBuilderdef dic = [a:[name:apple, type:123], b:[name:cheese, type:45...
EOs inside Groovy•   Setup•   Demo
Setup•   Main Component with a set of tables that will list the data from    each table•   Main.java replaced with Main.gr...
DEMO
Questions
Bonus
ConfigSlurper•   Utility class within Groovy for writing properties file•   Unlike regular Java properties files ConfigSlurper...
Reading configuration with ConfigSlurperdef config = new ConfigSlurper().parse (configFile)                def configFile = ...
Updating configuration with ConfigSlurper//get the all of the config data              WOWODC {config.Hi.GoodBuy.say = Hello...
Updating configuration with ConfigSlurper//get the all of the config data                 WOWODC {config.Hi.GoodBuy.tell = H...
Updating configuration with ConfigSlurper//get the all of the config data                 WOWODC {config.WOWODC.Bonus.testId...
DEMO
Upcoming SlideShare
Loading in...5
×

Groovy XML Processing with WebObjects

856

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
856
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
18
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Groovy XML Processing with WebObjects"

  1. 1. Groovy XML ProcessingVladimir Forfutdinov
  2. 2. Outline• Java vs Groovy short cuts• XML parsing with Groovy• XML generating with Groovy• How to access EO inside Groovy
  3. 3. Java vs Groovy• Java Virtual Machine thinks Groovy is Java• Inspired by Python, Ruby and Smalltalk• Java developers will have almost-zero learning curve• Supports Domain-Specific Languages• Powerful processing primitives, OO abilities and an Ant DSL• Works with existing Java objects and libraries
  4. 4. Setup• Easy to find and learn at: http://groovy.codehaus.org/• Eclipse plug-in at: http://groovy.codehaus.org/Eclipse+Plugin• groovyShell• groovy-all-1.7.0.jar
  5. 5. Hello World!//JAVAclass myfirstjavaprog{ public static void main(String args[]) { System.out.println("Hello World!"); }}//GROOVYprintln "Hello World!"//GROOVY command linegroovy -e "println Hello + args[0]" World! GROOVY SCRIPT ARG 1
  6. 6. Method call on a Null Object//JAVAMyObject obj = nullif (obj != null){ return obj.getChildren().getFirst()} else { return null}//GROOVYMyObject obj = nullreturn obj?.getChildren()?.getFirst()
  7. 7. ClosuresFunctions that are first class objects - a chunk of code that can be passed around as if itwere a string or an integer.square = { it * it }square(4)//RESULT16[ 1, 2, 3, 4 ].collect(square)//RESULT[ 1, 4, 9, 16 ]printMapClosure = { key, value -> println key + "t= " + value }[ "Name" : "John", "Address" : "Here", "Likes" : "WOWODC" ].each(printMapClosure)//RESULTName = JohnAddress = HereLikes = WOWODC
  8. 8. Meta Class - MethodsIntercepting Method Callsclass MyClass{ def hello(){ invoked hello directly } def invokeMethod(String name, Object args){ return "unknown method $name(${args.join(, )})" }}def mine= new MyClass()println mine.hello()//RESULTinvoked hello directlyprintln mine.foo("Mark", 19)//RESULTunknown method foo(Mark, 19)
  9. 9. Meta Class - PropertiesIntercepting Property Accessesclass MyClass{ def greeting = accessed greeting directly Object getProperty(String property) { "read from property $property" } void setProperty(String property, Object newValue) { throw new Exception("wrote to property $property") }}def mine = new MyClass()//try to read ‘greeting’ propertyprintln mine.greeting//RESULTread from property greeting//try to set ‘greeting’ propertytry { mine.greeting = hi } catch(e) { println e.message }//RESULTwrote to property greeting//we can access a property directly using .@ syntaxprintln mine.@greeting//RESULTaccessed greeting directly
  10. 10. Meta Class - At Run-timeAdding new property and method to a class during Run-timeclass A{}//add new property ‘hi’A.metaClass.hi = Hi!!!def a1 = new A()println a1.hi//RESULTHi!!!//add new method ‘hello’A.metaClass.hello = {-> "Hello!"}def a2 = new A()println a2.hello()//RESULTHello!
  11. 11. XML Parsing• XmlParser - supports GPath expressions for XML documents• XmlSlurper - lower overheads than XmlParser due to lazy evaluation
  12. 12. XML Input sampleclass XmlExamples { static def CAR_RECORDS = <records> <car name=HSV Maloo make=Holden year=2006> <country>Australia</country> <record type=speed>Production Pickup Truck with speed of 271kph</record> </car> <car name=P50 make=Peel year=1962> <country>Isle of Man</country> <record type=size>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record> </car> <car name=Royale make=Bugatti year=1931> <country>France</country> <record type=price>Most Valuable Car at $15 million</record> </car> </records> }
  13. 13. XmlParser vs XmlSlurperdef records_p = new XmlParser().parseText(XmlExamples.CAR_RECORDS)def records_s = new XmlSlurper().parseText(XmlExamples.CAR_RECORDS)def allRecords_p = records_p.car.size()assert allRecords_p == 3def allRecords_s = records_s.car.size()assert allRecords_s == 3def allNodes = records_p.depthFirst().size()assert allNodes_p == 10def allNodes_s = records_s.depthFirst().collect{ it }.size()assert allNodes_s == 10 <records> <car name=HSV Maloo make=Holden year=2006> <country>Australia</country>def firstRecord_p = records_p.car[0] <record type=speed>def firstRecord_s = records_s.car[0] Production Pickup Truck with speed of 271kph </record> </car>assert car == firstRecord_p.name() <car name=P50 make=Peel year=1962> <country>Isle of Man</country>assert car == firstRecord_s.name() <record type=size> Smallest Street-Legal Car at 99cm wide and 59 kg in weightassert Holden == firstRecord_p.@make </record> </car>assert Holden == firstRecord_s.@make.text() <car name=Royale make=Bugatti year=1931> <country>France</country>assert Australia == firstRecord_p.country.text() <record type=price> Most Valuable Car at $15 millionassert Australia == firstRecord_s.country.text() </record> </car> </records>
  14. 14. XmlParser vs XmlSlurper// 2 cars have an e in the makeassert records_p.car.findAll{ it.@make.contains(e) }.size() == 2// option 1assert records_s.car.findAll{ it.@make.text().contains(e) }.size() == 2// option 2assert records_s.car.findAll{ it.@make =~ .*e.* }.size() == 2 <records> <car name=HSV Maloo make=Holden year=2006> <country>Australia</country> <record type=speed> Production Pickup Truck with speed of 271kph </record> </car> <car name=P50 make=Peel year=1962> <country>Isle of Man</country> <record type=size> Smallest Street-Legal Car at 99cm wide and 59 kg in weight </record> </car> <car name=Royale make=Bugatti year=1931> <country>France</country> <record type=price> Most Valuable Car at $15 million </record> </car> </records>
  15. 15. XmlSlurperprintln records.depthFirst().grep{ it.@type != }.@type*.text()//Result[speed, size, price]println records.**.grep{ it.@type != }.@type*.text()//Result[speed, size, price]def countryOne = records.car[1].countryprintln countryOne.parent().@make.text()//ResultPeel <records>println countryOne....@make.text() <car name=HSV Maloo make=Holden year=2006> <country>Australia</country>//Result <record type=speed>Peel Production Pickup Truck with speed of 271kph </record>// names of cars with records sorted by year </car> <car name=P50 make=Peel year=1962>println records.car.list().sort{ <country>Isle of Man</country> it.@year.toInteger() <record type=size>}.@name*.text() Smallest Street-Legal Car at 99cm wide and 59 kg in weight//Result </record> </car>[Royale, P50, HSV Maloo] <car name=Royale make=Bugatti year=1931> <country>France</country>// names of countries with ‘s’ in the name <record type=price>println records.**.grep{ Most Valuable Car at $15 million </record> it.@type =~ s.* </car>}*.parent().country*.text() </records>//Result[Australia, Isle of Man]
  16. 16. XmlSlurperclass XmlExamples { static def CF_MESSAGE = <cf:Message xmlns:cf=http://controlsforce.com/schema/message.xsd> <cf:Properties> <cf:Name>ck_mstr</cf:Name> <cf:Process>FREUDENBERG_DEMO</cf:Process> <cf:User></cf:User> <cf:Date>Fri Dec 25 17:37:55 EST 2009</cf:Date> <cf:MessageCount>0</cf:MessageCount> <cf:UID>uniqueId-0</cf:UID> </cf:Properties> </cf:Message> }def xml = new XmlSlurper().parseText(XmlExamples.CF_MESSAGE)xml.Properties.children().each { println "${it.name()} -> ${it.text()}"}Name -> ck_mstrProcess -> FREUDENBERG_DEMOUser ->Date -> Fri Dec 25 17:37:55 EST 2009MessageCount -> 0UID -> uniqueId-0
  17. 17. XML Generation• Building XML using simple Java• StreamingMarkupBuilder - A builder class for creating XML markup
  18. 18. Java//assuming we have a Writer created alreadywriter.write("<root>"); writer.write(“<a a1=‘one’>”); writer.write("<b>3 < 5</b>"); writer.write("<c a2=‘two’>blah</c>"); writer.write("<d>"); writer.write("<f>hello</f>"); writer.write("</d>"); writer.write("</a>");writer.write("</root>");//Result<root> <a a1=one> <b>3 &lt; 5</b> <c a2=two>blah</c> <d> <f>hello</f> </d> </a></root>
  19. 19. StreamingMarkupBuilderimport groovy.xml.StreamingMarkupBuildernew StreamingMarkupBuilder().bind { root { writer.write("<root>"); a ( a1:one ) { writer.write(“<a a1=‘one’>”); writer.write("<b>3 < 5</b>"); b { mkp.yield( 3 < 5 ) } writer.write("<c a2=‘two’>blah</c>"); c ( a2:two, blah ) writer.write("<d>"); d { writer.write("<f>hello</f>"); f (‘hello’) writer.write("</d>"); } writer.write("</a>"); writer.write("</root>"); } }}.toString()//Result<root> <a a1=one> <b>3 &lt; 5</b> <c a2=two>blah</c> <d> <f>hello</f> </d> </a></root>
  20. 20. StreamingMarkupBuilderimport groovy.xml.StreamingMarkupBuilderdef dic = [a:123, b:456, c:949]new StreamingMarkupBuilder().bind { root { dic.each { "${it.key}" (it.value) } }}.toString()//Result<root> <a>123</a> <b>456</b> <c>949</c></root>
  21. 21. StreamingMarkupBuilderimport groovy.xml.StreamingMarkupBuilderdef dic = [a:[name:apple, type:123], b:[name:cheese, type:456], c:[name:milk, type:949]]new StreamingMarkupBuilder().bind { root { dic.each { "${it.key}" (it.value) } }}.toString()//Result<root> <a name=apple type=123/> <b name=cheese type=456/> <c name=milk type=949/></root>
  22. 22. EOs inside Groovy• Setup• Demo
  23. 23. Setup• Main Component with a set of tables that will list the data from each table• Main.java replaced with Main.groovy (just for some extra fun)• MySQL Database with three tables: • Employee Employee • age Job Manager job 0..1* employees 0..1* • manager Manager name Job name employees owner salary jobs 0..1 * name
  24. 24. DEMO
  25. 25. Questions
  26. 26. Bonus
  27. 27. ConfigSlurper• Utility class within Groovy for writing properties file• Unlike regular Java properties files ConfigSlurper scripts support native Java types and are structured like a tree.
  28. 28. Reading configuration with ConfigSlurperdef config = new ConfigSlurper().parse (configFile) def configFile = //get the all of the config data WOWODC {println config.WOWODC Bonus { testId = 1//Result testName = "Hello Bonus Test string"["Bonus":["testId":1, "testName":"Hello Bonus Test string"], "BonusList":["key1":"val1", "hi":"hello"]] }//get only the Bonus section BonusList {println config.WOWODC.Bonus key1 = val1 hi = hello//Result }["testId":1, "testName":"Hello Bonus Test string"] }//get only the testId value println config.WOWODC.Bonus.testId//Result1//list keys and values under BonusList sectionconfig.WOWODC.BonusList.each {println "${it.key} = ${it.value}"}//Resultkey1 = val1hi = hello
  29. 29. Updating configuration with ConfigSlurper//get the all of the config data WOWODC {config.Hi.GoodBuy.say = Hello Bonus { testId = 1def sw = new StringWriter() testName = "Hello Bonus Test string"println config?.writeTo(sw).toString() }//Result --> BonusList {WOWODC { key1 = val1 Bonus { hi = hello testId=1 } testName="Hello Bonus Test string" } } BonusList { key1="val1" hi="hello" }}Hi.GoodBuy.say="Hello" // got updated
  30. 30. Updating configuration with ConfigSlurper//get the all of the config data WOWODC {config.Hi.GoodBuy.tell = Hi Bonus { testId=1def sw = new StringWriter() testName="Hello Bonus Test string"println config?.writeTo(sw).toString() } BonusList {//Result key1="val1"WOWODC { hi="hello" Bonus { } testId=1 } testName="Hello Bonus Test string" Hi.GoodBuy.say="Hello" } BonusList { key1="val1" hi="hello" }}Hi { GoodBuy { say="Hello" tell="Hi" // got updated }}
  31. 31. Updating configuration with ConfigSlurper//get the all of the config data WOWODC {config.WOWODC.Bonus.testId = 2 Bonus { testId=1def sw = new StringWriter() testName="Hello Bonus Test string"println config?.writeTo(sw).toString() } BonusList {//Result --> key1="val1"WOWODC { hi="hello" Bonus { } testId=2 // got updated } testName="Hello Bonus Test string" Hi { } GoodBuy { BonusList { say="Hello" key1="val1" tell="Hi" hi="hello" } } }}Hi { GoodBuy { say="Hello" tell="Hi" }}
  32. 32. DEMO
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×