Frage

I have developed a Scala and JSF application for learning purpose. In this app I have to convert all my Scala collection objects to Java cllectios before it get rendered in JSF. Is there any easy way this can be achived with something like ScalaElResolver, if yes anybody have a sample code for ScalaElResolver. Thanks in Advance Philip

War es hilfreich?

Lösung

This code is based on ScalaElResolver by Werner Punz. I have stripped it down, so it just handles the conversion from a Scala Iterable to a java.lang.Iterable:

class SimpleScalaElResolver extends ELResolver {
  override def getValue(elContext: ELContext, base: AnyRef, 
                        prop: AnyRef): AnyRef = {
    println(s"SimpleElResolver: getValue: Entering: $base.$prop")
    if (base == null) {
      null
    } else {
      val method = base.getClass.getDeclaredMethod(prop.toString)
      if (method != null) {
        val res = method.invoke(base)
        if (res.isInstanceOf[Iterable[_]]) {
          val iter = res.asInstanceOf[Iterable[_]]
          println("getValue: Wrapping as Java iterable")
          elContext.setPropertyResolved(true)
          JavaConversions.asJavaIterable(iter)
        } else {
          null
        }
      } else {
        null
      }
    }
  }

This is sufficient to get it running using sbt and its web plugin (which uses jetty under the hood), even if all other methods remained "not yet implemented", like this:

override def getCommonPropertyType(elContext: ELContext, o: AnyRef): Class[_] = {
  ???
}

The other methods were not called in my case.

I've tested it only from within a .jspx; as far as I know this should work with JSF as well.


Example: If you have a class

class Model(val list: List[Int])

and in your controller

val model = new Model(List(1))

httpRequest.setAttribute("model", model)

you can access the instance in EL

        <ul>
            <c:forEach var="i" items="${ model.list }">
                <li>
                    <c:out value="${ i }"/>
                </li>
            </c:forEach>
        </ul>

so the property name in EL exactly matches the name of the val in your model class. Otherwise you get a java.lang.NoSuchMethodException.

Andere Tipps

Hi I just opened a scalaelresolver project on github, https://github.com/werpu/scalaelresolver the resolver does besides resolving scala properties also the collection conversions. An example is included.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top