2017-04-05 69 views
0

問題的簡短故事在標題中。有一些Java類,例如org.joda.time.Interval,我想(不重寫它)使其成爲案例類,即具有applyunapply方法。是否有可能爲現有的Java bean類獲取Scala案例類?

長的故事:我有一個Scala的播放應用程序,有我定義的形式,需要兩個區間,即

import org.joda.time.Interval 

case class MyParams(param1: String, interval1: Interval, interval2: Interval) 

,然後我試圖定義嵌套映射,但Interval是一個Java類,並沒有按」沒有apply/unapply,我寧願不創建我自己的副本。

val myForm = Form { 
     mapping(
     "param1" -> nonEmptyText, 
     "interval1" -> mapping(
      "start" -> jodaDate, 
      "end" -> jodaDate, 
     )(Interval.apply)(Interval.unapply), // <<<<<<<<<< Cannot resolve symbol ... 
     "interval2" -> mapping(
      "start" -> jodaDate, 
      "end" -> jodaDate, 
     )(Interval.apply)(Interval.unapply) // <<<<<<<<<< Cannot resolve symbol ... 
    )(MyParams.apply)(MyParams.unapply) 
} 

當然,我可以扁平化結構,但這樣做不會很好地擴展設計方面再加上有,將需要組成現有JSON複合材料結構,我想重用綁定到窗體這兩個JSON請求和表單提交。作爲補充

object IntervalUtils { 
    implicit object Interval { 
    def apply(start: DateTime, end: DateTime) = new org.joda.time.Interval(start, end) 
    def unapply(interval: org.joda.time.Interval) = Some((interval.getStart, interval.getEnd)) 
    } 
} 

所以OP的代碼編譯爲只缺少import IntervalUtils._然後:

UPDATE建設上公認的答案的頂部,並採取語法糖顧及我在最後做獎金也可以這樣做:

implicit val jodaIntervalWrites = new Writes[org.joda.time.Interval] { 
    def writes(interval: org.joda.time.Interval) = Json.obj(
    "start" -> interval.getStart, 
    "end" -> interval.getEnd 
) 
} 

implicit val jodaIntervalReads: Reads[org.joda.time.Interval] = (
    (JsPath \ "start").read[DateTime] and 
    (JsPath \ "end").read[DateTime] 
)(Interval.apply _) // <<<<<<<<<<<<<<<<<< reused here 

回答

2

要做到這一點,你並不需要的情況下類,你只需要兩個方法用合適的簽名,您可以輕鬆地將它們定義:

object JodaTime { 
    def mkInterval(start: ReadableInstant, end: ReadableInstant) = new Interval(start, end) 
    def unmkInterval(interval: Interval) = Some((interval.getStart, interval.getEnd)) 
} 

// elsewhere 
mapping(
    "start" -> jodaDate, 
    "end" -> jodaDate, 
)(JodaTime.mkInterval)(JodaTime.unmkInterval) 

事實上,你甚至不需要mkInterval,你可以只寫new Interval(_, _)(不知道是否超載可能會導致這個特定用例的一個問題,但如果是這樣只需指定佔位符類型)。