Richard Searle

home

Scala implicits to simplify XPathFunction

07 Sep 2010

Custom functions for xpath expressions can be defined via XPathFunction. The standard Java code is verbose, with the explicit type casting of the arguments only increasing the code size. An ideal implementation would allow the use of standard Scala functions, and provide an automagic conversion to XPathFunction required for integration with the Java XPath implementation.
class One[T,R<:Object](val f:Function1[T,R])  extends XPathFunction {
 def evaluate(list:java.util.List[_]) = f(list.get(0).asInstanceOf[T])
 }
Defines a class that wraps a Function1 and adapts it to the XPathFunction. Note that R must be a type that extends Object to conform to the XPathExpression.evaluate return type.
implicit def f1ToOne[T,R<:Object](f:Function1[T,R])=new One(f)
Provides an implicit conversion from Function1 to One (and hence to an implementation of XPathFunction)
Map[String,XPathFunction]("a1"->{i:String=>i*2})
Creates a simple naming from name to an XPathFunction, using anonymous Scala functions. Additional adapter class, implicit conversion function pairs are then needed to cover the remaining FunctionN cases. The Scala functions must still be written using Java types and in a manner that conforms to the expectations of XPathFunction. This is illegal
Map[String,XPathFunction]("a1"->{i:Int=>i*2})
Since Int does not extend Object.
Map[String,XPathFunction]("a1"->{i:Integer=>i.intValue()*2})
Has the same return type and is still illegal. But this is acceptable
Map[String,XPathFunction]("a1"->{i:Integer=>new Integer(i.intValue()*2)})