@@ -30,7 +30,8 @@ of this software and associated documentation files (the "Software"), to deal
3030import java .lang .reflect .Field ;
3131import java .lang .reflect .Method ;
3232import java .lang .reflect .Modifier ;
33- import java .math .*;
33+ import java .math .BigDecimal ;
34+ import java .math .BigInteger ;
3435import java .util .Collection ;
3536import java .util .Enumeration ;
3637import java .util .HashMap ;
@@ -92,7 +93,7 @@ of this software and associated documentation files (the "Software"), to deal
9293 * </ul>
9394 *
9495 * @author JSON.org
95- * @version 2015-12-09
96+ * @version 2016-05-20
9697 */
9798public class JSONObject {
9899 /**
@@ -900,7 +901,9 @@ public <E extends Enum<E>> E optEnum(Class<E> clazz, String key, E defaultValue)
900901 return myE ;
901902 }
902903 return Enum .valueOf (clazz , val .toString ());
903- } catch (IllegalArgumentException | NullPointerException e ) {
904+ } catch (IllegalArgumentException e ) {
905+ return defaultValue ;
906+ } catch (NullPointerException e ) {
904907 return defaultValue ;
905908 }
906909 }
@@ -1335,6 +1338,46 @@ public JSONObject putOpt(String key, Object value) throws JSONException {
13351338 return this ;
13361339 }
13371340
1341+ /**
1342+ * Creates a JSONPointer using an intialization string and tries to
1343+ * match it to an item within this JSONObject. For example, given a
1344+ * JSONObject initialized with this document:
1345+ * <pre>
1346+ * {
1347+ * "a":{"b":"c"}
1348+ * }
1349+ * </pre>
1350+ * and this JSONPointer string:
1351+ * <pre>
1352+ * "/a/b"
1353+ * </pre>
1354+ * Then this method will return the String "c".
1355+ * A JSONPointerException may be thrown from code called by this method.
1356+ *
1357+ * @param jsonPointer string that can be used to create a JSONPointer
1358+ * @return the item matched by the JSONPointer, otherwise null
1359+ */
1360+ public Object query (String jsonPointer ) {
1361+ return new JSONPointer (jsonPointer ).queryFrom (this );
1362+ }
1363+
1364+ /**
1365+ * Queries and returns a value from this object using {@code jsonPointer}, or
1366+ * returns null if the query fails due to a missing key.
1367+ *
1368+ * @param jsonPointer the string representation of the JSON pointer
1369+ * @return the queried value or {@code null}
1370+ * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1371+ */
1372+ public Object optQuery (String jsonPointer ) {
1373+ JSONPointer pointer = new JSONPointer (jsonPointer );
1374+ try {
1375+ return pointer .queryFrom (this );
1376+ } catch (JSONPointerException e ) {
1377+ return null ;
1378+ }
1379+ }
1380+
13381381 /**
13391382 * Produce a string in double quotes with backslash sequences in all the
13401383 * right places. A backslash will be inserted within </, producing <\/,
@@ -1477,7 +1520,6 @@ public boolean similar(Object other) {
14771520 * @return A simple JSON value.
14781521 */
14791522 public static Object stringToValue (String string ) {
1480- Double d ;
14811523 if (string .equals ("" )) {
14821524 return string ;
14831525 }
@@ -1496,23 +1538,23 @@ public static Object stringToValue(String string) {
14961538 * produced, then the value will just be a string.
14971539 */
14981540
1499- char b = string .charAt (0 );
1500- if ((b >= '0' && b <= '9' ) || b == '-' ) {
1541+ char initial = string .charAt (0 );
1542+ if ((initial >= '0' && initial <= '9' ) || initial == '-' ) {
15011543 try {
15021544 if (string .indexOf ('.' ) > -1 || string .indexOf ('e' ) > -1
1503- || string .indexOf ('E' ) > -1 ) {
1504- d = Double .valueOf (string );
1545+ || string .indexOf ('E' ) > -1
1546+ || "-0" .equals (string )) {
1547+ Double d = Double .valueOf (string );
15051548 if (!d .isInfinite () && !d .isNaN ()) {
15061549 return d ;
15071550 }
15081551 } else {
15091552 Long myLong = new Long (string );
15101553 if (string .equals (myLong .toString ())) {
1511- if (myLong == myLong .intValue ()) {
1512- return myLong .intValue ();
1513- } else {
1514- return myLong ;
1554+ if (myLong .longValue () == myLong .intValue ()) {
1555+ return Integer .valueOf (myLong .intValue ());
15151556 }
1557+ return myLong ;
15161558 }
15171559 }
15181560 } catch (Exception ignore ) {
@@ -1836,4 +1878,31 @@ public Writer write(Writer writer, int indentFactor, int indent)
18361878 throw new JSONException (exception );
18371879 }
18381880 }
1881+
1882+ /**
1883+ * Returns a java.util.Map containing all of the entrys in this object.
1884+ * If an entry in the object is a JSONArray or JSONObject it will also
1885+ * be converted.
1886+ * <p>
1887+ * Warning: This method assumes that the data structure is acyclical.
1888+ *
1889+ * @return a java.util.Map containing the entrys of this object
1890+ */
1891+ public Map <String , Object > toMap () {
1892+ Map <String , Object > results = new HashMap <String , Object >();
1893+ for (Entry <String , Object > entry : this .map .entrySet ()) {
1894+ Object value ;
1895+ if (entry .getValue () == null || NULL .equals (entry .getValue ())) {
1896+ value = null ;
1897+ } else if (entry .getValue () instanceof JSONObject ) {
1898+ value = ((JSONObject ) entry .getValue ()).toMap ();
1899+ } else if (entry .getValue () instanceof JSONArray ) {
1900+ value = ((JSONArray ) entry .getValue ()).toList ();
1901+ } else {
1902+ value = entry .getValue ();
1903+ }
1904+ results .put (entry .getKey (), value );
1905+ }
1906+ return results ;
1907+ }
18391908}
0 commit comments