summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorDerek Chen-Beker <dchenbecker@gmail.com>2010-04-13 20:51:44 +0000
committerDerek Chen-Beker <dchenbecker@gmail.com>2010-04-13 20:51:44 +0000
commit248ae6753e94429d5a5c14f9039ecf588b19b5bc (patch)
treecb317c79bd3602529fc6e694d5330a81bfa9ce0a /src/library
parent6d0d855d4917592e169f654ecaff0f44e685dd02 (diff)
downloadscala-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.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 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} )