Bending JAXB to the will of Scala [2/2]
import scala.annotation.target.field | |
import javax.xml.bind.annotation._ | |
import javax.xml.bind.annotation.adapters._ | |
type xmlElement = XmlElement @field | |
type xmlTypeAdapter = XmlJavaTypeAdapter @field | |
/** | |
* NB As with the CustomOptionAdapter we've had to modify the type signature here, | |
* https://github.com/krasserm/eventsourcing-example/blob/play-blog/modules/service/src/main/scala/dev/example/eventsourcing/util/Binding.scala | |
* because of the bug in MOXy requiring that the first type parameter of the List Adapter | |
* be the same as the first type parameter of XmlAdapter | |
*/ | |
abstract class AbstractListAdapter[B <: AbstractList[A], A] extends XmlAdapter[B, List[A]] { | |
import scala.collection.JavaConverters._ | |
def marshal(v: List[A]) = { | |
if (v == null) { | |
create(new ArrayList[A]) | |
} else create(v.asJava) | |
} | |
def unmarshal(v: B) = { | |
v.elem.asScala.toList | |
} | |
def create(l: JList[A]): B | |
} | |
trait AbstractList[A] { | |
def elem: JList[A] | |
} | |
object Person { | |
import java.util.{List => JList} | |
class PersonsAdapter extends AbstractListAdapter[PersonItems,Person] { | |
def create(l: JList[Person]) = new PersonItems(l) | |
} | |
@XmlAccessorType(XmlAccessType.FIELD) | |
case class PersonItems(@xmlElementRef(name = "person") elem: JList[Person]) extends AbstractList[Person] { | |
def this() = this(null) | |
} | |
} | |
@XmlRootElement | |
@XmlAccessorType(XmlAccessType.FIELD) | |
case class Person(name:String){ | |
private def this() = this("") | |
} | |
@XmlRootElement | |
@XmlAccessorType(XmlAccessType.FIELD) | |
case class Entry(@xmlElement id:String, | |
@xmlTypeAdapter(classOf[Person.PersonsAdapter]) authors:List[Person]= List()) { | |
private def this() = this("", List()) | |
} |
java.lang.ClassCastException: scala.collection.immutable.$colon$colon cannot be cast to java.util.Collection | |
at org.eclipse.persistence.internal.queries.CollectionContainerPolicy.iteratorFor(CollectionContainerPolicy.java:150) | |
at org.eclipse.persistence.internal.oxm.XMLCompositeDirectCollectionMappingNodeValue.marshal(XMLCompositeDirectCollectionMappingNodeValue.java:78) | |
at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:149) | |
at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:102) | |
at org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(ObjectMarshalContext.java:59) | |
at org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:401) | |
at org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(XPathObjectBuilder.java:240) | |
at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:118) | |
at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:1) | |
at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:751) |
import scala.annotation.target.field | |
import javax.xml.bind.annotation._ | |
import javax.xml.bind.annotation.adapters._ | |
import scala.collection.mutable | |
import scala.runtime.ScalaRunTime | |
type xmlElement = XmlElement @field | |
@XmlRootElement | |
@XmlAccessorType(XmlAccessType.FIELD) | |
case class Person(name:String) { | |
private def this() = this("") | |
} | |
@XmlRootElement | |
@XmlAccessorType(XmlAccessType.FIELD) | |
case class Entry(id:String, author:Array[Person] = Array[Person]()) { | |
private def this() = this("", Array[Person]()) | |
def productArity = 2 | |
def productElement(n: Int): Any = n match { | |
case 0 => id | |
case 1 => mutable.WrappedArray.make(contributor) | |
case _ => throw new IndexOutOfBoundsException(n.toString) | |
} | |
override def equals(that: Any) = ScalaRunTime._equals(this, that) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment