This is the example code for my blog JCR with Scala: Adding Properties in ASCII Art.
package com.day.scalademo.treebuilder2;
import org.apache.jackrabbit.core.TransientRepository
import javax.jcr.{Node, Property, SimpleCredentials}
object Treebuilder2 {
import Extensions._
def main(args: Array[String]) {
val repository = new TransientRepository
val session = repository.login(new SimpleCredentials("username", "password".toCharArray));
try {
val node = session.getRootNode ¦- "test"
addSubtree(node)
dump(node)
}
finally {
session.logout
}
}
def addSubtree(n: Node) {
n ¦- "movies" -+ { n: Node =>
n ¦- "cast" -+ { n: Node =>
n ¦= ("Gena Rowlands", "Victoria Snelling")
n ¦= ("Winona Ryder", "Corky")
n ¦= ("Roberto Benigni", "Taxi Driver")
}
n ¦= ("title", "Night on Earth")
n ¦= ("length", 123L)
n ¦= ("ratings", 9L::8L::5L::Nil)
n ¦= ("languages", "en"::"it"::"fi"::"fr"::Nil)
}
n ¦- "movies" -+ { n: Node =>
n ¦- "cast" -+ { n: Node =>
n ¦= ("James Stewart", "Det. Ferguson")
n ¦= ("Tom Helmore", "Gavin Elster")
n ¦= ("Henry Jones", "Coroner")
}
n ¦= ("title", "Vertigo")
n ¦= ("length", 124L)
n ¦= ("ratings", 10L::8L::7L::Nil)
n ¦= ("languages", "en"::Nil)
}
}
def dump(node: Node) {
println(node.getPath)
for (property <- node.properties) {
if (property.getDefinition.isMultiple)
for(value <- property.getValues)
println(property.getPath + " = " + value.getString)
else
println(property.getPath + " = " + property.getString)
}
for (child <- node.childNodes)
dump(child)
}
}
object Extensions {
import javax.jcr.{Value, ValueFactory}
implicit def extendNode(node: Node) = new NodeExtender(node)
abstract class Val[-T](value: T) {
def setOnNode(node: Node, name: String, factory: ValueFactory)
def toValue(factory: ValueFactory): Value
}
implicit def longToVal(l: long) = new Val(l) {
def setOnNode(node: Node, name: String, factory: ValueFactory) =
node.setProperty(name, factory.createValue(l))
def toValue(factory: ValueFactory) = factory.createValue(l)
}
implicit def stringToVal(s: String) = new Val(s) {
def setOnNode(node: Node, name: String, factory: ValueFactory) =
node.setProperty(name, factory.createValue(s))
def toValue(factory: ValueFactory) = factory.createValue(s)
}
implicit def listToVal[T](seq: Seq[T])(implicit toVal: T => Val[T]) = new Val(seq) {
def setOnNode(node: Node, name: String, factory: ValueFactory) = {
val values = seq.map(toVal(_).toValue(factory)).toArray
node.setProperty(name, values)
}
def toValue(factory: ValueFactory) = error("not applicable")
}
}
protected class NodeExtender(node: Node) {
private lazy val valueFactory = node.getSession.getValueFactory
def childNodes = new Iterator[Node] {
val it = node.getNodes
def hasNext = it.hasNext
def next = it.nextNode
}
def properties = new Iterator[Property] {
val it = node.getProperties
def hasNext = it.hasNext
def next = it.nextProperty
}
def -+[T](f: Node => T) = f(node)
def ¦-(relPath: String) = node.addNode(relPath)
def ¦-(relPath: String, tyqe: String) = node.addNode(relPath, tyqe)
def ¦=[T <% Extensions.Val[T]](name: String, value: T) = value.setOnNode(node, name, valueFactory)
}