diff options
Diffstat (limited to 'src')
13 files changed, 148 insertions, 70 deletions
diff --git a/src/main/scala/cc/spray/json/CompactPrinter.scala b/src/main/scala/cc/spray/json/CompactPrinter.scala index b64597a..2a85584 100644 --- a/src/main/scala/cc/spray/json/CompactPrinter.scala +++ b/src/main/scala/cc/spray/json/CompactPrinter.scala @@ -18,6 +18,9 @@ package cc.spray.json import java.lang.StringBuilder +/** + * A JsonPrinter that produces compact JSON source without any superfluous whitespace. + */ object CompactPrinter extends JsonPrinter { def print(x: JsValue, sb: StringBuilder) { diff --git a/src/main/scala/cc/spray/json/JsValue.scala b/src/main/scala/cc/spray/json/JsValue.scala index 8781f73..f98103c 100644 --- a/src/main/scala/cc/spray/json/JsValue.scala +++ b/src/main/scala/cc/spray/json/JsValue.scala @@ -1,21 +1,19 @@ /* - * Original implementation (C) by the databinder-dispatch team - * https://github.com/n8han/Databinder-Dispatch - * Adapted and extended in 2011 by Mathias Doenitz + * Copyright (C) 2009-2011 Mathias Doenitz + * Inspired by a similar implementation by Nathan Hamblen + * (https://github.com/n8han/Databinder-Dispatch) * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package cc.spray.json @@ -23,29 +21,36 @@ package cc.spray.json import formats._ import collection.mutable.ListBuffer +/** + * The general type of a JSON AST node. + */ sealed trait JsValue { override def toString = CompactPrinter(this) def toString(printer: (JsValue => String)) = printer(this) def fromJson[T :JsonReader]: T = jsonReader.read(this) } - object JsValue { - def apply(x: Any): JsValue = x match { + + /** + * General converter to a JsValue. + * Throws an IllegalArgumentException of the given value cannot be converted. + */ + def apply(value: Any): JsValue = value match { case null => JsNull case true => JsTrue case false => JsFalse case x: JsValue => x case x: String => JsString(x) - case x: Symbol => JsString(x.name) case x: Int => JsNumber(x) case x: Long => JsNumber(x) - case x: Short => JsNumber(x) - case x: Byte => JsNumber(x) - case x: Float => JsNumber(x) case x: Double => JsNumber(x) + case x: Char => JsString(String.valueOf(x)) + case x: Float => JsNumber(x) + case x: Byte => JsNumber(x) + case x: Short => JsNumber(x) case x: BigInt => JsNumber(x) case x: BigDecimal => JsNumber(x) - case x: Char => JsString(String.valueOf(x)) + case x: Symbol => JsString(x.name) case x: collection.Map[_, _] => JsObject(fromSeq(x)) case x@ collection.Seq((_, _), _*) => JsObject(fromSeq(x.asInstanceOf[Seq[(_, _)]])) case x: collection.Seq[_] => JsArray(x.toList.map(JsValue.apply)) @@ -62,24 +67,11 @@ object JsValue { } list.toList } - - def fromString(json: String) = JsonParser(json) - def toString(value: JsValue, printer: (JsValue => String) = CompactPrinter) = printer(value) -} - -case class JsString(value: String) extends JsValue - - -case class JsNumber(value: BigDecimal) extends JsValue - -object JsNumber { - def apply(n: Int) = new JsNumber(BigDecimal(n)) - def apply(n: Long) = new JsNumber(BigDecimal(n)) - def apply(n: Double) = new JsNumber(BigDecimal(n)) - def apply(n: BigInt) = new JsNumber(BigDecimal(n)) - def apply(n: String) = new JsNumber(BigDecimal(n)) } +/** + * A JSON object. + */ case class JsObject(fields: List[JsField]) extends JsValue { lazy val asMap: Map[String, JsValue] = { val b = Map.newBuilder[String, JsValue] @@ -87,42 +79,61 @@ case class JsObject(fields: List[JsField]) extends JsValue { b.result() } } - object JsObject { def apply(members: JsField*) = new JsObject(members.toList) } - +/** + * The members/fields of a JSON object. + */ case class JsField(name: String, value: JsValue) extends JsValue - object JsField { def apply(name: String, value: Any) = new JsField(name, JsValue(value)) } - +/** + * A JSON array. + */ case class JsArray(elements: List[JsValue]) extends JsValue - object JsArray { def apply(elements: JsValue*) = new JsArray(elements.toList) } +/** + * A JSON string. + */ +case class JsString(value: String) extends JsValue + +/** + * A JSON number. + */ +case class JsNumber(value: BigDecimal) extends JsValue +object JsNumber { + def apply(n: Int) = new JsNumber(BigDecimal(n)) + def apply(n: Long) = new JsNumber(BigDecimal(n)) + def apply(n: Double) = new JsNumber(BigDecimal(n)) + def apply(n: BigInt) = new JsNumber(BigDecimal(n)) + def apply(n: String) = new JsNumber(BigDecimal(n)) +} +/** + * JSON Booleans. + */ sealed trait JsBoolean extends JsValue { def value: Boolean } - object JsBoolean { def apply(x: Boolean): JsBoolean = if (x) JsTrue else JsFalse def unapply(x: JsBoolean): Option[Boolean] = Some(x.value) } - case object JsTrue extends JsBoolean { def value = true } - case object JsFalse extends JsBoolean { def value = false } - -case object JsNull extends JsValue +/** + * The representation for JSON null. + */ +case object JsNull extends JsValue
\ No newline at end of file diff --git a/src/main/scala/cc/spray/json/JsonParser.scala b/src/main/scala/cc/spray/json/JsonParser.scala index 275f310..4a2d64b 100644 --- a/src/main/scala/cc/spray/json/JsonParser.scala +++ b/src/main/scala/cc/spray/json/JsonParser.scala @@ -18,8 +18,8 @@ package cc.spray.json import org.parboiled.scala._ import org.parboiled.errors.{ErrorUtils, ParsingException} -import java.lang.StringBuilder import org.parboiled.Context +import java.lang.StringBuilder /** * This JSON parser is the almost direct implementation of the JSON grammar @@ -85,7 +85,7 @@ object JsonParser extends Parser { def WhiteSpace: Rule0 = rule { zeroOrMore(anyOf(" \n\r\t\f")) } // helper method for fast string building - // for maximum performance we use a somewhat unorthodox parsing technqiue that is a bit more verbose (and probably + // for maximum performance we use a somewhat unorthodox parsing technique that is a bit more verbose (and somewhat // less readable) but reduces object allocations during the parsing run to a minimum: // the Characters rules pushes a StringBuilder object onto the stack which is then directly fed with matched // and unescaped characters in the sub rules (i.e. no string allocations and value stack operation required) diff --git a/src/main/scala/cc/spray/json/JsonPrinter.scala b/src/main/scala/cc/spray/json/JsonPrinter.scala index 7751b7e..6f1b20a 100644 --- a/src/main/scala/cc/spray/json/JsonPrinter.scala +++ b/src/main/scala/cc/spray/json/JsonPrinter.scala @@ -19,6 +19,9 @@ package cc.spray.json import annotation.tailrec import java.lang.StringBuilder +/** + * A JsonPrinter serializes a JSON AST to a String. + */ trait JsonPrinter extends (JsValue => String) { def apply(x: JsValue) = { diff --git a/src/main/scala/cc/spray/json/PimpedAny.scala b/src/main/scala/cc/spray/json/PimpedAny.scala index 86a18ce..4c10771 100644 --- a/src/main/scala/cc/spray/json/PimpedAny.scala +++ b/src/main/scala/cc/spray/json/PimpedAny.scala @@ -1,5 +1,3 @@ -package cc.spray.json - /* * Copyright (C) 2009-2011 Mathias Doenitz * @@ -16,6 +14,8 @@ package cc.spray.json * limitations under the License. */ +package cc.spray.json + import formats.JsonWriter private[json] class PimpedAny[T](any: T, writer: JsonWriter[T]) { diff --git a/src/main/scala/cc/spray/json/PrettyPrinter.scala b/src/main/scala/cc/spray/json/PrettyPrinter.scala index f0fcf14..f8e3e93 100644 --- a/src/main/scala/cc/spray/json/PrettyPrinter.scala +++ b/src/main/scala/cc/spray/json/PrettyPrinter.scala @@ -19,6 +19,9 @@ package cc.spray.json import java.lang.StringBuilder import annotation.tailrec +/** + * A JsonPrinter that produces a nicely readable JSON source. + */ object PrettyPrinter extends JsonPrinter { val Indent = 2 diff --git a/src/main/scala/cc/spray/json/formats/BasicFormats.scala b/src/main/scala/cc/spray/json/formats/BasicFormats.scala index 378d67d..4be7ef6 100644 --- a/src/main/scala/cc/spray/json/formats/BasicFormats.scala +++ b/src/main/scala/cc/spray/json/formats/BasicFormats.scala @@ -1,6 +1,3 @@ -package cc.spray.json -package formats - /* * Original implementation (C) 2009-2011 Debasish Ghosh * Adapted and extended in 2011 by Mathias Doenitz @@ -18,6 +15,12 @@ package formats * limitations under the License. */ +package cc.spray.json +package formats + +/** + * Provides the JsonFormats for the most important Scala types. + */ trait BasicFormats { implicit object IntJsonFormat extends JsonFormat[Int] { diff --git a/src/main/scala/cc/spray/json/formats/CollectionFormats.scala b/src/main/scala/cc/spray/json/formats/CollectionFormats.scala index 53be0d5..02a9999 100644 --- a/src/main/scala/cc/spray/json/formats/CollectionFormats.scala +++ b/src/main/scala/cc/spray/json/formats/CollectionFormats.scala @@ -1,6 +1,3 @@ -package cc.spray.json -package formats - /* * Original implementation (C) 2009-2011 Debasish Ghosh * Adapted and extended in 2011 by Mathias Doenitz @@ -18,10 +15,16 @@ package formats * limitations under the License. */ +package cc.spray.json +package formats + import reflect.Manifest trait CollectionFormats { - + + /** + * Supplies the JsonFormat for Lists. + */ implicit def listFormat[T :JsonFormat] = new JsonFormat[List[T]] { def write(list: List[T]) = JsArray(list.map(_.toJson)) def read(value: JsValue) = value match { @@ -30,6 +33,9 @@ trait CollectionFormats { } } + /** + * Supplies the JsonFormat for Arrays. + */ implicit def arrayFormat[T :JsonFormat :Manifest] = new JsonFormat[Array[T]] { def write(array: Array[T]) = JsArray(array.map(_.toJson).toList) def read(value: JsValue) = value match { @@ -38,6 +44,10 @@ trait CollectionFormats { } } + /** + * Supplies the JsonFormat for Maps. The implicitly available JsonFormat for the key type K must + * always write JsStrings, otherwise a [[cc.spray.json.SerializationException]] will be thrown. + */ implicit def mapFormat[K :JsonFormat, V :JsonFormat] = new JsonFormat[Map[K, V]] { def write(m: Map[K, V]) = JsObject { m.toList.map { t => @@ -53,11 +63,22 @@ trait CollectionFormats { } } + /** + * Supplies the JsonFormat for immutable Sets. + */ implicit def immutableSetFormat[T :JsonFormat] = viaList[Set[T], T](list => Set(list :_*)) import collection.mutable.Set + + /** + * Supplies the JsonFormat for mutable Sets. + */ implicit def mutableSetFormat[T :JsonFormat] = viaList[Set[T], T](list => Set.empty ++ list) + /** + * A JsonFormat construction helper that creates a JsonFormat for an Iterable type I from a builder function + * List => I. + */ def viaList[I <: Iterable[T], T :JsonFormat](f: List[T] => I): JsonFormat[I] = new JsonFormat[I] { def write(iterable: I) = JsArray(iterable.map(_.toJson).toList) def read(value: JsValue) = value match { diff --git a/src/main/scala/cc/spray/json/formats/DefaultJsonFormats.scala b/src/main/scala/cc/spray/json/formats/DefaultJsonFormats.scala index 868ebb7..15f2abb 100644 --- a/src/main/scala/cc/spray/json/formats/DefaultJsonFormats.scala +++ b/src/main/scala/cc/spray/json/formats/DefaultJsonFormats.scala @@ -1,6 +1,3 @@ -package cc.spray.json -package formats - /* * Original implementation (C) 2009-2011 Debasish Ghosh * Adapted and extended in 2011 by Mathias Doenitz @@ -18,6 +15,12 @@ package formats * limitations under the License. */ +package cc.spray.json +package formats + +/** + * Provides all the predefined JsonFormats. + */ trait DefaultJsonFormats extends BasicFormats with StandardFormats with CollectionFormats with GenericFormats object DefaultJsonFormats extends DefaultJsonFormats diff --git a/src/main/scala/cc/spray/json/formats/GenericFormats.scala b/src/main/scala/cc/spray/json/formats/GenericFormats.scala index 52aa837..dbfb264 100644 --- a/src/main/scala/cc/spray/json/formats/GenericFormats.scala +++ b/src/main/scala/cc/spray/json/formats/GenericFormats.scala @@ -1,6 +1,3 @@ -package cc.spray.json -package formats - /* * Original implementation (C) 2009-2011 Debasish Ghosh * Adapted and extended in 2011 by Mathias Doenitz @@ -18,6 +15,12 @@ package formats * limitations under the License. */ +package cc.spray.json +package formats + +/** + * Provides the helpers for constructing custom JsonFormat implementations. + */ trait GenericFormats { private type JF[T] = JsonFormat[T] // simple alias for reduced verbosity diff --git a/src/main/scala/cc/spray/json/formats/JsonFormat.scala b/src/main/scala/cc/spray/json/formats/JsonFormat.scala index 1edac19..0951ef8 100644 --- a/src/main/scala/cc/spray/json/formats/JsonFormat.scala +++ b/src/main/scala/cc/spray/json/formats/JsonFormat.scala @@ -1,6 +1,3 @@ -package cc.spray.json -package formats - /* * Original implementation (C) 2009-2011 Debasish Ghosh * Adapted and extended in 2011 by Mathias Doenitz @@ -18,12 +15,24 @@ package formats * limitations under the License. */ +package cc.spray.json +package formats + +/** + * Provides the JSON deserialization for type T. + */ trait JsonReader[T] { def read(json: JsValue): T } +/** + * Provides the JSON serialization for type T. + */ trait JsonWriter[T] { def write(obj: T): JsValue } +/** + * Provides the JSON deserialization and serialization for type T. + */ trait JsonFormat[T] extends JsonReader[T] with JsonWriter[T] diff --git a/src/main/scala/cc/spray/json/formats/StandardFormats.scala b/src/main/scala/cc/spray/json/formats/StandardFormats.scala index 91e21d3..78bbe53 100644 --- a/src/main/scala/cc/spray/json/formats/StandardFormats.scala +++ b/src/main/scala/cc/spray/json/formats/StandardFormats.scala @@ -1,6 +1,3 @@ -package cc.spray.json -package formats - /* * Original implementation (C) 2009-2011 Debasish Ghosh * Adapted and extended in 2011 by Mathias Doenitz @@ -18,6 +15,12 @@ package formats * limitations under the License. */ +package cc.spray.json +package formats + +/** + * Provides the JsonFormats for the non-collection standard types. + */ trait StandardFormats { private type JF[T] = JsonFormat[T] // simple alias for reduced verbosity diff --git a/src/main/scala/cc/spray/json/package.scala b/src/main/scala/cc/spray/json/package.scala index 1932315..362fb7b 100644 --- a/src/main/scala/cc/spray/json/package.scala +++ b/src/main/scala/cc/spray/json/package.scala @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2009-2011 Mathias Doenitz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package cc.spray import json.formats.{JsonReader, JsonWriter} |