Scala for Sling
Building RESTful Web Applications with Scala for Sling
http://people.apache.org/~mduerig/scala4sling/




...
2


AGENDA

> Introduction

> What is Apache Sling?

> What is Scala?

> Scala for Sling

> Summary and questions
3


Introduction

> Michael Dürig
  –   Developer for Day Software
  –   http://michid.wordpress.com/


> Michael Marth
  ...
4


Overview

> What to expect
  –   Proof of concept
  –   Experimental code


> What not to expect
  –   Product showcas...
5


AGENDA

> Introduction

> What is Apache Sling?

> What is Scala?

> Scala for Sling

> Summary and questions
6


Sling builds on JCR

> Web application framework for JCR
  –   JCR (JSR-170/JSR-283): Apache Jackrabbit
  –   OSGi-bas...
7


URL decomposition


       GET   /forum/scala4sling.thread.html
8


URL decomposition


             GET   /forum/scala4sling.thread.html


Repository
9


URL decomposition


             GET   /forum/scala4sling.thread.html


Repository
             Repository path
10


URL decomposition


             GET   /forum/scala4sling.thread.html


Repository
             Repository path




 ...
11


URL decomposition


             GET   /forum/scala4sling.thread.html


Repository
             Repository path      ...
12


AGENDA

> Introduction

> What is Apache Sling?

> What is Scala?

> Scala for Sling

> Summary and questions
13


Scala builds on the JVM

