Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for JSONArray.putAll methods #552

Merged
merged 6 commits into from
Aug 1, 2020

Conversation

johnjaylward
Copy link
Contributor

@johnjaylward johnjaylward commented Jul 27, 2020

What problem does this code solve?
The new putAll methods did not implement a way to concatenate JSONArray objects. It was an oversight during the review process, but should probably be allowed. This also adds in a shallow copy constructor for JSONArrays so the solution is a bit more holistic. I also added support for adding Generic Iterable objects which don't have a size function.

  • Adds a copy constructor for JSONArray
  • Updates the JSONArray.addAll(Object) method to be more lenient
  • Adds support for JSONArray.putAll of generic Iterables
  • Adds support for JSONArray.putAll of another JSONArray
  • Updates some JavaDoc for clarification.
  • Updates putAll methods to match other put methods and not wrap the items in the collection/array

Risks
Low. Just closes some gaps that were missed in the initial PR

Changes to the API?
New methods added, but no breaking changes

Will this require a new release?
No

Should the documentation be updated?
Yes. Notes should be added about the new putAll methods and information on expected use cases

Does it break the unit tests?
No. New tests were added to verify existing functionality and show new functions

Was any code refactored in this commit?
Yes. The internal addAll methods created in #529 were modified to optionally wrap the contents of the collection/array instead of always wrapping them.

Review status
APPROVED

@stleary
Copy link
Owner

stleary commented Jul 28, 2020

No objection to enhancing add_all() and put_all() a bit.
A strong case is needed to justify new constructors.
Clone() looks like it was added by accident, code seems to work fine without it.

@stleary
Copy link
Owner

stleary commented Jul 29, 2020

Starting 3-day comment window.

@johnjaylward
Copy link
Contributor Author

do you still want clone removed?

@stleary
Copy link
Owner

stleary commented Jul 29, 2020

do you still want clone removed?

Yes, it does not seem to be related to the rest of the PR.

@johnjaylward
Copy link
Contributor Author

@stleary in reference to your note about parity with JSONObject constructors, we currently have this one that does a partial copy: https://github.com/stleary/JSON-java/blob/master/src/main/java/org/json/JSONObject.java#L197

Should I add another one that does a full copy?

@johnjaylward
Copy link
Contributor Author

johnjaylward commented Jul 29, 2020

thinking the constructor would look like this:

    /**
     * Construct a JSONObject from another JSONObject.
     *
     * @param jo
     *            A JSONObject.
     * @throws NullPointerException
     *            If the {@code jo} JSONObject parameter is {@code null}
     */
    public JSONObject(JSONObject jo) {
        this(jo.map.size());
        this.map.putAll(jo.map);
    }

or

    /**
     * Construct a JSONObject from another JSONObject.
     *
     * @param jo
     *            A JSONObject.
     * @throws NullPointerException
     *            If the {@code jo} JSONObject parameter is {@code null}
     */
    public JSONObject(JSONObject jo) {
        this.map = new HashMap<String, Object>(jo.map);
    }

@@ -1534,12 +1593,25 @@ private void addAll(Collection<?> collection) {
}
Copy link
Contributor Author

@johnjaylward johnjaylward Jul 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed the JSONObject.wrap method call here (and in the other addAll method), and I think we may have an issue with consistency. If you notice both the JSONObject.put(String, Object) and JSONArray.put(Object) methods do not do any "wrap" calls to the values. However, the constructors (before the new addAll methods) both wrap values. I feel like this may have been an oversight at some point. Changing the wrap to happen consistently in the put methods breaks a number of tests.

@stleary some guidance on what to do in this case would be appreciated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, to this effect, I actually worked around it in my own copy by adding the wrap calls to the put methods

@stleary
Copy link
Owner

stleary commented Jul 29, 2020

@johnjaylward Thanks for catching these items, I added 2 new issues to track them away from this PR.

@johnjaylward johnjaylward force-pushed the JSONArrayCopyConstructor branch from 1289cc1 to 46cab0f Compare July 30, 2020 13:54
@johnjaylward
Copy link
Contributor Author

johnjaylward commented Jul 30, 2020

@stleary , I changed the way the addAll and hence the putAll methods work in the latest commit. I did this so functionality of putAll would be consistent with put. You may want to reset the review timer so interested people can check it out.

John J. Aylward added 6 commits July 30, 2020 10:10
* Adds a copy constructor for JSONArray
* Updates the JSONArray.addAll(Object) method to be more lenient
* Adds support for JSONArray.putAll of generic Iterables
* Adds support for JSONArray.putAll of another JSONArray
When called from the constructor, the individual items in the
collection/array are wrapped as done originally before the `putAll`
methods were added.

However this commit changes how `putAll` works. The items are no longer
wrapped in order to keep consistency with the other `put` methods.

However this can lead to inconsistencies with expectations. For example
code like this will create a mixed JSONArray, some items wrapped, others
not:

```java
SomeBean[] myArr = new SomeBean[]{ new SomeBean(1), new SomeBean(2) };
JSONArray jArr = new JSONArray(myArr); // these will be wrapped
// these will not be wrapped
jArr.putAll(new SomeBean[]{ new SomeBean(3), new SomeBean(4) });
```

For consistency, it would be recommended that the above code is changed
to look like 1 of 2 ways.

Option 1:
```Java
SomeBean[] myArr = new SomeBean[]{ new SomeBean(1), new SomeBean(2) };
JSONArray jArr = new JSONArray();
jArr.putAll(myArr); // will not be wrapped
// these will not be wrapped
jArr.putAll(new SomeBean[]{ new SomeBean(3), new SomeBean(4) });
// our jArr is now consistent.
```

Option 2:
```Java
SomeBean[] myArr = new SomeBean[]{ new SomeBean(1), new SomeBean(2) };
JSONArray jArr = new JSONArray(myArr); // these will be wrapped
// these will be wrapped
jArr.putAll(new JSONArray(new SomeBean[]{ new SomeBean(3), new
SomeBean(4) }));
// our jArr is now consistent.
```
@johnjaylward johnjaylward force-pushed the JSONArrayCopyConstructor branch from d403a2e to d30ecad Compare July 30, 2020 14:13
@stleary
Copy link
Owner

stleary commented Jul 30, 2020

Thanks, we still have 2 days left on the comment window, should be fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants