diff options
author | Antonio Cunei <antonio.cunei@epfl.ch> | 2010-06-04 23:46:31 +0000 |
---|---|---|
committer | Antonio Cunei <antonio.cunei@epfl.ch> | 2010-06-04 23:46:31 +0000 |
commit | f1c6333e75cbd4eb594e4fad2b023c8259eb260f (patch) | |
tree | 1b77d6800c82fb1ba8535b6de5aac1fa36e519f0 /src/library | |
parent | 38d7917431282455c493802599c79ca4647fcab4 (diff) | |
download | scala-f1c6333e75cbd4eb594e4fad2b023c8259eb260f.tar.gz scala-f1c6333e75cbd4eb594e4fad2b023c8259eb260f.tar.bz2 scala-f1c6333e75cbd4eb594e4fad2b023c8259eb260f.zip |
Merged revisions 22170 via svnmerge from
https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk
........
r22170 | dchenbecker | 2010-06-05 01:05:57 +0200 (Sat, 05 Jun 2010) | 7 lines
Fix for #3284. This code should probably be refactored, but in the
interest of not breaking backwards compatibility, the JSON.parse
method has been marked deprecated for now.
Unit tests have been fixed so that this won't break the build this
time. ........
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 1be8a10931..6d3761af52 100644 --- a/src/library/scala/util/parsing/json/JSON.scala +++ b/src/library/scala/util/parsing/json/JSON.scala @@ -41,8 +41,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 @@ -57,7 +82,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 } @@ -66,23 +91,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 0d573edce4..e8e7897ca4 100644 --- a/src/library/scala/util/parsing/json/Parser.scala +++ b/src/library/scala/util/parsing/json/Parser.scala @@ -15,6 +15,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 { @@ -39,8 +64,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} ) |