> Multi-paradigm language for the JVM
  –   Conceived by Martin Odersky and his group (EPFL,...
14


Type inference: the scripting touch

> Values
  val x = 42               // x has type Int
  val s = x.toString      ...
15


Type inference: the scripting touch

> Values
   val x = 42               //   x has type Int
   val s = x.toString  ...
16


XML <pre>literals</pre>

> HTML? Scala!
  val title = "Hello Jazoon 09"

  println {
    <html>
      <body>
        ...
17


XML <pre>literals</pre>

> HTML? Scala!
  val title = "Hello Jazoon 09"

  println {
    <html>    println {
      <b...
18


XML <pre>literals</pre>

> HTML? Scala!
  val title = "Hello Jazoon 09"

  println {
    <html>
      <body>
        ...
19


Implicits: pimp my library

> Implicit conversion
  implicit def translate(s: String) = new {
    def toGerman = s ma...
20


Objects are functions are objects…

> Object as function
  object Twice {
    def apply(n: Int) = 2*n
  }

  println(...
21


AGENDA

> Introduction

> What is Apache Sling?

> What is Scala?

> Scala for Sling

> Summary and questions
22


Demo application: Forum
23


Forum: html.scala

package forum {
  object html {
  import html_Bindings._
  // ...

    println {
      <html>
    ...
24


Forum: html.scala
                              GET   /forum.html
package forum {
  object html {
  import html_Bindi...
25


Forum: html.scala

package forum {
  object html {
                              Put Sling variables into scope
  imp...
26


Forum: html.scala

package forum {
  object html {
                 /**
  import html_Bindings._
  // ...          * ...
27


Forum: html.scala

package forum {
  object html {
                 /**
  import html_Bindings._
  // ...          * ...
28


Forum: html.scala

package forum {
  object html {
  import html_Bindings._
  // implicit def rich(node: Node) = new ...
29


Forum: thread overview

object ThreadOverview {
  // imports omitted

    def render(node: Node) =
      emptyUnless(...
30


Forum: thread overview

object ThreadOverview {
                def emptyUnless(condition: Boolean)(block: => NodeSeq...
31


Forum: form data

object ThreadNewForm {
  def render = {
    <h1>start a new thread</h1>
    <form action="/content/...
32


Forum: form data

object ThreadNewForm {
  def render = {
    <h1>start a new thread</h1>
    <form action="/content/...
33


Forum: form data

object ThreadNewForm {
  def render = {
                                 POST should add new       ...
34


Forum: form data

object ThreadNewForm {
  def render = {
                                 POST should add new child ...
35


Forum: form data

object ThreadNewForm {
  def render = {
                                 POST should add new child ...
36


Forum: form data

object ThreadNewForm {
  def render = {
    <h1>start a new thread</h1>
    <form action="/content/...
37


Extracting form fields

> Sling post servlet
  –   No action required: used by default
  –   Creates nodes and proper...
38


Forum: custom POST request handler
package forum {
  object POST {
    import POST_Bindings._
    // ...

        val...
39


Forum: custom POST request handler
package forum {            POST       /forum.html
  object POST {
    import POST_...
40


Forum: custom POST request handler
package forum {
  object POST {
    import POST_Bindings._
    // ...             ...
41


Forum: custom POST request handler
package forum {
  object POST {
    import POST_Bindings._
    // ...
            ...
42


Forum: custom POST request handler
package forum {
  object POST {
    import POST_Bindings._
    // ...

        val...
43


Forum: custom POST request handler
package forum {
  object POST {
    import POST_Bindings._
    // ...

        val...
44


Forum: custom POST request handler
package forum {
  object POST {
    import POST_Bindings._
    // ...

        val...
45


Forum: custom POST request handler
package forum {
  object POST {
    import POST_Bindings._
    // ...

        val...
46


Forum: unit testing

object html_Bindings extends MockBindings {
  override def currentNode = new MockNode
          ...
47


Forum: unit testing

object html_Bindings extends MockBindings {
  override def currentNode = new MockNode
          ...
48


Forum: unit testing

object html_Bindings extends MockBindings {
  override def currentNode = new MockNode
          ...
49


Forum: unit testing
          <html>
            <head>
              <link href="/apps/forum/static/blue.css" rel="s...
50


AGENDA

> Introduction

> What is Apache Sling?

> What is Scala?

> Scala for Sling

> Summary and questions
51


Conclusion

> Advantages
  –   Scala!
  –   No language boundary
  –   Tool support (i.e. IDE, ScalaDoc,
      safe r...
52


Conclusion

> Advantages
  –   Scala!
  –   No language boundary
  –   Tool support (i.e. IDE, ScalaDoc,
      safe r...
53


Conclusion

> Advantages
  –   Scala!
                                          <p>Welcome to { currentNode("name") }...
54


Conclusion

> Advantages
  –   Scala!
  –   No language boundary
  –   Tool support (i.e. IDE, ScalaDoc,
      safe r...
55


Conclusion

> Advantages
  –   Scala!
  –   No language boundary
  –   Tool support (i.e. IDE, ScalaDoc,
      safe r...
56


Conclusion

> Advantages
  –   Scala!
  –   No language boundary
                                          object htm...
57


Conclusion

> Advantages
  –   Scala!
  –   No language boundary
  –   Tool support (i.e. IDE, ScalaDoc,
      safe r...
58


Summary

> Apache Sling
  –   Great for building RESTful web applications
  –   Pluggable scripting support (JSR-223)...
Michael Dürig                                  michael.duerig@day.com
Michael Marth                                  micha...
Upcoming SlideShare
Loading in …5
×

Scala4sling

1,444 views

Published on

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,444
On SlideShare
0
From Embeds
0
Number of Embeds
107
Actions
Shares
0
Downloads
19
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Scala4sling

  1. 1. Scala for Sling Building RESTful Web Applications with Scala for Sling http://people.apache.org/~mduerig/scala4sling/ Michael Dürig Day Software AG 10080 LOGO SPEAKER‘S COMPANY
  2. 2. 2 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  3. 3. 3 Introduction > Michael Dürig – Developer for Day Software – http://michid.wordpress.com/ > Michael Marth – Technology Evangelist for Day Software – http://dev.day.com/
  4. 4. 4 Overview > What to expect – Proof of concept – Experimental code > What not to expect – Product showcase, tutorial – Live coding (demo code available from http://people.apache.org/~mduerig/scala4sling/) > Prerequisites – Basic understanding of Java content repositories (JCR) – Prior exposure to Scala a plus
  5. 5. 5 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  6. 6. 6 Sling builds on JCR > Web application framework for JCR – JCR (JSR-170/JSR-283): Apache Jackrabbit – OSGi-based: Apache Felix – http://incubator.apache.org/sling/ > Scriptable application layer for JCR – JSR-223: Scripting for the Java platform > REST over JCR – Content resolution for mapping request URLs to JCR nodes – Servlet resolution for mapping JCR nodes to request handlers (i.e. scripts)
  7. 7. 7 URL decomposition GET /forum/scala4sling.thread.html
  8. 8. 8 URL decomposition GET /forum/scala4sling.thread.html Repository
  9. 9. 9 URL decomposition GET /forum/scala4sling.thread.html Repository Repository path
  10. 10. 10 URL decomposition GET /forum/scala4sling.thread.html Repository Repository path Application selection
  11. 11. 11 URL decomposition GET /forum/scala4sling.thread.html Repository Repository path Script selection Application selection
  12. 12. 12 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  13. 13. 13 Scala builds on the JVM > Multi-paradigm language for the JVM – Conceived by Martin Odersky and his group (EPFL, Lausanne) – Fully interoperable with Java – IDE plugins for Eclipse and IntelliJ IDEA – http://www.scala-lang.org/ > Concise, elegant, and type safe – Touch and feel of a genuine scripting language – Smoothly integrates object oriented and functional features – Great for creating DSLs
  14. 14. 14 Type inference: the scripting touch > Values val x = 42 // x has type Int val s = x.toString // s has type String val q = s.substring(s) // type mismatch; found String, required Int > Type parameters class Pair[S, T](s: S, t: T) def makePair[S, T](s: S, t: T) = new Pair(s, t) val p = makePair(42.0, "Scala") // p has type Pair[Double, String]
  15. 15. 15 Type inference: the scripting touch > Values val x = 42 // x has type Int val s = x.toString // s has type String val q = s.substring(s) // class Pair<S, T> type mismatch; found String, required Int { public final S s; public final T t; > Type parameters public Pair(S s, T t) { super(); class Pair[S, T](s: S, t: =T) this.s s; def makePair[S, T](s: S, t: t; = new Pair(s, t) this.t = T) } val p = makePair(42.0, "Scala") // p has type Pair[Double, String] } public <S, T> Pair<S, T> makePair(S s, T t) { return new Pair<S, T>(s, t); } public final Pair<Double, String> p = makePair(42.0, "Scala");
  16. 16. 16 XML <pre>literals</pre> > HTML? Scala! val title = "Hello Jazoon 09" println { <html> <body> <h1>{ title }</h1> { (for (c <- title) yield c) .mkString(" ") } </body> </html> }
  17. 17. 17 XML <pre>literals</pre> > HTML? Scala! val title = "Hello Jazoon 09" println { <html> println { <body> Elem(null, "html", Null, TopScope, <h1>{ title }</h1> "body", Null, TopScope, Elem(null, { Elem(null, "h1", Null, TopScope, (for (c <- title) yield c) Text(title) .mkString(" ") ), } Text( </body> (for (c <- title) yield c) </html> .mkString(" ") } ) ) ) }
  18. 18. 18 XML <pre>literals</pre> > HTML? Scala! val title = "Hello Jazoon 09" println { <html> <body> <h1>{ title }</h1> { (for (c <- title) yield c) .mkString(" ") } </body> <html> </html> <body> } <h1>Hello Jazoon 09</h1> H e l l o J a z o o n 0 9 </body> </html>
  19. 19. 19 Implicits: pimp my library > Implicit conversion implicit def translate(s: String) = new { def toGerman = s match { case "Example" => "Beispiel" // ... case _ => throw new Exception("No translation for " + s) } } val german = "Example".toGerman > Déjà vu? – Similar to extension methods in C# – Similar to conversion constructors in C++ – Equivalent to type classes in Haskell
  20. 20. 20 Objects are functions are objects… > Object as function object Twice { def apply(n: Int) = 2*n } println(Twice(21)) // prints 42 > Function as object def twice(n: Int) = 2*n val doubler = twice(_) println(doubler(21)) // prints 42
  21. 21. 21 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  22. 22. 22 Demo application: Forum
  23. 23. 23 Forum: html.scala package forum { object html { import html_Bindings._ // ... println { <html> <body> Welcome to the { currentNode("name") } forum &mdash; { Calendar.getInstance.getTime } { ThreadNewForm.render } { ThreadOverview.render(currentNode) } </body> </html> } }
  24. 24. 24 Forum: html.scala GET /forum.html package forum { object html { import html_Bindings._ // ... println { <html> <body> Welcome to the { currentNode("name") } forum &mdash; { Calendar.getInstance.getTime } { ThreadNewForm.render } { ThreadOverview.render(currentNode) } </body> </html> } }
  25. 25. 25 Forum: html.scala package forum { object html { Put Sling variables into scope import html_Bindings._ (currentNode, request, response, etc.) // ... println { <html> <body> Welcome to the { currentNode("name") } forum &mdash; { Calendar.getInstance.getTime } { ThreadNewForm.render } { ThreadOverview.render(currentNode) } </body> </html> } }
  26. 26. 26 Forum: html.scala package forum { object html { /** import html_Bindings._ // ... * Print out an object followed by a new line character. * @param x the object to print. */ println { def println(x: Any): Unit = out.println(x) <html> <body> Welcome to the { currentNode("name") } forum &mdash; { Calendar.getInstance.getTime } { ThreadNewForm.render } { ThreadOverview.render(currentNode) } </body> </html> } }
  27. 27. 27 Forum: html.scala package forum { object html { /** import html_Bindings._ // ... * Print out an object followed by a new line character. * @param x the object to print. */ println { def println(x: Any): Unit = out.println(x) <html> <body> Welcome to the { currentNode("name") } forum &mdash; { Calendar.getInstance.getTime } { ThreadNewForm.render } { ThreadOverview.render(currentNode) } </body> </html> } }
  28. 28. 28 Forum: html.scala package forum { object html { import html_Bindings._ // implicit def rich(node: Node) = new { ... def apply(property: String) = node.getProperty(property).getString ... println { } <html> <body> Welcome to the { currentNode("name") } forum &mdash; { Calendar.getInstance.getTime } { ThreadNewForm.render } { ThreadOverview.render(currentNode) } </body> </html> } }
  29. 29. 29 Forum: thread overview object ThreadOverview { // imports omitted def render(node: Node) = emptyUnless(node.hasNodes) { <h1>threads</h1> <ul>{ node.nodes map toListItem }</ul> } private def toListItem(node: Node) = { <li> { node("subject") } (<a href={ node.path + ".thread.html"}>show thread</a>) </li> } }
  30. 30. 30 Forum: thread overview object ThreadOverview { def emptyUnless(condition: Boolean)(block: => NodeSeq) = // imports omitted if (condition) block else Empty def render(node: Node) = emptyUnless(node.hasNodes) { <h1>threads</h1> <ul>{ node.nodes map toListItem }</ul> } private def toListItem(node: Node) = { <li> { node("subject") } (<a href={ node.path + ".thread.html"}>show thread</a>) </li> } }
  31. 31. 31 Forum: form data object ThreadNewForm { def render = { <h1>start a new thread</h1> <form action="/content/forum/*" method="POST" enctype="multipart/form-data"> subject <input name="subject" type="text" /> <textarea name="body"></textarea> logo <input name="logo“ type="file" /> <input type="submit" value="save" /> <input name=":redirect" value="/content/forum.html" type="hidden" /> </form> } }
  32. 32. 32 Forum: form data object ThreadNewForm { def render = { <h1>start a new thread</h1> <form action="/content/forum/*" method="POST" enctype="multipart/form-data"> subject <input name="subject" type="text" /> <textarea name="body"></textarea> logo <input name="logo“ type="file" /> <input type="submit" value="save" /> <input name=":redirect" value="/content/forum.html" type="hidden" /> </form> } }
  33. 33. 33 Forum: form data object ThreadNewForm { def render = { POST should add new child node to /content/forum/ <h1>start a new thread</h1> <form action="/content/forum/*" method="POST" enctype="multipart/form-data"> subject <input name="subject" type="text" /> <textarea name="body"></textarea> logo <input name="logo“ type="file" /> <input type="submit" value="save" /> <input name=":redirect" value="/content/forum.html" type="hidden" /> </form> } }
  34. 34. 34 Forum: form data object ThreadNewForm { def render = { POST should add new child node to /content/forum/ <h1>start a new thread</h1> <form action="/content/forum/*" with properties subject and body ... method="POST" of enctype="multipart/form-data"> type String, subject <input name="subject" type="text" /> <textarea name="body"></textarea> logo <input name="logo“ type="file" /> <input type="submit" value="save" /> <input name=":redirect" value="/content/forum.html" type="hidden" /> </form> } }
  35. 35. 35 Forum: form data object ThreadNewForm { def render = { POST should add new child node to /content/forum/ <h1>start a new thread</h1> <form action="/content/forum/*" with properties subject and body ... method="POST" of enctype="multipart/form-data"> type String, subject <input name="subject" and a child node logo of type nt:file. ... type="text" /> <textarea name="body"></textarea> logo <input name="logo“ type="file" /> <input type="submit" value="save" /> <input name=":redirect" value="/content/forum.html" type="hidden" /> </form> } }
  36. 36. 36 Forum: form data object ThreadNewForm { def render = { <h1>start a new thread</h1> <form action="/content/forum/*" method="POST" enctype="multipart/form-data"> subject <input name="subject" type="text" /> <textarea name="body"></textarea> logo <input name="logo“ type="file" /> <input type="submit" value="save" /> <input name=":redirect" value="/content/forum.html" type="hidden" /> </form> } Redirect to forum.html on success }
  37. 37. 37 Extracting form fields > Sling post servlet – No action required: used by default – Creates nodes and properties for form fields – Tweaked with hidden form fields – Sensible defaults > Custom POST request handler – Write a script POST.scala – Process form fields in code – Full control over request processing
  38. 38. 38 Forum: custom POST request handler package forum { object POST { import POST_Bindings._ // ... val node = addNodes(session.root, newPath) node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) if (request("logo") != "") { val logoNode = node.addNode("logo", "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) } session.save response.sendRedirect(request(":redirect")) } }
  39. 39. 39 Forum: custom POST request handler package forum { POST /forum.html object POST { import POST_Bindings._ // ... val node = addNodes(session.root, newPath) node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) if (request("logo") != "") { val logoNode = node.addNode("logo", "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) } session.save response.sendRedirect(request(":redirect")) } }
  40. 40. 40 Forum: custom POST request handler package forum { object POST { import POST_Bindings._ // ... Add node for this post val node = addNodes(session.root, newPath) node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) if (request("logo") != "") { val logoNode = node.addNode("logo", "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) } session.save response.sendRedirect(request(":redirect")) } }
  41. 41. 41 Forum: custom POST request handler package forum { object POST { import POST_Bindings._ // ... Set properties for body and subject val node = addNodes(session.root, newPath) node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) if (request("logo") != "") { val logoNode = node.addNode("logo", "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) } session.save response.sendRedirect(request(":redirect")) } }
  42. 42. 42 Forum: custom POST request handler package forum { object POST { import POST_Bindings._ // ... val node = addNodes(session.root, newPath) If the request contains a logo node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) if (request("logo") != "") { val logoNode = node.addNode("logo", "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) } session.save response.sendRedirect(request(":redirect")) } }
  43. 43. 43 Forum: custom POST request handler package forum { object POST { import POST_Bindings._ // ... val node = addNodes(session.root, newPath) If the request contains a logo node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) ... add a child node logo of type nt:file if (request("logo") != "") { val logoNode = node.addNode("logo", "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) } session.save response.sendRedirect(request(":redirect")) } }
  44. 44. 44 Forum: custom POST request handler package forum { object POST { import POST_Bindings._ // ... val node = addNodes(session.root, newPath) If the request contains a logo node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) ... add a child node logo of type nt:file if (request("logo") != "") { val logoNode = node.addNode("logo", set properties jcr:lastModified, ... and "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") jcr:mimeType and jcr:data val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) } session.save response.sendRedirect(request(":redirect")) } }
  45. 45. 45 Forum: custom POST request handler package forum { object POST { import POST_Bindings._ // ... val node = addNodes(session.root, newPath) node.setProperty("body", request("body")) node.setProperty(“subject", request(“subject")) if (request("logo") != "") { val logoNode = node.addNode("logo", "nt:file") val contentNode = logoNode.addNode("jcr:content", "nt:resource") val logo = request.getRequestParameter("logo") contentNode.setProperty("jcr:lastModified", Calendar.getInstance) contentNode.setProperty("jcr:mimeType", logo.getContentType) contentNode.setProperty("jcr:data", logo.getInputStream) Save changes and send redirect } session.save response.sendRedirect(request(":redirect")) } }
  46. 46. 46 Forum: unit testing object html_Bindings extends MockBindings { override def currentNode = new MockNode with MockItem override def request = new MockSlingHttpServletRequest with MockHttpServletRequest with MockServletRequest } object Test extends Application { forum.html }
  47. 47. 47 Forum: unit testing object html_Bindings extends MockBindings { override def currentNode = new MockNode with MockItem override def request = new MockSlingHttpServletRequest with MockHttpServletRequest with MockServletRequest } object Test extends Application { forum.html }
  48. 48. 48 Forum: unit testing object html_Bindings extends MockBindings { override def currentNode = new MockNode with MockItem override def request = new MockSlingHttpServletRequest with MockHttpServletRequest with MockServletRequest } object Test extends Application { forum.html }
  49. 49. 49 Forum: unit testing <html> <head> <link href="/apps/forum/static/blue.css" rel="stylesheet"></link> object html_Bindings extends MockBindings { </head> <body> override def currentNode = new MockNode <div id="Header"> Welcome to the forum with MockItem &mdash; Wed Jun 17 17:12:48 CEST 2009 </div> <div id="Menu"> override def <p>search all threads: request = new MockSlingHttpServletRequest <form action="/content/forum.search.html" with MockHttpServletRequest enctype="multipart/form-data" method="GET"> <input value="" type="text" size="10" name="query"></input> with MockServletRequest <input value="search" type="submit"></input> } </form> </p> </div> <div id="Content"> object Test extends Application { <h1>start a new thread</h1> <span id="inp"> forum.html <form action="/content/forum/*" enctype="multipart/form-data" method="POST"> } <p>subject</p> <p><input type="text" name="subject"></input></p> <p><textarea name="body"></textarea></p> <p>logo</p> <p><input type="file" name="logo"></input></p> <p><input value="save" type="submit"></input></p> <input value="/content/forum.html" type="hidden" name=":redirect"></input> </form> </span> </div> </body> </html>
  50. 50. 50 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  51. 51. 51 Conclusion > Advantages – Scala! – No language boundary – Tool support (i.e. IDE, ScalaDoc, safe refactoring, unit testing) > Disadvantages – IDE support shaky, improves quickly though – Not much refactoring support as of today
  52. 52. 52 Conclusion > Advantages – Scala! – No language boundary – Tool support (i.e. IDE, ScalaDoc, safe refactoring, unit testing) > Disadvantages – IDE support shaky, improves quickly though – Not much refactoring support as of today
  53. 53. 53 Conclusion > Advantages – Scala! <p>Welcome to { currentNode("name") } forum</p> – No language boundary &mdash; { Calendar.getInstance.getTime } { ThreadNewForm.render } – Tool support (i.e. IDE, ScalaDoc, { ThreadOverview.render(currentNode) } safe refactoring, unit testing) > Disadvantages – IDE support shaky, improves quickly though – Not much refactoring support as of today
  54. 54. 54 Conclusion > Advantages – Scala! – No language boundary – Tool support (i.e. IDE, ScalaDoc, safe refactoring, unit testing) > Disadvantages – IDE support shaky, improves quickly though – Not much refactoring support as of today
  55. 55. 55 Conclusion > Advantages – Scala! – No language boundary – Tool support (i.e. IDE, ScalaDoc, safe refactoring, unit testing) > Disadvantages – IDE support shaky, improves quickly though – Not much refactoring support as of today
  56. 56. 56 Conclusion > Advantages – Scala! – No language boundary object html_Bindings { – Tool support (i.e. IDE, ScalaDoc, def currentNode = new MockNode safe refactoring, unit testing) ... } object Test extends Application { > Disadvantages forum.html } – IDE support shaky, improves quickly though – Not much refactoring support as of today
  57. 57. 57 Conclusion > Advantages – Scala! – No language boundary – Tool support (i.e. IDE, ScalaDoc, safe refactoring, unit testing) > Disadvantages – IDE support shaky, improves quickly though – Not much refactoring support as of today
  58. 58. 58 Summary > Apache Sling – Great for building RESTful web applications – Pluggable scripting support (JSR-223) > Scala – Great for scripting – Supports «on the fly» templates through XML literals – Easy unit testing
  59. 59. Michael Dürig michael.duerig@day.com Michael Marth michael.marth@day.com Day Software AG http://www.day.com/ References: • Scala for Sling: http://people.apache.org/~mduerig/scala4sling/ • The Scala programming language: http://www.scala-lang.org/ • Apache Sling: http://incubator.apache.org/sling/ LOGO SPEAKER‘S COMPANY

×