SlideShare a Scribd company logo
1 of 59
Download to read offline
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


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
  –   Technology Evangelist for Day Software
  –   http://dev.day.com/
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


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-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


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




                       Application selection
11


URL decomposition


             GET   /forum/scala4sling.thread.html


Repository
             Repository path                    Script selection




                       Application selection
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, 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


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


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


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


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


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


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


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


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>
        <body>
          Welcome to the { currentNode("name") } forum
          &mdash; { Calendar.getInstance.getTime }
          { ThreadNewForm.render }
          { ThreadOverview.render(currentNode) }
        </body>
      </html>
    }
}
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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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 refactoring, unit testing)


> Disadvantages
  –   IDE support shaky, improves
      quickly though
  –   Not much refactoring support as
      of today
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


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


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


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


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


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


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
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

More Related Content

What's hot

開放運算&GPU技術研究班
開放運算&GPU技術研究班開放運算&GPU技術研究班
開放運算&GPU技術研究班Paul Chao
 
Php Development With Eclipde PDT
Php Development With Eclipde PDTPhp Development With Eclipde PDT
Php Development With Eclipde PDTBastian Feder
 
PuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, Puppet
PuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, PuppetPuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, Puppet
PuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, PuppetPuppet
 
Salesforce CLI Cheat Sheet
Salesforce CLI Cheat Sheet Salesforce CLI Cheat Sheet
Salesforce CLI Cheat Sheet Keir Bowden
 
What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?Demis Bellot
 
Powershell Seminar @ ITWorx CuttingEdge Club
Powershell Seminar @ ITWorx CuttingEdge ClubPowershell Seminar @ ITWorx CuttingEdge Club
Powershell Seminar @ ITWorx CuttingEdge ClubEssam Salah
 
Powershell Training
Powershell TrainingPowershell Training
Powershell TrainingFahad Noaman
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 
What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?Demis Bellot
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueGleicon Moraes
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseChristian Melchior
 
What istheservicestack
What istheservicestackWhat istheservicestack
What istheservicestackDemis Bellot
 
Apache Hive Hook
Apache Hive HookApache Hive Hook
Apache Hive HookMinwoo Kim
 

What's hot (20)

Caché acelerador de contenido
Caché acelerador de contenidoCaché acelerador de contenido
Caché acelerador de contenido
 
Hadoop
HadoopHadoop
Hadoop
 
開放運算&GPU技術研究班
開放運算&GPU技術研究班開放運算&GPU技術研究班
開放運算&GPU技術研究班
 
C++ for the Web
C++ for the WebC++ for the Web
C++ for the Web
 
Php Development With Eclipde PDT
Php Development With Eclipde PDTPhp Development With Eclipde PDT
Php Development With Eclipde PDT
 
PuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, Puppet
PuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, PuppetPuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, Puppet
PuppetConf. 2016: Puppet Best Practices: Roles & Profiles – Gary Larizza, Puppet
 
Everything as a code
Everything as a codeEverything as a code
Everything as a code
 
Salesforce CLI Cheat Sheet
Salesforce CLI Cheat Sheet Salesforce CLI Cheat Sheet
Salesforce CLI Cheat Sheet
 
Php on Windows
Php on WindowsPhp on Windows
Php on Windows
 
What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?
 
Powershell Seminar @ ITWorx CuttingEdge Club
Powershell Seminar @ ITWorx CuttingEdge ClubPowershell Seminar @ ITWorx CuttingEdge Club
Powershell Seminar @ ITWorx CuttingEdge Club
 
Powershell Training
Powershell TrainingPowershell Training
Powershell Training
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
What is the ServiceStack?
What is the ServiceStack?What is the ServiceStack?
What is the ServiceStack?
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in Practise
 
Migration from ASP to ASP.NET
Migration from ASP to ASP.NETMigration from ASP to ASP.NET
Migration from ASP to ASP.NET
 
What istheservicestack
What istheservicestackWhat istheservicestack
What istheservicestack
 
Apache Hive Hook
Apache Hive HookApache Hive Hook
Apache Hive Hook
 

Similar to Scala4sling

Scala & sling
Scala & slingScala & sling
Scala & slingmichid
 
Scala for scripting
Scala for scriptingScala for scripting
Scala for scriptingmichid
 
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...Databricks
 
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalOop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalMichael Stal
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvmIsaias Barroso
 
BOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala appsBOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala appsPeter Pilgrim
 
Apache spark undocumented extensions
Apache spark undocumented extensionsApache spark undocumented extensions
Apache spark undocumented extensionsSandeep Joshi
 
Dax Declarative Api For Xml
Dax   Declarative Api For XmlDax   Declarative Api For Xml
Dax Declarative Api For XmlLars Trieloff
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLsintelliyole
 
Introduction to Spark with Scala
Introduction to Spark with ScalaIntroduction to Spark with Scala
Introduction to Spark with ScalaHimanshu Gupta
 
Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Karel Minarik
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKShu-Jeng Hsieh
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkIndicThreads
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Frameworkvhazrati
 

Similar to Scala4sling (20)

Scala & sling
Scala & slingScala & sling
Scala & sling
 
Scala for scripting
Scala for scriptingScala for scripting
Scala for scripting
 
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
 
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalOop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvm
 
BOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala appsBOF2644 Developing Java EE 7 Scala apps
BOF2644 Developing Java EE 7 Scala apps
 
Apache spark undocumented extensions
Apache spark undocumented extensionsApache spark undocumented extensions
Apache spark undocumented extensions
 
Dax Declarative Api For Xml
Dax   Declarative Api For XmlDax   Declarative Api For Xml
Dax Declarative Api For Xml
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
Scala in a nutshell by venkat
Scala in a nutshell by venkatScala in a nutshell by venkat
Scala in a nutshell by venkat
 
Introduction to Spark with Scala
Introduction to Spark with ScalaIntroduction to Spark with Scala
Introduction to Spark with Scala
 
Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]Elasticsearch And Ruby [RuPy2012]
Elasticsearch And Ruby [RuPy2012]
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDK
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Full Stack Scala
Full Stack ScalaFull Stack Scala
Full Stack Scala
 
GradleFX
GradleFXGradleFX
GradleFX
 
Overview Of Lift Framework
Overview Of Lift FrameworkOverview Of Lift Framework
Overview Of Lift Framework
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 

More from day

Performance Pack
Performance PackPerformance Pack
Performance Packday
 
Testing Zen
Testing ZenTesting Zen
Testing Zenday
 
Java Persistence Frameworks
Java Persistence FrameworksJava Persistence Frameworks
Java Persistence Frameworksday
 
Embrace OSGi Apache Con Europe2009
Embrace OSGi Apache Con Europe2009Embrace OSGi Apache Con Europe2009
Embrace OSGi Apache Con Europe2009day
 
Scripting Yor Java Application with BSF3
Scripting Yor Java Application with BSF3Scripting Yor Java Application with BSF3
Scripting Yor Java Application with BSF3day
 
Tarpm Clustering
Tarpm ClusteringTarpm Clustering
Tarpm Clusteringday
 
Tech Summit 08 Support Initiative
Tech Summit 08 Support InitiativeTech Summit 08 Support Initiative
Tech Summit 08 Support Initiativeday
 
Non Cms For Web Apps
Non Cms For Web AppsNon Cms For Web Apps
Non Cms For Web Appsday
 
Getting Into The Flow With Cq Dam
Getting Into The Flow With Cq DamGetting Into The Flow With Cq Dam
Getting Into The Flow With Cq Damday
 
Dispatcher Oom
Dispatcher OomDispatcher Oom
Dispatcher Oomday
 
Advanced Collaboration And Beyond
Advanced Collaboration And BeyondAdvanced Collaboration And Beyond
Advanced Collaboration And Beyondday
 
Wc Mand Connectors2
Wc Mand Connectors2Wc Mand Connectors2
Wc Mand Connectors2day
 
Jackrabbit Roadmap
Jackrabbit RoadmapJackrabbit Roadmap
Jackrabbit Roadmapday
 
Doc Book Vs Dita
Doc Book Vs DitaDoc Book Vs Dita
Doc Book Vs Ditaday
 
