Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I create a class hierarchy of typed factory method constructors and access them from Scala using abstract types?
    primarykey
    data
    text
    <p>(Essentially I need some kind of a synthesis of these two questions (<a href="https://stackoverflow.com/questions/1586811/is-there-a-self-type-in-scala-that-represents-the-current-type">1</a>, <a href="https://stackoverflow.com/questions/7616692/how-can-i-invoke-the-constructor-of-a-scala-abstract-type">2</a>), but I'm not smart enough to combine them myself.)</p> <p>I have a set of JAXB representations in Scala like this:</p> <pre><code>abstract class Representation { def marshalToXml(): String = { val context = JAXBContext.newInstance(this.getClass()) val writer = new StringWriter context.createMarshaller.marshal(this, writer) writer.toString() } } class Order extends Representation { @BeanProperty var name: String = _ ... } class Invoice extends Representation { ... } </code></pre> <p>The problem I have is with my unmarshalling "constructor" methods:</p> <pre><code>def unmarshalFromJson(marshalledData: String): {{My Representation Subclass}} = { val mapper = new ObjectMapper() mapper.getDeserializationConfig().withAnnotationIntrospector(new JaxbAnnotationIntrospector()) mapper.readValue(marshalledData, this.getClass()) } def unmarshalFromXml(marshalledData: String): {{My Representation Subclass}} = { val context = JAXBContext.newInstance(this.getClass()) val representation = context.createUnmarshaller().unmarshal( new StringReader(marshalledData) ).asInstanceOf[{{Type of My Representation Subclass}}] representation // Return the representation } </code></pre> <p>Specifically, I can't figure out how to attach these unmarshalling methods in a typesafe and DRY way to each of my classes, and then to call them from Scala (and hopefully sometimes by using only abstract type information). In other words, I would like to do this:</p> <pre><code>val newOrder = Order.unmarshalFromJson(someJson) </code></pre> <p>And more ambitiously:</p> <pre><code>class Resource[R &lt;: Representation] { getRepresentation(marshalledData: String): R = {{R's Singleton}}.unmarshalFromXml(marshalledData) } </code></pre> <p>In terms of my particular stumbling blocks:</p> <ul> <li>I can't figure out whether I should define my <code>unmarshalFrom*()</code> constructors once in the <code>Representation</code> class, or in a singleton <code>Representation</code> object - if the latter, I don't see how I can automatically inherit that down through the class hierarchy of <code>Order</code>, <code>Invoice</code> etc.</li> <li>I can't get <code>this.type</code> (<a href="https://stackoverflow.com/questions/1586811/is-there-a-self-type-in-scala-that-represents-the-current-type">as per this answer</a>) to work as a way of self-typing <code>unmarshalFromJson()</code> - I get a compile error <code>type mismatch; found: ?0 where type ?0 required: Representation.this.type</code> on the <code>readValue()</code> call</li> <li>I can't figure out how to use the implicit <code>Default[A]</code> pattern (<a href="https://stackoverflow.com/questions/7616692/how-can-i-invoke-the-constructor-of-a-scala-abstract-type">as per this answer</a>) to work down my Representation class hierarchy to call the singleton unmarshalling constructors using type information only</li> </ul> <p>I know this is a bit of a mammoth question touching on various different (but related) issues - any help gratefully received!</p> <p>Alex</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload