-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Use Appendable in place of Writer #241
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
Conversation
Change JSONObject, JSONArray, and JSONStringer to use Appendable where appropriate. This removes the need for synchronization in a few areas.
|
Overall this looks like a great refactor to me. I'd just like to ensure that all the branch points that were in Thanks for the great contribution. |
|
On an initial inspection, it looks like
Does that look right? If I missed any of them feel free to just update the pull request accordingly. |
|
Nevermind about the first part. I mistakenly looked at the diff instead of the full file. The conversion for I'm still in favor of removing the |
|
One last item. I'm not sure I'm a fan of this check in the if (o != null) {
writer.append(o);
} else {
quote(value.toString(), writer);
}If |
|
For the instanceof Boolean test, it's writing the value without going through the quote() method. This is so that boolean values are written as bare words, not quoted strings. Regarding the instanceof JSONString, I was just changing the logic from a ternary operation so that I could call the two parameter form of quote(), passing in the Appendable directly, rather than going through a separate StringBuilder accumulator. You're quite correct that this is a logic change from what was in the valueToString() method, which throws an exception instead. |
|
Good point on the boolean check, I didn't think of that. I can't decide if the exception being thrown on null is really a good idea either. I guess the original implementation expected "" to be written out for nulls, but then you can never have |
|
It's a tough one to resolve satisfactorily. The Javadoc of JSONString doesn't say what should happen if null is returned from toJSONString(), so we're in to an area of programming by co-incidence. If a JSONString object was used in a JSONObject or JSONArray object model, it would appear to work, though maybe unexpectedly, by falling back on its toString() method. If it was used in a JSONWriter or JSONStringer, it would fail with an exception. Solutions look like:
Personally, I think the behaviour of (3) is too subtle a change to consider as a change for an existing API. Either (1) or (2) could be justified, but it depends on how conservative you want to be. |
|
@stleary I think @run2000 made a decent list of the differences and problems each solution faces. I like the 2nd and 3rd options the best. I don't think we should ever fall back on toString() as that breaks the point of having the interface. If we go with option 2, we should update the Javadoc on the |
|
Thanks for the thorough refactor and discussion, and appreciate that this does not break the unit tests. Regarding behavior changes, will need a little time to look at them. For example, it is possible that the unit test coverage was not adequate, and should have broken on a behavior change. All things being equal, strongly prefer conservative changes that do not affect existing code. |
|
Resetting the clock on this pull request since functional changes were made without explanation or unit test results. |
|
No, it is removing the execute flag. |
|
And the 826ceef commit... |
|
Looking at the combined changes, the permissions are not changed. |
|
OK, I think I understand what is going on. Most of the changes were committed around June 18 2016. At the time, I committed to reviewing the unit tests, since even though they passed, they may have missed something. That was about the time I became heavily committed at work, and never got around to the unit tests. In the meanwhile, 826ceef was committed on July 1 2016, which in addition to the accidental mode change to 100755, appears to include functional changes to JSONArray.join(), JSONObject.valueToString(), JSONObject.writeValue(), and JSONWriter.value(). The mode change was corrected in 2917cc5, also on July 1 2016. Someone, hopefully @johnjaylward, needs to look at these changes and provide an approval or comments. Someone else (myself) needs to run the unit tests to make sure nothing is broken, and then make sure the code coverage of the changed code is acceptable, and that there are no missing tests that should be added. So no clock reset, because as it turns out, I never started the merge countdown. Please let me know if I am missing or misunderstanding something here. |
|
I took a quick look at the latest commits, but didn't fully review them to see why the changes were made. I probably won't have time to look at them in depth until Wednesday |
|
Apologies, I was just commiting some outstanding code I'd chaned since sending the merge request, not realising that it would affect the merge. The chane is adding an overload to writeValue () to take two parameters, since there two callers that took 0, 0 as the third and fourth parameters. Sorry for the noise. |
|
@run2000 No worries, this is a good exercise to make sure the changes are fully understood and work as intended. |
|
Sorry, I finally got around to reviewing the latest changes and they all look good. The main changes were to remove references to the The last change of significance is in The last thing to decide on before approval of this PR is how we want to handle the exception case for writing out |
|
Is there anything additional I need to do to help this along? Or are you comfortable shepparding this along now? I think my comments from Jun 16 still stand regarding the tradeoffs of toString() versus null versus JSONException. |
|
@run2000, there seems to be at least one item left from @johnjaylward's most recent comment, regarding the exception case for JSONString implementations that return null. Otherwise, I still need to do a final review of the changes, and confirm the unit test coverage is good. If you want, you could look at the unit tests to confirm all new code has coverage and that the unit tests are "reasonable". That is, that they adequately test the functionality, ensure there are no unexpected changes to existing functionality, and there are not any uncaught bugs. If so, please post your results here. |
|
I've been looking at test cases for When I next find a few hours, I'll have a closer look at where These are in |
|
Thanks, tests, and progress, looks good. |
|
I've created a new pull request #53 on the |
|
|
Ok, will do. Since I'm in that area, I notice JSONString doesn't have the json.org copyright notice. Is this an oversight or intentional? |
|
it would be an oversight. If you could add that too that would be best. |
This goes through the `null` return, and also documents what happens if a runtime exception is thrown.
|
Okay, Javadoc has been expanded on to document the |
|
I am not strongly in favor of this change. However, if the preparation is done to spec, the commit can proceed.
|
Fix up whitespace that was causing headaches for review. JSONWriter.value(Object) calls JSONObject.writeValue(Appendable, Object) directly, instead of going through the intermediary of valueToString(). This means it writes to the given Appendable directly, rather than builing a String value using a buffer, then writing the buffer.
| sb.append(separator); | ||
| } | ||
| sb.append(JSONObject.valueToString(this.myArrayList.get(i))); | ||
| JSONObject.writeValue(sb, this.myArrayList.get(i)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write directly to the one StringBuilder, avoiding creation of temporary buffer.
|
What problem does this code solve?
Changes to the API? Will this require a new release? Should the documentation be updated? Change to unit tests? |
|
The change from Writer to Appendable looks OK. Can't accept the change to JSONObject.valueToString() at the present time. Behavior changes have a high bar for acceptance, which this does not meet. Or the changes to buffer copies, since there is no compelling case for changing the code. If still interested, please resubmit just the Appendable changes. Also, going forward, recommend that code comments actually be in the code, not the pull request. |
+1 for this |
This change modifies JSONWriter to take an Appendable instead of a Writer as its constructor parameter. Appendable is an interface implemented by Writer, as well as classes such as StringBuilder.
This refactor allows JSONStringer to use a StringBuilder directly, instead of a StringWriter.
It also flows through to writeValue() in JSONObject. This in turn allows valueToString() to be simplified, simply delegating to writeValue() with StringBuilder as a parameter.
I ran the test suite in JSON-Java-unit-test, which continues to pass. The code coverage varies in minor ways in JSONObject, JSONArray, and JSONWriter, due to the code reorganisation.