Scala, XML and GAE

Preview:

DESCRIPTION

Presentation at first Melbourne Scala User Group 27th April, 2009

Citation preview

scala, xml and gaemark@ryall.name

xml literals

val document =<root> <child> <grandchild an_attribute="value1" /> <grandchild an_attribute="value2" /> </child></root>

val document =scala.xml.Elem(null, "root", scala.xml.Null, scala.xml.TopScope, scala.xml.Elem(null, "child", scala.xml.Null, scala.xml.TopScope, scala.xml.Elem(null, "grandchild", new scala.xml.UnprefixedAttribute("an_attribute","value1", scala.xml.Null), scala.xml.TopScope, scala.xml.Text("content1") ), scala.xml.Elem(null, "grandchild", new scala.xml.UnprefixedAttribute("an_attribute","value2", scala.xml.Null), scala.xml.TopScope, scala.xml.Text("content2") ) ))

extraction operators

// immediate descendant of document called 'child'document \ "child"

// any descendant of document called 'another_grandchild'document \\ "another_grandchild"

// any descendant attribute called 'an_attribute'document \\ "@an_attribute"

pattern matching

• match single node with {variable}

• match node sequence with {variable @ _*}

• cannot match attribute directly

val a = document match { case Elem(_, "root", _, _, _*) => true case _ => null}

val a = document match { case <root>{ _* }</root> => true case _ => false}

def process(node: scala.xml.Node): Unit = { println(node) node match { case <root>{contents @ _* }</root> => for (a <- contents) process(a) case <child>{contents @ _*}</child> => for (a <- contents) process(a) case <grandchild>{contents @ _*}</grandchild> => for (a <- contents) process(a) case _ => println("leaf") }}

def add(p: Node, newEntry: Node ): Node = p match { case <div>{ ch @ _* }</div> => <div>{ ch }{ newEntry }</div> }

Concatenation

document match { case n @ <grandchild>{ _* }</grandchild> => println(n.attribute("an_attribute"))}

Extracting attributes

persisting and restoring

scala.xml.XML.saveFull("filename.xml", document, "UTF-8", true, null)

val document2 = scala.xml.XML.loadFile("filename.xml")

stream parsing

val src = scala.io.Source.fromString("<root><child></child></root>")val er = new scala.xml.pull.XMLEventReader().initialize(src)er.next...

building xml

var variable1 = "value1"

val variable2 = <another_grandchild an_attribute="value2" />

var document = <root> <child> <grandchild an_attribute={variable1} /> {variable2} </child> </root>

google app engine

• ‘cloud’ web hosting environment on google’s infrastructure

• uses non relational ‘bigtable’ for data persistance

• user authentication uses google accounts or openid

• also has email (sending), memcache and image manipulation services

basics

class Servlet extends HttpServlet { override def doGet(request: HttpServletRequest, response: HttpServletResponse): Unit = { val out = response.getWriter()... out.println(<html>{head}<body>{body}</body></html>) }}

authentication

var userService = UserServiceFactory.getUserService();var user = userService.getCurrentUser();

if (user == null) { response.sendRedirect(userService.createLoginURL(request.getRequestURI())) return}

persistence

@PersistenceCapable {val identityType = IdentityType.APPLICATION}class Person(@Persistent var firstName: String,@Persistent var lastName: String) { @PrimaryKey @Persistent {val valueStrategy = IdGeneratorStrategy.IDENTITY} var id: java.lang.Long = null }