Doc Book Vs Dita Teresa
Doc Book Vs Dita TeresaDoc Book Vs Dita Teresa
Doc Book Vs Dita Teresaday
 
862
862862
862day
 
Apache Con Us2007 Sanselan
Apache Con Us2007 SanselanApache Con Us2007 Sanselan
Apache Con Us2007 Sanselanday
 
Apache Con Us2007 Jcr In Action
Apache Con Us2007 Jcr In ActionApache Con Us2007 Jcr In Action
Apache Con Us2007 Jcr In Actionday
 
Apache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei BatisApache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei Batisday
 
Apache Con U S07 F F T Sling
Apache Con U S07  F F T  SlingApache Con U S07  F F T  Sling
Apache Con U S07 F F T Slingday
 

More from day (20)

Performance Pack
Performance PackPerformance Pack
Performance Pack
 
Testing Zen
Testing ZenTesting Zen
Testing Zen
 
Java Persistence Frameworks
Java Persistence FrameworksJava Persistence Frameworks
Java Persistence Frameworks
 
Embrace OSGi Apache Con Europe2009
Embrace OSGi Apache Con Europe2009Embrace OSGi Apache Con Europe2009
Embrace OSGi Apache Con Europe2009
 
Scripting Yor Java Application with BSF3
Scripting Yor Java Application with BSF3Scripting Yor Java Application with BSF3
Scripting Yor Java Application with BSF3
 
Tarpm Clustering
Tarpm ClusteringTarpm Clustering
Tarpm Clustering
 
Tech Summit 08 Support Initiative
Tech Summit 08 Support InitiativeTech Summit 08 Support Initiative
Tech Summit 08 Support Initiative
 
Non Cms For Web Apps
Non Cms For Web AppsNon Cms For Web Apps
Non Cms For Web Apps
 
Getting Into The Flow With Cq Dam
Getting Into The Flow With Cq DamGetting Into The Flow With Cq Dam
Getting Into The Flow With Cq Dam
 
Dispatcher Oom
Dispatcher OomDispatcher Oom
Dispatcher Oom
 
Advanced Collaboration And Beyond
Advanced Collaboration And BeyondAdvanced Collaboration And Beyond
Advanced Collaboration And Beyond
 
Wc Mand Connectors2
Wc Mand Connectors2Wc Mand Connectors2
Wc Mand Connectors2
 
Jackrabbit Roadmap
Jackrabbit RoadmapJackrabbit Roadmap
Jackrabbit Roadmap
 
Doc Book Vs Dita
Doc Book Vs DitaDoc Book Vs Dita
Doc Book Vs Dita
 
Doc Book Vs Dita Teresa
Doc Book Vs Dita TeresaDoc Book Vs Dita Teresa
Doc Book Vs Dita Teresa
 
862
862862
862
 
Apache Con Us2007 Sanselan
Apache Con Us2007 SanselanApache Con Us2007 Sanselan
Apache Con Us2007 Sanselan
 
Apache Con Us2007 Jcr In Action
Apache Con Us2007 Jcr In ActionApache Con Us2007 Jcr In Action
Apache Con Us2007 Jcr In Action
 
Apache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei BatisApache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei Batis
 
Apache Con U S07 F F T Sling
Apache Con U S07  F F T  SlingApache Con U S07  F F T  Sling
Apache Con U S07 F F T Sling
 

Recently uploaded

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Recently uploaded (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

Scala4sling

  • 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 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  • 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 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 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  • 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 URL decomposition GET /forum/scala4sling.thread.html
  • 8. 8 URL decomposition GET /forum/scala4sling.thread.html Repository
  • 9. 9 URL decomposition GET /forum/scala4sling.thread.html Repository Repository path
  • 10. 10 URL decomposition GET /forum/scala4sling.thread.html Repository Repository path Application selection
  • 11. 11 URL decomposition GET /forum/scala4sling.thread.html Repository Repository path Script selection Application selection
  • 12. 12 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  • 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 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 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 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 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 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 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 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 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  • 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 AGENDA > Introduction > What is Apache Sling? > What is Scala? > Scala for Sling > Summary and questions
  • 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 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 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 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 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 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 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 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. 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