diff options
author | Derek Chen-Beker <dchenbecker@gmail.com> | 2010-04-13 20:51:44 +0000 |
---|---|---|
committer | Derek Chen-Beker <dchenbecker@gmail.com> | 2010-04-13 20:51:44 +0000 |
commit | 248ae6753e94429d5a5c14f9039ecf588b19b5bc (patch) | |
tree | cb317c79bd3602529fc6e694d5330a81bfa9ce0a /src/library | |
parent | 6d0d855d4917592e169f654ecaff0f44e685dd02 (diff) | |
download | scala-248ae6753e94429d5a5c14f9039ecf588b19b5bc.tar.gz scala-248ae6753e94429d5a5c14f9039ecf588b19b5bc.tar.bz2 scala-248ae6753e94429d5a5c14f9039ecf588b19b5bc.zip |
Fix for #3284.
but in the interest of not breaking backwards compatibility, the
JSON.parse method has been marked deprecated for now.
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/util/parsing/json/JSON.scala | 52 | ||||
-rw-r--r-- | src/library/scala/util/parsing/json/Parser.scala | 29 |
2 files changed, 60 insertions, 21 deletions
diff --git a/src/library/scala/util/parsing/json/JSON.scala b/src/library/scala/util/parsing/json/JSON.scala index 1900044698..dfcc98d5df 100644 --- a/src/library/scala/util/parsing/json/JSON.scala +++ b/src/library/scala/util/parsing/json/JSON.scala @@ -42,8 +42,33 @@ object JSON extends Parser { * * @param input the given JSON string. * @return an optional list of of elements. + * + * @deprecated Use parseFull or parseRaw as needed. + */ + def parse(input: String): Option[List[Any]] = parseRaw(input).map(unRaw).flatMap({ + case l : List[_] => Some(l) + case _ => None + }) + + /** + * This method converts "raw" results back into the original, deprecated + * form. */ - def parse(input: String): Option[List[Any]] = + private def unRaw (in : Any) : Any = in match { + case JSONObject(obj) => obj.map({ case (k,v) => (k,unRaw(v))}).toList + case JSONArray(list) => list.map(unRaw) + case x => x + } + + /** + * Parse the given JSON string and return a list of elements. If the + * string is a JSON object it will be a JSONObject. If it's a JSON + * array it will be be a JSONArray. + * + * @param input the given JSON string. + * @return an optional JSONType element. + */ + def parseRaw(input : String) : Option[JSONType] = phrase(root)(new lexical.Scanner(input)) match { case Success(result, _) => Some(result) case _ => None @@ -58,7 +83,7 @@ object JSON extends Parser { * @return an optional list or map. */ def parseFull(input: String): Option[Any] = - parse(input) match { + parseRaw(input) match { case Some(data) => Some(resolveType(data)) case None => None } @@ -67,23 +92,12 @@ object JSON extends Parser { * A utility method to resolve a parsed JSON list into objects or * arrays. See the parse method for details. */ - def resolveType(input: List[_]): Any = { - var objMap = Map[String, Any]() - - if (input.forall { - case (key: String, value: List[_]) => - objMap = objMap.+[Any](key -> resolveType(value)) - true - case (key : String, value) => - objMap += key -> value - true - case _ => false - }) objMap - else - input.map { - case l : List[_] => resolveType(l) - case x => x - } + def resolveType(input: Any): Any = input match { + case JSONObject(data) => data.transform { + case (k,v) => resolveType(v) + } + case JSONArray(data) => data.map(resolveType) + case x => x } /** diff --git a/src/library/scala/util/parsing/json/Parser.scala b/src/library/scala/util/parsing/json/Parser.scala index 46a556c0ee..2a9d734760 100644 --- a/src/library/scala/util/parsing/json/Parser.scala +++ b/src/library/scala/util/parsing/json/Parser.scala @@ -16,6 +16,31 @@ import scala.util.parsing.combinator.syntactical._ import scala.util.parsing.combinator.lexical._ /** + * A marker class for the JSON result types. + * + * @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org"> + */ +sealed abstract class JSONType + +/** + * Represents a JSON Object (map). + * @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org"> + */ +case class JSONObject (obj : Map[Any,Any]) extends JSONType { + override def toString = "JSONObject(" + obj.map({ case (k,v) => k + " -> " + v }).mkString(", ") + ")" +} + +/** + * Represents a JSON Array (list). + * @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org"> + */ +case class JSONArray (list : List[Any]) extends JSONType { + override def toString = "JSONArray(" + list.mkString(", ") + ")" +} + +/** + * The main JSON Parser. + * * @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org"> */ class Parser extends StdTokenParsers with ImplicitConversions { @@ -40,8 +65,8 @@ class Parser extends StdTokenParsers with ImplicitConversions { // Define the grammar def root = jsonObj | jsonArray - def jsonObj = "{" ~> repsep(objEntry, ",") <~ "}" - def jsonArray = "[" ~> repsep(value, ",") <~ "]" + def jsonObj = "{" ~> repsep(objEntry, ",") <~ "}" ^^ { case vals : List[_] => JSONObject(Map(vals : _*)) } + def jsonArray = "[" ~> repsep(value, ",") <~ "]" ^^ { case vals : List[_] => JSONArray(vals) } def objEntry = stringVal ~ (":" ~> value) ^^ { case x ~ y => (x, y) } def value: Parser[Any] = (jsonObj | jsonArray | number | "true" ^^^ true | "false" ^^^ false | "null" ^^^ null | stringVal) def stringVal = accept("string", { case lexical.StringLit(n) => n} ) |