Scala & sling
-
Upload
michid -
Category
Technology
-
view
1.601 -
download
5
description
Transcript of Scala & sling
LOGO SPEAKER‘S COMPANY
Scala for SlingBuilding RESTful Web Applications with Scala for Slinghttp://people.apache.org/~mduerig/scala4sling/
Michael Dürig
Day Software AG
10080
2
Introduction
> Michael Dürig– Developer for Day Software– http://michid.wordpress.com/
> Michael Marth– Technology Evangelist for Day Software– http://dev.day.com/
3
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
4
AGENDA
> Introduction
> What is Apache Sling?
> What is Scala?
> Scala for Sling
> Summary and questions
5
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)
6
URL decomposition
GET /forum/scala4sling.thread.html
RepositoryRepository path Script selection
Application selection
7
AGENDA
> Introduction
> What is Apache Sling?
> What is Scala?
> Scala for Sling
> Summary and questions
8
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– Ideal for creating internal DSLs
> Values
> Type parameters
9
Type inference: the scripting touch
val x = 42 // x has type Intval s = x.toString // s has type Stringval q = s.substring(s) // type mismatch; found String, required Int
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]
class Pair<S, T> { public final S s; public final T t; public Pair(S s, T t) { super(); this.s = s; this.t = t; }} 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");
Scala vs. Java3 vs. 13 LOC!
10
XML <pre>literals</pre>
> HTML? Scala!val title = "Hello Jazoon 09"
println { Elem(null, "html", Null, TopScope, Elem(null, "body", Null, TopScope, Elem(null, "h1", Null, TopScope, Text(title) ), Text( (for (c <- title) yield c) .mkString(" ") ) ) )}
val title = "Hello Jazoon 09" println { <html> <body> <h1>{ title }</h1> { (for (c <- title) yield c) .mkString(" ") } </body> </html>}
Syntactic sugar
<html> <body> <h1>Hello Jazoon 09</h1> H e l l o J a z o o n 0 9 </body> </html>
System.out
11
Implicits: pimp my library
> Implicit conversion
> Déjà vu?– Similar to extension methods in C#– Similar to conversion constructors in C++ – Equivalent to type classes in Haskell
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
12
AGENDA
> Introduction
> What is Apache Sling?
> What is Scala?
> Scala for Sling
> Summary and questions
13
Demo application: Forum
package forum {
object html {
import html_Bindings._
// ...
println {
<html>
<body>
Welcome to the { currentNode("name") } forum
— { Calendar.getInstance.getTime }
{ ThreadNewForm.render }
{ ThreadOverview.render(currentNode) }
</body>
</html>
}
}
GET /forum.html
Put Sling variables into scope (currentNode, request, response, etc.)
/** * Print out an object followed by a new line character. * @param x the object to print. */def println(x: Any): Unit = out.println(x)
14
Forum: html.scala
implicit def rich(node: Node) = new { def apply(property: String) = node.getProperty(property).getString ...}
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>
}
}
15
Forum: form data
POST should add new child node to /content/forum/
Redirect to forum.html on success
... with properties subject and body of type String,
... and a child node logo of type nt:file.
16
Forum: custom POST request handlerpackage 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")) }}
POST /forum.html
Add node for this postSet properties for body and subject
If the request contains a logo
... add a child node logo of type nt:file
... and set properties jcr:lastModified, jcr:mimeType and jcr:data
Save changes and send redirect
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
}
17
Forum: unit testing<html> <head> <link href="/apps/forum/static/blue.css" rel="stylesheet"></link> </head> <body> <div id="Header"> Welcome to the forum — Wed Jun 17 17:12:48 CEST 2009 </div> <div id="Menu"> <p>search all threads: <form action="/content/forum.search.html" enctype="multipart/form-data" method="GET"> <input value="" type="text" size="10" name="query"></input> <input value="search" type="submit"></input> </form> </p> </div> <div id="Content"> <h1>start a new thread</h1> <span id="inp"> <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>
System.out
18
AGENDA
> Introduction
> What is Apache Sling?
> What is Scala?
> Scala for Sling
> Summary and questions
19
Conclusion
> Advantages– Scala!– No language boundary: «on the
fly» templates through XML literals
– Tool support (i.e. IDE, ScalaDoc, safe refactoring, unit testing)
> Disadvantages– IDE support shaky, improves
quickly though– Not much refactoring support as
of today
object html_Bindings { def currentNode = new MockNode ...}
object Test extends Application { forum.html}
<p>Welcome to { currentNode("name") } forum</p> — { Calendar.getInstance.getTime } { ThreadNewForm.render }{ ThreadOverview.render(currentNode) }
LOGO SPEAKER‘S COMPANY
Michael Dürig [email protected]
Michael Marth [email protected]
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/