Skip to content

Commit

Permalink
customized deploy, added pull request codahale#42
Browse files Browse the repository at this point in the history
  • Loading branch information
artgon committed Jul 7, 2012
1 parent e648056 commit 178e78d
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 11 deletions.
7 changes: 4 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<groupId>com.codahale</groupId>
<artifactId>jerkson_2.9.1</artifactId>
<version>0.6.0-SNAPSHOT</version>
<version>0.6.0-Matygo</version>
<name>Jerkson for Scala</name>

<properties>
Expand Down Expand Up @@ -47,8 +47,9 @@

<distributionManagement>
<repository>
<id>repo.codahale.com</id>
<url>scp://codahale.com/home/codahale/repo.codahale.com</url>
<id>matygo</id>
<name>Matygo Releases</name>
<url>http://office.matygo.com:8081/nexus/content/repositories/matygo/</url>
</repository>
</distributionManagement>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class CaseClassDeserializer(config: DeserializationConfig,
classLoader: ClassLoader) extends JsonDeserializer[Object] {
private val isSnakeCase = javaType.getRawClass.isAnnotationPresent(classOf[JsonSnakeCase])
private val params = CaseClassSigParser.parse(javaType.getRawClass, config.getTypeFactory, classLoader).map {
case (name, jt) => (if (isSnakeCase) snakeCase(name) else name, jt)
case (name, jt, defaultValue) => (if (isSnakeCase) snakeCase(name) else name, jt, defaultValue)
}.toArray
private val paramTypes = params.map { _._2.getRawClass }.toList
private val constructor = javaType.getRawClass.getConstructors.find { c =>
Expand Down Expand Up @@ -48,7 +48,7 @@ class CaseClassDeserializer(config: DeserializationConfig,
val node = jp.readValueAsTree[JsonNode]

val values = new ArrayBuffer[AnyRef]
for ((paramName, paramType) <- params) {
for ((paramName, paramType, paramDefault) <- params) {
val field = node.get(paramName)
val tp = new TreeTraversingParser(if (field == null) NullNode.getInstance else field, jp.getCodec)
val value = if (paramType.getRawClass == classOf[Option[_]]) {
Expand All @@ -60,6 +60,12 @@ class CaseClassDeserializer(config: DeserializationConfig,

if (field != null || value != null) {
values += value
} else {
// see if a default value was supplied
paramDefault match {
case Some(v) => values += v
case None =>
}
}


Expand Down
32 changes: 29 additions & 3 deletions src/main/scala/com/codahale/jerkson/util/CaseClassSigParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ object CaseClassSigParser {
protected def simpleName(klass: Class[_]) =
klass.getName.split("\\$").last

implicit def class2companion(clazz: Class[_]) = new {
def companionClass(classLoader: ClassLoader): Class[_] = {
val path = if (clazz.getName.endsWith("$")) clazz.getName else "%s$".format(clazz.getName)
Some(Class.forName(path, true, classLoader)).getOrElse {
throw new Error("Could not resolve clazz='%s'".
format(path))
}
}

def companionObject(classLoader: ClassLoader) = companionClass(classLoader).getField("MODULE$").get(null)
}

protected def findSym[A](clazz: Class[A], classLoader: ClassLoader) = {
val name = simpleName(clazz)
val pss = parseScalaSig(clazz, classLoader)
Expand Down Expand Up @@ -81,12 +93,26 @@ object CaseClassSigParser {

def parse[A](clazz: Class[A], factory: TypeFactory, classLoader: ClassLoader) = {
findSym(clazz, classLoader).children.filter(c => c.isCaseAccessor && !c.isPrivate)
.flatMap { ms =>
.zipWithIndex.map { case (ms,idx) => {
ms.asInstanceOf[MethodSymbol].infoType match {
case NullaryMethodType(t: TypeRefType) => ms.name -> typeRef2JavaType(t, factory, classLoader) :: Nil
case NullaryMethodType(t: TypeRefType) => {

// try and find the field's default
val companionClass = clazz.companionClass(classLoader)
val companionObject = clazz.companionObject(classLoader)
val defaultMethod = try {
Some(companionClass.getMethod("apply$default$%d".format(idx + 1)))
}
catch {
case _ => None // indicates no default value was supplied
}
val defaultValue = defaultMethod.map(m => Some(m.invoke(companionObject))).getOrElse(None)

Tuple3(ms.name, typeRef2JavaType(t, factory, classLoader), defaultValue) :: Nil
}
case _ => Nil
}
}
}}.flatten
}

protected def typeRef2JavaType(ref: TypeRefType, factory: TypeFactory, classLoader: ClassLoader): JavaType = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.codahale.jerkson.tests
import com.codahale.jerkson.Json._
import com.codahale.simplespec.Spec
import com.codahale.jerkson.ParsingException
import com.fasterxml.jackson.databind.node.IntNode
import org.junit.Test
import com.fasterxml.jackson.databind.node.IntNode

class CaseClassSupportSpec extends Spec {
class `A basic case class` {
Expand All @@ -27,6 +27,13 @@ class CaseClassSupportSpec extends Spec {
}
}

class `A case class with a default field` {
@Test def `is parsable from an incomplete JSON object` = {
parse[CaseClassWithDefaultString]("""{"id":1}""").must(be(CaseClassWithDefaultString(1, "Coda")))
parse[CaseClassWithDefaultInt]("""{"id":1}""").must(be(CaseClassWithDefaultInt(1, 42)))
}
}

class `A case class with lazy fields` {
@Test def `generates a JSON object with those fields evaluated` = {
generate(CaseClassWithLazyVal(1)).must(be("""{"id":1,"woo":"yeah"}"""))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.codahale.jerkson.tests

import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.annotation.{JsonIgnoreProperties, JsonIgnore}
import com.codahale.jerkson.JsonSnakeCase
import com.fasterxml.jackson.annotation.{JsonIgnoreProperties, JsonIgnore}
import com.fasterxml.jackson.databind.JsonNode

case class CaseClass(id: Long, name: String)

case class CaseClassWithDefaultString(id: Long, name: String = "Coda")
case class CaseClassWithDefaultInt(id: Long, answer: Int = 42)

case class CaseClassWithLazyVal(id: Long) {
lazy val woo = "yeah"
}
Expand Down

2 comments on commit 178e78d

@opyate
Copy link

@opyate opyate commented on 178e78d Jul 24, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see this comment: codahale#42 (comment)
The above commit may have a bug.

@artgon
Copy link
Owner Author

@artgon artgon commented on 178e78d Aug 7, 2012 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.