11package org .json ;
22
3+ import java .beans .PropertyChangeListener ;
4+ import java .beans .PropertyChangeSupport ;
35import java .io .Closeable ;
46
57/*
@@ -42,9 +44,10 @@ of this software and associated documentation files (the "Software"), to deal
4244import java .util .Iterator ;
4345import java .util .Locale ;
4446import java .util .Map ;
45- import java .util .Map .Entry ;
4647import java .util .ResourceBundle ;
4748import java .util .Set ;
49+ import java .util .function .BiFunction ;
50+ import java .util .function .Supplier ;
4851import java .util .regex .Pattern ;
4952
5053/**
@@ -100,7 +103,7 @@ of this software and associated documentation files (the "Software"), to deal
100103 * @author JSON.org
101104 * @version 2016-08-15
102105 */
103- public class JSONObject {
106+ public class JSONObject extends HashMap < String , Object > {
104107 /**
105108 * JSONObject.NULL is equivalent to the value that JavaScript calls null,
106109 * whilst Java's null is equivalent to the value that JavaScript calls
@@ -159,11 +162,6 @@ public String toString() {
159162 */
160163 static final Pattern NUMBER_PATTERN = Pattern .compile ("-?(?:0|[1-9]\\ d*)(?:\\ .\\ d+)?(?:[eE][+-]?\\ d+)?" );
161164
162- /**
163- * The map where the JSONObject's properties are kept.
164- */
165- private final Map <String , Object > map ;
166-
167165 /**
168166 * It is sometimes more convenient and less ambiguous to have a
169167 * <code>NULL</code> object than to use Java's <code>null</code> value.
@@ -182,7 +180,7 @@ public JSONObject() {
182180 // implementations to rearrange their items for a faster element
183181 // retrieval based on associative access.
184182 // Therefore, an implementation mustn't rely on the order of the item.
185- this . map = new HashMap < String , Object > ();
183+ super ();
186184 }
187185
188186 /**
@@ -286,18 +284,14 @@ public JSONObject(JSONTokener x) throws JSONException {
286284 * If a key in the map is <code>null</code>
287285 */
288286 public JSONObject (Map <?, ?> m ) {
289- if (m == null ) {
290- this .map = new HashMap <String , Object >();
291- } else {
292- this .map = new HashMap <String , Object >(m .size ());
293- for (final Entry <?, ?> e : m .entrySet ()) {
294- if (e .getKey () == null ) {
295- throw new NullPointerException ("Null key." );
296- }
297- final Object value = e .getValue ();
298- if (value != null ) {
299- this .map .put (String .valueOf (e .getKey ()), wrap (value ));
300- }
287+ super (m .size ());
288+ for (final Entry <?, ?> e : m .entrySet ()) {
289+ if (e .getKey () == null ) {
290+ throw new NullPointerException ("Null key." );
291+ }
292+ final Object value = e .getValue ();
293+ if (value != null ) {
294+ super .put (String .valueOf (e .getKey ()), wrap (value ));
301295 }
302296 }
303297 }
@@ -453,17 +447,6 @@ public JSONObject(String baseName, Locale locale) throws JSONException {
453447 }
454448 }
455449
456- /**
457- * Constructor to specify an initial capacity of the internal map. Useful for library
458- * internal calls where we know, or at least can best guess, how big this JSONObject
459- * will be.
460- *
461- * @param initialCapacity initial capacity of the internal map.
462- */
463- protected JSONObject (int initialCapacity ) {
464- this .map = new HashMap <String , Object >(initialCapacity );
465- }
466-
467450 /**
468451 * Accumulate values under a key. It is similar to the put method except
469452 * that if there is already an object stored under the key then a JSONArray
@@ -569,7 +552,7 @@ public static String doubleToString(double d) {
569552 */
570553 public Object get (String key ) throws JSONException {
571554 try {
572- return this . map .get (key );
555+ return super .get (key );
573556 } catch (Exception e ) {
574557 throw new JSONException (e .getMessage ());
575558 }
@@ -870,7 +853,7 @@ public String getString(String key) throws JSONException {
870853 * @return true if the key exists in the JSONObject.
871854 */
872855 public boolean has (String key ) {
873- return this . map .containsKey (key );
856+ return super .containsKey (key );
874857 }
875858
876859 /**
@@ -944,23 +927,7 @@ public Iterator<String> keys() {
944927 * @return A keySet.
945928 */
946929 public Set <String > keySet () {
947- return this .map .keySet ();
948- }
949-
950- /**
951- * Get a set of entries of the JSONObject. These are raw values and may not
952- * match what is returned by the JSONObject get* and opt* functions. Modifying
953- * the returned EntrySet or the Entry objects contained therein will modify the
954- * backing JSONObject. This does not return a clone or a read-only view.
955- *
956- * Use with caution.
957- *
958- * @see Map#entrySet()
959- *
960- * @return An Entry Set
961- */
962- protected Set <Entry <String , Object >> entrySet () {
963- return this .map .entrySet ();
930+ return super .keySet ();
964931 }
965932
966933 /**
@@ -969,7 +936,7 @@ protected Set<Entry<String, Object>> entrySet() {
969936 * @return The number of keys in the JSONObject.
970937 */
971938 public int length () {
972- return this . map .size ();
939+ return super .size ();
973940 }
974941
975942 /**
@@ -978,7 +945,7 @@ public int length() {
978945 * @return true if JSONObject is empty, otherwise false.
979946 */
980947 public boolean isEmpty () {
981- return this . map .isEmpty ();
948+ return super .isEmpty ();
982949 }
983950
984951 /**
@@ -989,10 +956,10 @@ public boolean isEmpty() {
989956 * is empty.
990957 */
991958 public JSONArray names () {
992- if (this . map .isEmpty ()) {
959+ if (super .isEmpty ()) {
993960 return null ;
994961 }
995- return new JSONArray (this . map .keySet ());
962+ return new JSONArray (super .keySet ());
996963 }
997964
998965 /**
@@ -1035,7 +1002,7 @@ public Object opt(String key) {
10351002 if (key == null ) {
10361003 return null ;
10371004 } else {
1038- final Object value = this . map .get (key );
1005+ final Object value = super .get (key );
10391006 if (JSONObject .NULL .equals (value )) {
10401007 return null ;
10411008 } else {
@@ -1527,7 +1494,7 @@ private void populateMap(Object bean) {
15271494 try {
15281495 final Object result = method .invoke (bean );
15291496 if (result != null ) {
1530- this . map .put (key , wrap (result ));
1497+ super .put (key , wrap (result ));
15311498 // we don't use the result anywhere outside of wrap
15321499 // if it's a resource we should be sure to close it
15331500 // after calling toString
@@ -1826,6 +1793,22 @@ public JSONObject putMap(String key, Map<?, ?> value) throws JSONException {
18261793 return this .put (key , new JSONObject (value ));
18271794 }
18281795
1796+ private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport (this );
1797+ private final String propertyName = "map" ;
1798+ public void addUpdateListener (PropertyChangeListener propertyChangeListener ) {
1799+ propertyChangeSupport .addPropertyChangeListener (propertyChangeListener );
1800+ }
1801+
1802+ public void update (String key , Object newValue ) throws JSONException {
1803+ if (propertyChangeSupport .hasListeners (this .propertyName )) {
1804+ final Object oldValue = this .opt (key );
1805+ this .put (key , newValue );
1806+ propertyChangeSupport .firePropertyChange (this .propertyName , oldValue , newValue );
1807+ } else {
1808+ throw new JSONException ("updateListener not initialized" );
1809+ }
1810+ }
1811+
18291812 /**
18301813 * <p><img src='https://media1.tenor.com/images/23d9d746fc87b3a93298af43dae21f6a/tenor.gif' /></p>
18311814 *
@@ -1853,16 +1836,18 @@ public JSONObject put(String key, Object value) throws JSONException {
18531836 // just...
18541837 // works
18551838 // btw idc
1856- this . map .put (key , JSONObject .NULL );
1839+ super .put (key , JSONObject .NULL );
18571840 } else {
18581841 testValidity (value );
18591842
18601843 if (value instanceof Collection ) {
18611844 this .putCollection (key , (Collection <?>) value );
1845+ } else if (value instanceof JSONObject ) {
1846+ super .put (key , value );
18621847 } else if (value instanceof Map ) {
18631848 this .putMap (key , (Map <?, ?>) value );
18641849 } else {
1865- this . map .put (key , value );
1850+ super .put (key , value );
18661851 }
18671852 }
18681853 return this ;
@@ -2076,7 +2061,7 @@ public static Writer quote(String string, Writer w) throws IOException {
20762061 * no value.
20772062 */
20782063 public Object remove (String key ) {
2079- return this . map .remove (key );
2064+ return super .remove (key );
20802065 }
20812066
20822067 /**
0 commit comments