11package org .json ;
22
3- import java .beans .PropertyChangeListener ;
4- import java .beans .PropertyChangeSupport ;
53import java .io .Closeable ;
64
75/*
@@ -38,7 +36,6 @@ of this software and associated documentation files (the "Software"), to deal
3836import java .lang .reflect .Modifier ;
3937import java .math .BigDecimal ;
4038import java .math .BigInteger ;
41- import java .util .ArrayList ;
4239import java .util .Collection ;
4340import java .util .Enumeration ;
4441import java .util .HashMap ;
@@ -48,6 +45,7 @@ of this software and associated documentation files (the "Software"), to deal
4845import java .util .Objects ;
4946import java .util .ResourceBundle ;
5047import java .util .Set ;
48+ import java .util .concurrent .atomic .AtomicBoolean ;
5149import java .util .regex .Pattern ;
5250
5351/**
@@ -1793,9 +1791,7 @@ public JSONObject putMap(String key, Map<?, ?> value) throws JSONException {
17931791 return this .put (key , new JSONObject (value ));
17941792 }
17951793
1796- private PropertyChangeSupport propertyChangeSupportUpdate = new PropertyChangeSupport (this );
1797- private PropertyChangeSupport propertyChangeSupportNotify = new PropertyChangeSupport (this );
1798- private static final String propertyChangeGlobalKeyword = "__THIS__" ;
1794+ private Runnable updateListener = null ;
17991795 /**
18001796 * Add a PropertyChangeListener to the JSONObject.
18011797 * The listener object may be added more than once, and will be called
@@ -1805,32 +1801,8 @@ public JSONObject putMap(String key, Map<?, ?> value) throws JSONException {
18051801 *
18061802 * @param listener The PropertyChangeListener to be added
18071803 */
1808- public void onUpdateGlobal (PropertyChangeListener listener ) {
1809- this .propertyChangeSupportUpdate .addPropertyChangeListener (JSONObject .propertyChangeGlobalKeyword , listener );
1810- }
1811-
1812- /**
1813- * Add a PropertyChangeListener for a specific property to the JSONObject.
1814- * The listener will be invoked only when a call on
1815- * update names that specific property
1816- * The listener object may be added more than once, and will be called
1817- * as many times as it is added.
1818- * If {@code listener} is null, no exception is thrown and no action
1819- * is taken.
1820- *
1821- * @param key The key string to listen on.
1822- * @param listener The PropertyChangeListener to be added
1823- */
1824- public void onUpdate (String key , PropertyChangeListener listener ) {
1825- if (JSONObject .propertyChangeGlobalKeyword .equals (key )) {
1826- throw new JSONException ("key \" " + JSONObject .propertyChangeGlobalKeyword + "\" is reserved" );
1827- } else {
1828- this .propertyChangeSupportUpdate .addPropertyChangeListener (key , listener );
1829- }
1830- }
1831-
1832- public void onNotify (String key , PropertyChangeListener listener ) {
1833- this .propertyChangeSupportNotify .addPropertyChangeListener (key , listener );
1804+ public void onUpdate (Runnable runnable ) throws JSONException {
1805+ updateListener = runnable ;
18341806 }
18351807
18361808 /**
@@ -1839,7 +1811,7 @@ public void onNotify(String key, PropertyChangeListener listener) {
18391811 *
18401812 * @param key
18411813 * A key string.
1842- * @param newValue
1814+ * @param v2
18431815 * An object which is the newValue. It should be of one of these
18441816 * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
18451817 * String, or the JSONObject.NULL object.
@@ -1849,60 +1821,38 @@ public void onNotify(String key, PropertyChangeListener listener) {
18491821 * @throws JSONException
18501822 * If updateListener not initialized.
18511823 */
1852- public JSONObject update (String key , Object newValue ) throws JSONException {
1853- final JSONObject oldThis = new JSONObject (this .toString ());
1854- final Object oldValue = this .opt (key );
1855-
1856-
1857- if (newValue instanceof JSONObject ) {
1858- this .put (key , newValue );
1859- final JSONObject __oldThis = new JSONObject (this .toString ());
1860-
1861- JSONObject newValueJson = (JSONObject ) newValue ;
1862-
1863- newValueJson .onUpdateGlobal (evt -> {
1864- this .propertyChangeSupportUpdate .firePropertyChange (JSONObject .propertyChangeGlobalKeyword , __oldThis , this );
1865- this .propertyChangeSupportUpdate .firePropertyChange (key , oldValue , newValue );
1866-
1867- this .propertyChangeSupportNotify .firePropertyChange (key , oldValue , newValue );
1868- });
1869- } else {
1870- this .put (key , newValue );
1824+ public JSONObject update (String key , Object v2 ) throws JSONException {
1825+ final Object v1 = super .put (key , v2 );
1826+ if (v2 instanceof JSONObject ) {
1827+ ((JSONObject ) v2 ).updateListener = this .updateListener ;
1828+ }
1829+ if (!(Objects .equals (v2 , v1 ) && Objects .equals (v1 , v2 ))) {
1830+ this .updateListener .run ();
18711831 }
1872-
1873-
1874- this .propertyChangeSupportUpdate .firePropertyChange (JSONObject .propertyChangeGlobalKeyword , oldThis , this );
1875- this .propertyChangeSupportUpdate .firePropertyChange (key , oldValue , newValue );
1876-
1877- this .propertyChangeSupportNotify .firePropertyChange (key , oldValue , newValue );
1878-
18791832 return this ;
18801833 }
18811834
1882- public JSONObject notify (String key , Object oldValue , Object newValue ) throws JSONException {
1883- this .propertyChangeSupportNotify .firePropertyChange (key , oldValue , newValue );
1835+ public JSONObject synchronize (JSONObject jo ) throws JSONException {
1836+ jo .forEach ((key , v2 ) -> {
1837+ this .compute (key , (k , v1 ) -> {
1838+ if (Objects .equals (v1 , v2 ) && Objects .equals (v2 , v1 )) {
1839+ return v1 ;
1840+ } else {
1841+ return JSONObject .NULL .equals (v2 ) ? JSONObject .NULL : v2 ;
1842+ }
1843+ });
1844+ });
18841845
1885- return this ;
1886- }
1846+ final String [] names = JSONObject .getNames (this );
1847+ if (names != null ) {
1848+ for (String key : names ) {
1849+ if (!jo .has (key )) {
1850+ this .remove (key );
1851+ }
1852+ }
1853+ }
18871854
1888- /**
1889- * Put a key/value pair in the JSONObject and
1890- * reports a bound property update to listeners.
1891- *
1892- * @param key
1893- * A key string.
1894- * @param newValue
1895- * An object which is the newValue. It should be of one of these
1896- * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
1897- * String, or the JSONObject.NULL object.
1898- * @return this.
1899- * @throws JSONException
1900- * If the newValue is non-finite number.
1901- * @throws JSONException
1902- * If updateListener not initialized.
1903- */
1904- public JSONObject update (JSONObject jo ) throws JSONException {
1905- return this .updateOrRemove (jo , false , true );
1855+ return this ;
19061856 }
19071857
19081858 /**
@@ -1921,63 +1871,32 @@ public JSONObject update(JSONObject jo) throws JSONException {
19211871 * @throws JSONException
19221872 * If updateListener not initialized.
19231873 */
1924- public JSONObject updateOrRemove (JSONObject jo ) throws JSONException {
1925- return this .updateOrRemove (jo , true , true );
1926- }
1927-
1928- public JSONObject mix (JSONObject jo ) throws JSONException {
1929- return this .updateOrRemove (jo , false , false );
1930- }
1931-
1932- public JSONObject mixOrRemove (JSONObject jo ) throws JSONException {
1933- return this .updateOrRemove (jo , true , false );
1934- }
1935-
1936- private JSONObject updateOrRemove (JSONObject jo , boolean remove , boolean triggerUpdate ) throws JSONException {
1937- final JSONObject oldThis = new JSONObject (this .toString ());
1938-
1939- final HashMap <String , Object > oldValues = new HashMap <String , Object >();
1940- final HashMap <String , Object > newValues = new HashMap <String , Object >();
1941- final ArrayList <String > delValues = new ArrayList <String >();
1874+ public JSONObject updateSynchronize (JSONObject jo ) throws JSONException {
1875+ final AtomicBoolean changed = new AtomicBoolean (false );
19421876
19431877 jo .forEach ((key , v2 ) -> {
19441878 this .compute (key , (k , v1 ) -> {
19451879 if (Objects .equals (v1 , v2 ) && Objects .equals (v2 , v1 )) {
19461880 return v1 ;
19471881 } else {
1948- oldValues .put (key , JSONObject .NULL .equals (v1 ) ? null : v1 );
1949- newValues .put (key , JSONObject .NULL .equals (v2 ) ? null : v2 );
1882+ changed .set (true );
19501883 return JSONObject .NULL .equals (v2 ) ? JSONObject .NULL : v2 ;
19511884 }
19521885 });
19531886 });
19541887
1955- if (remove ) {
1956- final String [] names = JSONObject .getNames (this );
1957- if (names != null ) {
1958- for (String key : names ) {
1959- if (!jo .has (key )) {
1960- oldValues .put (key , this .remove (key ));
1961- delValues .add (key );
1962- }
1888+ final String [] names = JSONObject .getNames (this );
1889+ if (names != null ) {
1890+ for (String key : names ) {
1891+ if (!jo .has (key )) {
1892+ changed .set (true );
1893+ this .remove (key );
19631894 }
19641895 }
19651896 }
19661897
1967- if (oldValues .size () > 0 ) {
1968- if (triggerUpdate ) {
1969- this .propertyChangeSupportUpdate .firePropertyChange (JSONObject .propertyChangeGlobalKeyword , oldThis , this );
1970- }
1971-
1972- oldValues .forEach ((key , oldValue ) -> {
1973- final Object v2 = delValues .contains (key ) ? null : newValues .get (key );
1974- final Object v1 = oldValue == null && v2 == null ? JSONObject .NULL : oldValue ;
1975-
1976- if (triggerUpdate ) {
1977- this .propertyChangeSupportUpdate .firePropertyChange (key , v1 , v2 );
1978- }
1979- this .propertyChangeSupportNotify .firePropertyChange (key , v1 , v2 );
1980- });
1898+ if (changed .get ()) {
1899+ this .updateListener .run ();
19811900 }
19821901
19831902 return this ;
0 commit comments