summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDerek Chen-Beker <dchenbecker@gmail.com>2010-06-04 23:05:57 +0000
committerDerek Chen-Beker <dchenbecker@gmail.com>2010-06-04 23:05:57 +0000
commitd3a747882c0332dd1316c31c500f983268bd8c8b (patch)
tree48def287f402c75cd5d2d5e9fc7632ff0257b483 /src
parent84b86a977ea090c66e128b26e1b7643fd50a99a1 (diff)
downloadscala-d3a747882c0332dd1316c31c500f983268bd8c8b.tar.gz
scala-d3a747882c0332dd1316c31c500f983268bd8c8b.tar.bz2
scala-d3a747882c0332dd1316c31c500f983268bd8c8b.zip
Fix for #3284.
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')
-rw-r--r--src/library/scala/util/parsing/json/JSON.scala52
-rw-r--r--src/library/scala/util/parsing/json/Parser.scala29
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} )