Compare commits

...

1189 Commits

Author SHA1 Message Date
Sean Leary
78137d389d
Merge pull request #1001 from marilynel/master
addressing sonarqube concerns in JSONObject
2025-07-31 20:54:08 -05:00
marilynel
38c3a0bb3f more sonarcube issues 2025-07-27 11:45:07 -08:00
marilynel
ebd9a17a3b addressing minor sonarqube concerns 2025-07-27 11:26:50 -08:00
Sean Leary
82432f0245
Merge pull request #1000 from marilynel/master
fixing sonarcube issues
2025-07-23 20:46:33 -05:00
marilynel
e762629bcc oops one more sonarcube issue lol 2025-07-20 12:04:51 -08:00
marilynel
7fc41a6c0e addressing cognitive complextity 2025-07-20 11:58:30 -08:00
marilynel
d5d82cdb87 fixing sonarcube issues 2025-07-20 11:31:29 -08:00
Sean Leary
0a9364e920
Merge pull request #999 from marilynel/master
fixed some strict mode issues
2025-07-16 20:12:57 -05:00
marilynel
c91b728386 oops forgot null 2025-07-13 12:52:42 -08:00
marilynel
fdaeb486ed fixed some strict mode issues 980 2025-07-13 12:41:17 -08:00
Sean Leary
f0a78aff61
Merge pull request #995 from marilynel/master
Fix regression XML parsing null with keepStrings
2025-07-09 20:18:48 -05:00
Sean Leary
a79e8a15e5
Merge pull request #994 from stleary/tech-debt-20250701
tech-debt-25250701
2025-07-08 11:04:29 -05:00
marilynel
7bb3df8ebf added test details 2025-07-06 12:41:44 -08:00
marilynel
3dce55794f fixed keeping null as string 2025-07-06 12:37:05 -08:00
Sean Leary
d7593fb808
Merge pull request #992 from surajdm123/add-tests
Added JUnit test cases for HTTPTokener
2025-07-06 08:27:59 -05:00
Sean Leary
1eed44a59e
Merge pull request #993 from surajdm123/add-tests-2
Added JUnit tests for XMLTokenerTest
2025-07-06 08:27:20 -05:00
Sean Leary
7eccadefcd
Merge pull request #991 from Simulant87/update-codeql-v3
update CodeQL to v3
2025-07-04 16:39:18 -05:00
Sean Leary
7b0d1942b4 tech-debt-25250701 add jacoco to gradle build, refactor JSONObject to restore performance 2025-07-03 20:39:13 -05:00
surajdm123
a729c2077a Added JUnit tests for XMLTokenerTest 2025-07-03 01:23:46 -07:00
surajdm123
7ac773be72 Added JUnit test cases for HTTPTokener 2025-07-03 00:58:15 -07:00
Simulant
7da120e631 update CodeQL to v3 2025-07-01 22:57:36 +02:00
Sean Leary
197afddbfb
Merge pull request #990 from Simulant87/984-refactor-cognitive-complexity-populateMap
Refactor JSONObject populateMap() per SonarQube
2025-07-01 07:13:18 -05:00
Sean Leary
1bdaacc8b0
Merge pull request #989 from AlexCai2019/master
Minor refactoring
2025-06-27 20:17:17 -05:00
Alex Cai
c882783d58
Format line 2755 in JSONObject.java 2025-06-27 01:44:27 +08:00
Simulant
5063d314a5 #984 extract method for annotation value check 2025-06-25 23:08:01 +02:00
Simulant
916fba5d39 #984 extract methods reducing cognitive complexity
for JSONObject#populateMap
2025-06-25 23:00:07 +02:00
AlexCai2019
aac376f305 Remove a redundant condition and an empty string
Remove "NULL.equals(object)" on line 2756 of JSONObject.java since line 2752 has already tested it.
Remove the empty string on line 249 of JSONPointer.java.
2025-06-23 01:31:51 +08:00
Sean Leary
32e56da786
Merge pull request #988 from stleary/remove-unused-code-jsonobject
removed unused method from jsonobject
2025-06-16 11:34:35 -05:00
Sean Leary
50330430ce remove-unused-code-jsonobject removed unused method from jsonobject 2025-06-07 16:15:43 -05:00
Sean Leary
f1935f5254
Merge pull request #987 from AlexCai2019/master
Use constant.equals()
2025-06-07 09:59:48 -05:00
AlexCai2019
e800cc349f Use constant.equals()
There are some equals() that are not constant.equals(variable), but variable.equals(constant)
2025-06-05 02:15:49 +08:00
Sean Leary
72a1a48173
Merge pull request #983 from harshith8854/master
Use JSONParserConfiguration to decide on serializing Null fields into JSONObject #982
2025-05-31 09:58:46 -05:00
hboggavarapu
a381060f81 Add testcase to assert Null fields serialization without JSONParserConfiguration 2025-05-24 21:54:12 +05:30
hboggavarapu
dadc3e59dc Use JSONParserConfiguration to decide on serializing null fields into JSONObject #982 2025-05-23 17:57:08 +05:30
Sean Leary
24fafcffeb
Merge pull request #981 from stleary/pre-release-20250517
pre-release-20250517 prep for next release
2025-05-17 07:44:38 -05:00
Sean Leary
418d5e9973 pre-release-20250517 prep for next release 2025-05-17 07:41:21 -05:00
Sean Leary
82a02d879e
Merge pull request #969 from marilynel/master
refactored large test for strict mode
2025-04-18 11:48:25 -05:00
marilynel
2184ef34d1 refactored large test for strict mode 2025-04-13 11:35:45 -07:00
Sean Leary
8e65eaa992
Merge pull request #968 from marilynel/master
Update keepStrings behavior to reflect changes in keepBooleanAsString, keepNumberAsString
2025-04-10 11:56:36 -05:00
marilynel
74439cf696 Merge branch 'master' of https://github.com/marilynel/JSON-java 2025-04-06 11:05:02 -07:00
marilynel
53da5ce2a9 adjusted keepstrings behavior to reflect changes in keepBooleanAsString & keepNumberAsString 2025-04-06 11:04:33 -07:00
Sean Leary
2e9ad6ff5a
Merge pull request #966 from marilynel/master
granular flags to control for keeping boolean or number values as strings
2025-04-04 07:40:55 -05:00
marilynel
8dbf03e76b work on issue 841 2025-03-30 12:21:44 -07:00
Sean Leary
4917e3579d
Merge pull request #962 from marilynel/master
Fix: handles edge case 'no \n at end of csv dataset + empty last column'
2025-03-26 20:24:01 -05:00
marilynel
45ec164faa Merge branch 'master' of https://github.com/marilynel/JSON-java 2025-03-23 10:27:57 -07:00
Sean Leary
d4c5136c21
Merge pull request #961 from effad/master
Option to store null value in JSONObject when parsing a map
2025-03-23 10:21:53 -05:00
Robert Lichtenberger
fd0cca3586 Fix cloning of parser configuration. 2025-03-21 10:12:20 +01:00
Robert Lichtenberger
50a5ce256b
Merge branch 'stleary:master' into master 2025-03-21 07:27:12 +01:00
Robert Lichtenberger
1afd7cd6bc Use better name for parser configuration option, fix API comment. 2025-03-21 07:25:37 +01:00
Sean Leary
7751b397bf
Merge pull request #960 from marilynel/master
Updated configuration to enable strictMode unit testing with Maven
2025-03-19 11:39:35 -05:00
Robert Lichtenberger
5d1c789490 Add test for JSONArray from Java collection. 2025-03-19 08:10:33 +01:00
Robert Lichtenberger
d1327c2da3 Allow to configure Java null handling. 2025-03-19 07:59:57 +01:00
marilynel
b2943b8fd0 fixed issue #943 Csv parsing skip last row if last line is missing newline 2025-03-16 12:50:58 -07:00
Marilyn Leary
628d8c42d9
Merge branch 'stleary:master' into master 2025-03-16 10:38:04 -07:00
marilynel
76ee4312b3 readme edit 2025-03-16 10:36:24 -07:00
marilynel
4a662316f7 edited pom.xml for mvn testing with strict mode 2025-03-16 10:33:14 -07:00
Sean Leary
6452a6f38d
Merge pull request #955 from marilynel/master
Add testWithStrictMode option to build.gradle
2025-03-05 20:30:24 -06:00
marilynel
ae4f4afcc7 dont mess with my line 2025-03-02 11:08:00 -08:00
marilynel
8a86894c63 test with strict mode enabled and fixed 2025-03-02 11:02:27 -08:00
marilynel
f30167e7c0 tests seem to be working, run with strictMode = fale then true 2025-02-23 22:00:22 -08:00
Sean Leary
75e5a3d646
Merge pull request #951 from marilynel/master
Fixing and updating unit tests for default strictMode
2025-02-21 07:37:47 -06:00
marilynel
3919abd69a optimized unit tests to respond accurately to default strictMode 2025-02-15 12:30:12 -08:00
marilynel
f112a091aa fixed failing unit tests in strict mode, issue 940 2025-02-15 12:03:03 -08:00
Sean Leary
42afb34045
Merge pull request #949 from marilynel/master
deprecated unnecessary setter method
2025-02-15 09:59:56 -06:00
Marilyn Leary
a746322e57
Merge branch 'stleary:master' into master 2025-02-09 19:36:46 -08:00
Sean Leary
c524cd17a0
Merge pull request #950 from stleary/upgrade-upload-artifact-in-pipeline
upgrade-upload-artifact-in-pipeline update from v3 to v4
2025-02-09 15:01:26 -06:00
Sean Leary
52f249c71e upgrade-upload-artifact-in-pipeline update from v3 to v4 2025-02-09 14:47:18 -06:00
marilynel
1689fc28cf deprecated unnecessary setter method 2025-02-09 11:13:22 -08:00
Sean Leary
22f8290840
Merge pull request #948 from Simulant87/947-JSONTokener-configuration-ignored
use JSONParserConfiguration of JSONTokener in JSONObject and JSONArray constructor instead of creating a new one
2025-01-19 09:09:42 -06:00
Sean Leary
8b857da467
Merge pull request #946 from Simulant87/928-javadoc-warning-JSONParserConfiguration
#928 add missing javaDoc for JSONParserConfiguration
2025-01-19 09:07:53 -06:00
Sean Leary
07b1291448
Merge pull request #942 from michael-ameri/fix-clone
add missing fields when cloning JSONParserConfiguration
2025-01-19 09:06:21 -06:00
Sean Leary
1d81e8879a
Merge pull request #938 from Simulant87/remove-references
Strict mode unit tests
2025-01-19 09:03:47 -06:00
Simulant
4c873a1db4 #947 use JSONParserConfiguration of JSONTokener in JSONObject and JSONArray constructor 2025-01-15 21:41:01 +01:00
Simulant
6631b80e8f #947 add new failing tests with JSONTokener having strict mode configuration 2025-01-15 21:38:46 +01:00
Simulant
9218f28db8 #928 add missing java dock for JSONParserConfiguration
(cherry picked from commit afd9a6fbb70cd66d440a53458c186d11377bd2ff)
2025-01-15 21:02:25 +01:00
Simulant
94341cd663 Revert "#928 add missing java dock for JSONParserConfiguration"
This reverts commit afd9a6fbb70cd66d440a53458c186d11377bd2ff.
2025-01-15 20:58:45 +01:00
Simulant
afd9a6fbb7 #928 add missing java dock for JSONParserConfiguration 2025-01-15 20:55:13 +01:00
Simulant87
54470e6b56
Merge branch 'stleary:master' into remove-references 2025-01-15 20:48:24 +01:00
Sean Leary
dde9d7eceb
Merge pull request #931 from stleary/remove-duplicate-moditect
remove-duplicate-moditect: from pom.xml
2025-01-15 07:46:37 -06:00
Sean Leary
8c427d9101
Merge pull request #937 from michael-ameri/remove-references
Update JSONParserConfiguration usage in JSONTokener, JSONArray, and JSONObject
2025-01-15 07:45:50 -06:00
Michael Ameri
4bbbe77446 add missing fields when cloning 2025-01-12 23:03:31 +01:00
Simulant
ad44a9274c add new test cases for JSONObject and JSONArray Constructors with JSONTokener and strict mode 2025-01-11 21:43:04 +01:00
Simulant
3b7ba07531 add test for invalid input on JSONTokener 2025-01-11 21:40:41 +01:00
Simulant
215f4268bf add Javadoc and rename parameters to speaking variable names 2025-01-11 21:35:36 +01:00
Michael Ameri
ca1c6830c9 remove field references to JSONTokener and JSONParserConfiguration in JSONArray
and JSONObject
2025-01-10 18:05:27 +01:00
Sean Leary
2e153737b1 remove-duplicate-moditect: from pom.xml 2025-01-08 07:33:37 -06:00
Sean Leary
391c86931b
Merge pull request #930 from stleary/pre-release-20250107
pre-release-20250107
2025-01-07 15:40:58 -06:00
Sean Leary
ed8c73964a pre-release-20250107 2025-01-07 15:30:43 -06:00
Sean Leary
324090a876
Merge pull request #929 from stleary/restore-moditect-pom.xml
restore-moditect-pom.xml restore plugin
2025-01-07 15:24:21 -06:00
Sean Leary
41c6e9e81e restore-moditect-pom.xml restore plugin 2025-01-07 07:47:46 -06:00
Sean Leary
0e60592bdb
Merge pull request #924 from stleary/pre-release-20241224
pre-release-20241224: updates for next release
2024-12-24 08:27:15 -06:00
Sean Leary
4cd70cf9d9 pre-release-20241224: updates for next release 2024-12-24 08:19:27 -06:00
Sean Leary
ac40a6faa3
Merge pull request #921 from stleary/restore-jsonparserconfiguration
Restore strict mode text parsing
2024-12-21 10:11:03 -06:00
Sean Leary
2dcef89a6f Code review action items - add comments and consistent error messages for strict mode 2024-12-21 09:50:52 -06:00
Sean Leary
d3c7eaf17e restore-jsonparserconfiguration: fix unit tests to work when strictMode default is true 2024-12-15 13:18:39 -06:00
Sean Leary
09536cd6c8 restore-jsonparserconfiguration: add jsonobject strict tests. Detect semicolon instead of colon separator in object 2024-12-15 10:38:54 -06:00
Sean Leary
1f0729cadb restore-jsonparserconfiguration: strict mode initial attempt. Still missing all JSONObject test cases and strict mode sanity check. Might be able to simplify implementation a bit more 2024-12-14 14:40:40 -06:00
Sean Leary
80b2672f77 restore-jsonparserconfiguration: clean up some whitespace 2024-12-14 10:07:26 -06:00
Sean Leary
1f308db7c4 restore-jsonparserconfiguration: Restore methods to be used for strict mode 2024-12-14 10:01:27 -06:00
Sean Leary
2ee5bf13f4
Merge pull request #907 from hexetia/fix-901
Fix a bug when calling JSONArray.addAll() with Collection as Object
2024-11-13 16:29:34 -06:00
Sean Leary
e7e52dad82
Merge pull request #894 from stleary/update-jsonpath
update-jsonpath: update jsonpath from 2.4.0 to 2.9.0
2024-11-10 17:43:33 -06:00
Sean Leary
39ee5e092f
Merge pull request #911 from stleary/revert-strict-mode-for-now
Revert strict mode
2024-11-10 17:41:11 -06:00
Sean Leary
215ec9bb9c Revert "Merge pull request #877 from rikkarth/feat/871-strictMode"
This reverts commit d02ac0f2a35f8c8ba56230bc4b67275010d4d617, reversing
changes made to cfd47615d0b9a2392945d198d7fd820bbbc17437.
2024-11-03 09:50:08 -06:00
Sean Leary
61dc2644d8 Revert "Merge pull request #886 from Simulant87/884-strictmode-javadoc"
This reverts commit 8983ca6da195bd8b7eb9e6655e97a2490d4afa2e, reversing
changes made to d02ac0f2a35f8c8ba56230bc4b67275010d4d617.
2024-11-03 09:49:50 -06:00
Sean Leary
ab1b9a3459 Revert "Merge pull request #888 from rikkarth/fix/887"
This reverts commit 14f71274f79ac50afb316845539f4195facc33ee, reversing
changes made to 054786e300d0fc38f0cf7fc0f2db4d9b39cb6443.
2024-11-03 09:49:23 -06:00
Lucas Nascimento
14e9cdc485
fix(#901): add the jsonparserConfiguration param to avoid a stackoverflow error 2024-10-05 11:43:00 -03:00
Lucas Nascimento
0d71dcf713
test(#901): call JsonArray.putAll with a casted list as object 2024-10-05 11:39:26 -03:00
Sean Leary
14f71274f7
Merge pull request #888 from rikkarth/fix/887
fix(#887): complete strictMode for JSONArray
2024-05-20 20:18:49 -05:00
rikkarth
a8ab79e3f3
chore(#887): JSONParserConfiguration strictMode true flag cleanup 2024-05-19 14:41:16 +01:00
Sean Leary
783577be19 update-jsonpath: update jsonpath from 2.4.0 to 2.9.0 2024-05-14 20:48:33 -05:00
Sean Leary
054786e300
Merge pull request #889 from kaiyaok2/fix_nio_tests
Fixed non-idempotent unit tests in `JSONObjectTest`
2024-05-03 12:15:52 -05:00
rikkarth
48dfeb84b0
fix(#887): unit tests, uncommented tests after fix 2024-04-28 23:52:53 +01:00
rikkarth
1ae43bdb90
fix(#887): regressions, unit tests
- JSONArray now evaluates EOF accordingly for empty Array inputs.
- JSONTokener fixed indentation
- externalized two JSONMLTest cases
2024-04-28 23:30:05 +01:00
Sean Leary
cf00ef3e8a fixes the broken JSONTokenerTest cases 2024-04-28 12:47:51 -05:00
Sean Leary
0180bd90f0 fixes the broken XMLTest cases 2024-04-28 12:41:58 -05:00
Sean Leary
fa2f3402d6 fixes the broken XMLConfigurationTest cases 2024-04-28 11:33:31 -05:00
Sean Leary
f4944fbf1e fixes the broken JSONMLTest cases 2024-04-28 11:28:38 -05:00
Sean Leary
1881cbe91a fixes the broken CDLTest cases 2024-04-28 11:23:01 -05:00
Sean Leary
209837357b fixes the broken JSONObjectTest cases 2024-04-28 11:03:24 -05:00
Sean Leary
d1fd901bdb fixes the JSONObjectNumberTest cases 2024-04-28 10:47:40 -05:00
Sean Leary
6529a7e536 fixes the broken JSONArrayTest cases 2024-04-28 10:45:23 -05:00
Sean Leary
4319b71934 force strict mode to expose failing tests 2024-04-28 10:37:36 -05:00
rikkarth
1e3f37be98
feat(#877): add additional validation, test case 2024-04-27 22:37:21 +01:00
rikkarth
7a8c21621c
fix(#877): adaptation for java 6 compatibility 2024-04-27 22:16:38 +01:00
rikkarth
9216a19366
feat(#877): improved JSONArray and JSONTokener logic
JSONArray construction improved to recursive validation
JSONTokener implemented smallCharMemory and array level for improved validation
Added new test cases and minor test case adaption
2024-04-27 22:14:35 +01:00
Kaiyao Ke
b6e347d7f8 fixed non-idempotent unit tests 2024-04-26 01:01:21 -05:00
rikkarth
879579d3bb
chore(#887): signature minor edit 2024-04-23 20:54:20 +01:00
rikkarth
898dd5a39d
fix(#887): allow null value strict mode 2024-04-23 20:52:02 +01:00
rikkarth
ce13ebd5fe
chore(#887): clean up parsedUnquotedText implementation 2024-04-23 20:42:11 +01:00
rikkarth
7cc19483fb
fix(#887): regression parsing array with non-string and boolean values 2024-04-23 19:06:27 +01:00
rikkarth
0bace72ced
fix(#887): small typo 2024-04-21 22:09:05 +01:00
rikkarth
03def9c7fc
Merge branch 'master' of github.com:stleary/JSON-java into fix/887 2024-04-21 22:05:56 +01:00
rikkarth
3dcd5b2fab
fix(#887): double array breaking JSONTokener.nextValue
change(#887): input validation
2024-04-21 11:03:15 +01:00
Sean Leary
8983ca6da1
Merge pull request #886 from Simulant87/884-strictmode-javadoc
add javadoc for strictmode
2024-04-15 17:00:32 -05:00
rikkarth
ce074e9f9a
fix(#887): corrected small typo 2024-04-14 23:23:06 +01:00
rikkarth
fe597d296e
fix(#887): complete strictMode for JSONArray 2024-04-14 23:11:17 +01:00
Simulant87
5bd4257c54
add javadoc for strictmode 2024-04-12 15:30:41 +02:00
Sean Leary
d02ac0f2a3
Merge pull request #877 from rikkarth/feat/871-strictMode
StrictMode Implementation for JSONArray
2024-04-10 10:27:09 -05:00
Sean Leary
cfd47615d0
Update README.md to fix the download-jar link
This got accidentally left out in the last release
2024-04-07 12:33:33 -05:00
rikkarth
3200275881
change(stleary#871-strictMode): cleanup
chore: removed PII from json sample
chore: JSONParserConfiguration.java cleanup
chore: JSONTokener.java nextValue partial rollback
2024-04-07 10:26:28 +01:00
rikkarth
d92d62afc2
Merge branch 'master' into feat/871-strictMode 2024-03-30 22:03:57 +00:00
rikkarth
46534b56ad
feat(#871-strictMode): removed allowSingleQuotes
test(#871-strictMode): adjusted related tests, add more test cases for non-compliant quotes in strict mode
2024-03-30 18:44:51 +00:00
Sean Leary
87406e4db1
Merge pull request #879 from Simulant87/add-syntax-error-details
extend syntax error information
2024-03-30 09:42:27 -05:00
rikkarth
c0918c2428
feat(#871-strictMode): add allowSingleQuote option, add enhancements and simplification 2024-03-30 11:06:30 +00:00
rikkarth
d2cb38dba7
feat(#871-strictMode): added ORIGINAL implementation to JSONParserConfiguration 2024-03-30 10:26:44 +00:00
rikkarth
4929fc99c1
test(#871-strictMode): added more test cases, improved existing ones 2024-03-30 10:15:47 +00:00
rikkarth
372f5caac4
feat(#871-strictMode): enhanced and simplified strictMode logic 2024-03-30 10:15:10 +00:00
Simulant
0fcf352848 Revert "explain position information numbers in syntax exception"
This reverts commit d69d5e284b3ee797f3950d80eb9dfc571a944284.
2024-03-27 20:36:35 +01:00
Simulant87
78cdb3d0d6
fix wrong comment update 2024-03-23 22:07:05 +01:00
Simulant87
7324cc0b26
fix wrong comment update 2024-03-23 22:06:20 +01:00
Simulant87
75a34a246f
fix wrong comment update 2024-03-23 22:05:51 +01:00
Simulant87
78151beea2
fix wrong comment update 2024-03-23 22:05:27 +01:00
Simulant87
ccb4a9b95f
fix wrong comment update 2024-03-23 22:04:53 +01:00
Simulant87
4e39d8ccf2
fix wrong comment update 2024-03-23 22:03:57 +01:00
Simulant
d69d5e284b explain position information numbers in syntax exception 2024-03-23 22:02:54 +01:00
Simulant
f1c9d0787b add test cases for extended syntax error exception messages 2024-03-23 21:49:58 +01:00
rikkarth
49de92224d
chore(#871-strictMode): fix small spacing typo 2024-03-22 18:42:49 +00:00
rikkarth
d335447ab4
test(#871-strictMode): add two more test which validate error correctness 2024-03-22 18:28:56 +00:00
Simulant
6c160b7d1a leave JSONTokener.toString unchanged 2024-03-22 12:08:06 +01:00
Simulant
30dc22790c extend syntax error information 2024-03-22 12:02:09 +01:00
rikkarth
8f66865e0a
Merge branch 'master' into feat/871-strictMode 2024-03-21 08:08:15 +00:00
Sean Leary
45dede448c
Merge pull request #867 from Simulant87/863-improve-toString-performance-StringBuilderWriter
Improve toString Performance: Use StringBuilderWriter for toString methods
2024-03-20 16:56:33 -05:00
Simulant87
6aed1cfeb6
fix typo 2024-03-18 23:07:22 +01:00
rikkarth
3672b5e158
chore(#871-strictMode): reverted unrelated changes 2024-03-17 15:20:38 +00:00
rikkarth
f3b3491f4d
chore(#871-strictMode): reverted refactor in JSONTokener 2024-03-16 01:13:52 +00:00
rikkarth
e2fe14d951
fix(#871-strictMode): replaced stream with conventional loop for 1.6 compatibility 2024-03-16 00:48:58 +00:00
rikkarth
0ff368ca07
chore(#871-strictMode): corrected small syntax typo in unit test 2024-03-15 23:13:21 +00:00
rikkarth
c51efe8b08
docs(#871-strictMode): JSONArray constructor JavaDoc update 2024-03-15 22:55:09 +00:00
rikkarth
e67abb3842
feat(#871-strictMode): improved validation, strict mode for quotes implementation 2024-03-15 22:28:31 +00:00
rikkarth
c140e91bb8 test(#871-strictMode): strict mode false initial implementation 2024-03-15 01:23:20 +00:00
rikkarth
63e8314deb feat(#871-strictMode): strictMode JSONArray initial implementation
test(#871-strictMode): initial test implementation
2024-03-15 00:45:32 +00:00
rikkarth
dcbbccc76c feat(#871-strictMode): strictMode configuration add to JSONParserConfiguration
docs(#871-strictMode): add javadoc
2024-03-15 00:19:25 +00:00
Simulant
b75da07545 #863 move instanceof Enum check back to original position 2024-03-10 23:21:47 +01:00
Simulant
6c35b08ad6 #863 make StringBuilderWriter public and move test 2024-03-10 23:20:09 +01:00
Simulant
60090a7167 add a test case for an enum implementing JSONString
(cherry picked from commit d17bbbd4174b3d84f70a6f0fdce9edc10d846a1a)
2024-03-10 21:13:54 +01:00
Simulant
0c5cf18255 Revert "#863 improve performance of JSONTokener#nextString"
This reverts commit 63625b3c622407273d2654660be7659ac5d74db7.
2024-03-10 21:12:28 +01:00
Simulant
5974fc1a38 Merge branch 'master' into 863-improve-toString-performance-StringBuilderWriter 2024-03-10 21:10:21 +01:00
Simulant
a3f15e5883 Revert "#863 replace usage of back() method in JSONObject parsing"
This reverts commit 5407423e439dfb4095e371666a65cf4f6603606d.
2024-03-10 21:08:31 +01:00
Simulant
045324ab42 Revert "#863 replace short switch statements with if-else"
This reverts commit c010033591c192a0821bdd8fe23bc61cdc6fe738.
2024-03-10 21:08:10 +01:00
Simulant
eda08415ca Revert "#863 increase compiler stack size on build pipeline"
This reverts commit 6660e4091569fc48e582ab77c6626491f8bab8db.
2024-03-10 21:05:22 +01:00
Sean Leary
48c092acfb
Merge pull request #876 from stleary/remove-jsonparserconfig-ctor
remove-jsonparserconfig-ctor - just use withOverwriteDuplicateKey()
2024-03-09 09:22:39 -06:00
Sean Leary
dab29ec1d5 remove-jsonparserconfig-ctor - just use the withOverwriteDuplicateKey() method 2024-03-09 09:15:53 -06:00
Sean Leary
712859d771
Merge pull request #857 from XIAYM-gh/master
Implemented custom duplicate key handling (#840)
2024-03-09 09:11:09 -06:00
XIAYM
05b0897f41
Merge branch 'stleary:master' into master 2024-03-09 22:19:30 +08:00
Simulant
c010033591 #863 replace short switch statements with if-else 2024-03-05 22:12:57 +01:00
Simulant
5407423e43 #863 replace usage of back() method in JSONObject parsing 2024-03-05 22:11:24 +01:00
Simulant
63625b3c62 #863 improve performance of JSONTokener#nextString
replacing a switch-case statement with few branches
by if-else cases
2024-03-05 09:43:54 +01:00
Sean Leary
f9b5587c87
Merge pull request #875 from stleary/20240303-pre-release-updates
20240303-pre-release-updates updates for release
2024-03-03 08:55:13 -06:00
Sean Leary
3d69990ab5 20240303-pre-release-updates updates for release 2024-03-03 08:47:53 -06:00
Sean Leary
ba05e1a98c
Merge pull request #874 from stleary/pipeline-updates
Deployment and Pipeline action updates
2024-03-03 08:02:03 -06:00
Sean Leary
390d442054 pipeline-updates - remove deployment.yml for now, will restore after setting up secrets 2024-03-02 10:00:13 -06:00
Sean Leary
3eb8a62af6 pipeline-updates - space after # char? 2024-03-02 09:57:40 -06:00
Sean Leary
989cdb61bc pipeline-updates - do not build in parallel 2024-03-02 09:15:32 -06:00
Sean Leary
8de0628bd1 pipeline-updates - disable deployment.yml workflow for now (it's not set up in secrets yet) 2024-03-02 08:55:24 -06:00
Sean Leary
569be9d19e Merge branch 'master' into pipeline-updates 2024-03-02 08:34:10 -06:00
Sean Leary
3f97826462
Merge pull request #869 from stleary/revert-recent-objLong-getLong-changes
Revert recent obj long get long changes
2024-02-28 09:52:04 -06:00
Sean Leary
d520210ea2 Added one more example to XMLTest clarifyCurrentBehavior() 2024-02-25 10:45:34 -06:00
Simulant
f38452a00c add a comment explaining the ordering
(cherry picked from commit df0e3e9ab73d99f1256055a17bd86c8a1a000b59)
2024-02-25 09:50:26 +01:00
Simulant
4f456d9432 #863 fix changed behaviour of changing order in writeValue with JSONString 2024-02-25 09:42:06 +01:00
Sean Leary
898288810f add unit tests to clarify current behavior for JSONObject and XML 2024-02-24 21:07:12 -06:00
Simulant
d878c38d40 #863 reorder instanceof checks by assumed frequency 2024-02-24 22:36:14 +01:00
Simulant
e2194bc190 #863 undo wrong optimisation, fixing failing test 2024-02-24 21:35:29 +01:00
Simulant
d672b44a25 #863 add StringBuilderWriter unit test 2024-02-24 21:29:28 +01:00
Simulant
06778bd2d9 #863 compute initial capacity for StringBuilderWriter 2024-02-24 21:21:06 +01:00
Sean Leary
771c82c4eb backing out recent changes to optLong, getLong. See #868 2024-02-24 13:07:51 -06:00
Simulant
6660e40915 #863 increase compiler stack size on build pipeline 2024-02-23 22:02:35 +01:00
Simulant
0ff635c456 #863 improve formatting 2024-02-23 21:56:40 +01:00
Simulant
7c7a98da71 #863 use StringBuilderWriter to toString methods
resulting in a faster toString generation.
2024-02-23 21:48:25 +01:00
Sean Leary
d36066cf82
Merge pull request #860 from jscrdev/fixed-javadocs2
Added missing Javadocs for Java 21
2024-02-22 20:18:34 -06:00
XIAYM-gh
af8cb376c2 Add tests (+ fix bugs) & missing javadoc 2024-02-19 18:58:25 +08:00
Sean Leary
c1107fa987 pipeline-updates: Java 11 intermittent fail - try separate build 2024-02-18 16:17:41 -06:00
Sean Leary
cd631d970e pipeline-updates: Java 11 intermittent fail - try an earlier release (there is no later release 2024-02-18 15:54:29 -06:00
Sean Leary
f0289413d6 pipeline-updates: Java 11 intermittent fail - try increasing stack size 2024-02-18 15:45:13 -06:00
Sean Leary
b4b39bb441 pipeline-updates: Java 11 intermittent test failures, try not running in parallel 2024-02-18 15:29:44 -06:00
XIAYM
6dc1ed0a02
Merge branch 'stleary:master' into master 2024-02-18 11:07:09 +08:00
Valentyn Kolesnikov
86253211c2 Added missing Javadocs for Java 21 2024-02-18 04:20:33 +02:00
Sean Leary
77c899d325
Merge pull request #858 from stleary/cleanup-after-commit
cleanup-after-commit for #854 and #856
2024-02-17 16:23:51 -06:00
XIAYM
b314611230
Merge branch 'stleary:master' into master 2024-02-15 09:51:56 +08:00
XIAYM-gh
cb2c8d3962 Revert some unnecessary changes (mentioned in #840) 2024-02-14 17:53:58 +08:00
Sean Leary
f164b8c597 cleanup-after-commit reverted pom.xml version 8 change and tabs in cdl. Updated JavaDocs in cdl 2024-02-13 20:08:54 -06:00
Sean Leary
6358b7f681
Merge pull request #854 from jscrdev/fixed-javadocs
Enhanced documentation for Java classes
2024-02-13 09:05:48 -06:00
XIAYM-gh
21a9fae7b0 Try making java 6 & old version javadoc generator compatible 2024-02-13 22:33:30 +08:00
Sean Leary
8550175556
Merge pull request #856 from michael-ameri/custom-delimiter
add ability for custom delimiters
2024-02-13 08:21:43 -06:00
XIAYM-gh
10514e48cb Implemented custom duplicate key handling
- Supports: throw an exception (by default), ignore, overwrite & merge into a JSONArray
 - With tests, 4/4 passed.
2024-02-13 18:56:10 +08:00
mameri
72214f1b43 add ability for custom delimiters 2024-02-09 11:52:18 +01:00
Valentyn Kolesnikov
99c84fdf3a Enhanced documentation for Java classes 2024-02-07 14:43:44 +02:00
Sean Leary
010e83b925
Update RELEASES.md for release 20240205 2024-02-05 20:44:18 -06:00
Sean Leary
9865dbbebe
Update pom.xml for release 20240205 2024-02-05 20:23:59 -06:00
Sean Leary
4548696c8d
Update README.md for release 20240205 2024-02-05 20:22:23 -06:00
Sean Leary
f0308a3475
Merge pull request #855 from stleary/Fix-stack-overflow-failures
Fixing JSONArrayTest testRecursiveDepthArrayFor1000Levels()
2024-02-05 14:18:20 -06:00
Sean Leary
19dec1bb5f Fixing JSONArrayTest testRecursiveDepthArrayFor1000Levels() 2024-02-02 13:11:37 -06:00
Sean Leary
f2d20988de
Merge pull request #832 from keatontaylor10/feature-disable-whitespace-trim
Add a config flag to disable whitespace trimming
2024-01-26 19:40:36 -06:00
Keaton
7915d8518f
Merge branch 'stleary:master' into feature-disable-whitespace-trim 2024-01-18 09:17:26 +02:00
Sean Leary
55b824d4c4
Merge pull request #846 from stleary/cleanup-and-merge-tests
Cleanup warnings and merge new unit tests
2024-01-04 08:52:02 -06:00
Sean Leary
ac7806d060
Merge pull request #845 from seppl831/fix-annotation-search-performance
improved annotation search performance
2024-01-01 11:43:15 -06:00
Sean Leary
86bb0a1a02 cleanup-and-merge-tests: pull in unit tests from #809 2023-12-30 17:00:02 -06:00
Sean Leary
5ddb8c3d35 cleanup-and-merge-tests: fix warnings, set gradlew permissions, enable unchecked warnings in maven 2023-12-30 16:30:19 -06:00
Thomas Gress
23ac2e7bca improved annotation search performance 2023-12-29 12:28:24 +01:00
Sean Leary
d7819a4fa2
Merge pull request #823 from sk02241994/issue_743
JSON parsing self reference object and array
2023-12-27 05:28:17 -06:00
sk02241994
7701f21839 Adding comments 2023-12-24 11:39:26 +05:30
sk02241994
ffd48afa42 Review comments 2023-12-23 10:53:54 +05:30
sk02241994
abea194120 Adding JSONParserConfiguration for configuring the depth of nested maps 2023-12-22 15:47:55 +05:30
sk02241994
dcac3bc18e Adding test case for nested json with depth of 999, 1000, 1001 2023-12-22 15:47:54 +05:30
sk02241994
6d811607dd Resolving issue #743
- Recursive depth issue found in JSONObject
- Recursive depth issue found in JSONArray
2023-12-22 15:47:54 +05:30
Keaton Taylor
4d6de8c00a Remove unused constructor and add comment above other constructor 2023-12-13 14:04:05 +02:00
Sean Leary
6dba7220e1
Merge pull request #835 from LaFriska/branch1
deleted redundant .toString() call in README test method Sysout
2023-12-07 08:20:34 -06:00
Sean Leary
d4521696a9
Merge pull request #831 from adityap27/refactor
Refactor NumberConversionUtil and toString() of CookieList & XML Classes.
2023-12-03 10:18:22 -06:00
Keaton Taylor
e430db40aa Update XMLParserConfiguration to not be static and add a comment about the use of shouldTrimWhiteSpace 2023-11-30 10:05:54 +02:00
LaFriska
7cbeb35498 deleted redundant .toString() call in README test method Sysout 2023-11-28 17:39:46 -05:00
Aditya Purohit
aba82d9cc4 isNumericChar() - switch comparison order 2023-11-28 02:56:10 +00:00
Keaton Taylor
9ee10fdfc8 Merge remote-tracking branch 'origin/master' into feature-disable-whitespace-trim 2023-11-27 11:15:49 +02:00
Aditya Purohit
4a468d163a
Merge branch 'stleary:master' into refactor 2023-11-26 20:16:53 -04:00
Sean Leary
92991770ca
Merge pull request #830 from HappyHacker123/upgrade_json_path
Upgrade json-path's version to 2.4.0 to avoid dependency conflict.
2023-11-25 13:51:07 -06:00
Keaton Taylor
09f35372d4 Update clone() method so that default constructor does not need to be changed 2023-11-22 11:14:50 +02:00
Keaton Taylor
30f5b2de79 Add a config flag to disable whitespace trimming 2023-11-20 17:50:22 +02:00
Aditya Purohit
7f1cb8bf62 refactor: decompose condition of digit checks by using extra method 'isNumericChar(...)' in NumberConversionUtil. 2023-11-19 09:51:44 -04:00
Aditya Purohit
75419e3f25 refactor: introduce explaining variable 'indentationSuffix' in XML.toString() 2023-11-19 09:21:05 -04:00
Aditya Purohit
097a401f3f refactor: rename variable boolean 'b' to 'isEndOfPair' in CookieList.toString() 2023-11-19 09:11:32 -04:00
Sean Leary
5c4a7a1b1f
Merge pull request #828 from harshith2000/Fix-flaky-tests
Fixed flaky tests in XMLTest.java
2023-11-17 11:51:00 -06:00
HappyHacker123
b5f9febfe9 Upgrade json-path's version to 2.4 to avoid dependency conflict. 2023-11-17 21:31:06 +08:00
Saiharshith Karuneegar Ramesh
1a61af8255 Fixed flaky tests in XMLTest.java 2023-11-13 13:25:30 -06:00
Sean Leary
11c29c366d
Merge pull request #824 from johnjaylward/fix821
Ignore tests that fail due to resource differences
2023-11-10 11:27:18 -06:00
John J. Aylward
a3742acf74 Fixes #821
add ignore annotation to tests that may fail due to differences in machine resources and can't be controlled via the tests
2023-11-06 17:54:09 -05:00
Sean Leary
783d298f99
Merge pull request #814 from rudrajyotib/issue813
Refactor duplicate code for stringToNumber() in JSONObject, JSONArray, and XML
2023-10-31 17:40:17 -05:00
Sean Leary
6c1bc0660a
Merge pull request #820 from rudrajyotib/issue748
Close XML tag explicitly for empty tags with configuration.
2023-10-31 17:38:45 -05:00
rudrajyoti biswas
8ec822c575 #748 - PR comments - follow convention of configuration builder. 2023-10-28 07:36:31 +05:30
rudrajyoti biswas
1ceb70b525 #813 - PR comments - alignments 2023-10-28 07:09:37 +05:30
rudrajyoti biswas
c05d7058ff #748 - javadoc updated for methods. 2023-10-27 17:17:20 +05:30
rudrajyoti biswas
07a358449a Merge branch 'master' into issue813 2023-10-27 17:09:01 +05:30
rudrajyoti biswas
7fe2fd95a5 Merge branch 'master' into issue748 2023-10-27 17:07:46 +05:30
Sean Leary
b5b9f636ff
Merge pull request #815 from johnjaylward/ensure_1-6_compat
Ensure java 6 compatable
2023-10-25 13:53:23 -05:00
rudrajyoti biswas
c6ec2f0e4c #748 - close XML tag explicitly for empty tags with configuration. 2023-10-25 23:23:00 +05:30
Sean Leary
1a2108efa2
Merge pull request #812 from yeikel/patch-1
docs: use syntax highlighting
2023-10-25 09:58:30 -05:00
Sean Leary
caadcba30e
Merge pull request #794 from rudrajyotib/master
XML optLong/getLong equivalent updates for string to number conversion.
2023-10-25 09:55:13 -05:00
John J. Aylward
ea842b437c remove unneeded matrix build typ for java 1.6 2023-10-23 17:13:07 -04:00
John J. Aylward
a2a8240d0d upload jar files to GitHub release 2023-10-23 17:07:10 -04:00
John J. Aylward
1ab11d0802 ensure java 6 compatable 2023-10-23 15:08:21 -04:00
rudrajyoti biswas
5539722c69 #813 - address PR review comment - brought down visibility. 2023-10-23 23:03:35 +05:30
rudrajyoti biswas
98b79ae7bf #813 - moved number conversion related common changes to utility static method. 2023-10-23 19:16:25 +05:30
Rudrajyoti Biswas
04a4c5a3ec
Merge branch 'stleary:master' into master 2023-10-21 12:29:31 +00:00
Yeikel
6007165c17
docs: use syntax highlighting
use syntax highlighting to improve the format of the readme
2023-10-21 00:10:42 -04:00
Sean Leary
411f71137b
Merge pull request #803 from yeikel/patch-2
ci: test with Java 21
2023-10-20 07:37:32 -05:00
Sean Leary
e9117dbe5c
Merge branch 'master' into patch-2 2023-10-20 07:33:03 -05:00
Sean Leary
7a85b514a9
Merge pull request #808 from theKnightsOfRohan/fix-build-messages
Fix compiler warnings
2023-10-20 07:32:07 -05:00
Sean Leary
82c8f486c5
Merge pull request #806 from johnjaylward/deploymentPipeline
Add new deployment pipeline
2023-10-20 07:31:12 -05:00
Sean Leary
006b29bda3
Merge branch 'master' into deploymentPipeline 2023-10-20 07:28:44 -05:00
Sean Leary
996d3a5fad
Merge pull request #801 from johnjaylward/updateActionsForDeploy
Updates the pipeline to validate that packaging a jar works properly
2023-10-20 07:26:41 -05:00
Yeikel
de745e9c81
ci: test with Java 21 2023-10-19 22:41:47 -04:00
rudrajyoti biswas
2374766018 #790 - Update XML with changes for string to number conversion.
For now the code remains duplicated in JSON and XML parsers.
Unit test cases updated to comply with number expectations.
2023-10-19 14:07:53 +05:30
rudrajyoti biswas
1d0775cce7 Revert changes with feature and refactor together. 2023-10-19 10:28:11 +05:30
Sean Leary
d677a99f4e
Merge pull request #798 from hofi1/bugfix/fix-XML-flacky-test
fix: flakiness in org.json.junit.XMLTest#testIndentComplicatedJsonObjectWithArrayAndWithConfig
2023-10-17 13:52:29 -05:00
Sean Leary
e6d37c469d
Merge pull request #788 from hofi1/bugfix/fix-JSON-flakiness
Fix string compare unit tests
2023-10-17 13:51:40 -05:00
theKnightsOfRohan
f074bed732 fix(ParserConfiguration): add <T> params to docs 2023-10-16 17:48:03 -07:00
John J. Aylward
e8f125fb6e update workflow to use GPG 2023-10-16 18:23:39 -04:00
John J. Aylward
ed183e6142 remove deprecated parent pom per Sonatype docs 2023-10-16 18:22:08 -04:00
John J. Aylward
a86786a5f5 Add snapshot repository 2023-10-16 18:03:39 -04:00
John J. Aylward
7c4f98c42c Add new deployment pipeline.
This should only trigger when a release is published
2023-10-16 17:30:57 -04:00
John J. Aylward
3894483560 Add build badges to README 2023-10-16 15:44:02 -04:00
John J. Aylward
be115059e9 Correct supported java versions 2023-10-16 15:44:02 -04:00
John J. Aylward
2b41cf44b5 include jar in job artifacts 2023-10-16 15:43:55 -04:00
John J. Aylward
9a9efac2af Correct moditect configuration to work on java8 2023-10-16 15:36:33 -04:00
John J. Aylward
134074aeaa Revert "Reverting #761"
This reverts commit b180dbedbc99bb177e5b277f1bff2a1b79cebda6.
2023-10-16 15:36:33 -04:00
John J. Aylward
8540bb80c0 Validate that the mvn package step completes 2023-10-16 15:36:33 -04:00
simonh5
4dfd779b1c fix: flakiness in org.json.junit.XMLTest#testIndentComplicatedJsonObjectWithArrayAndWithConfig 2023-10-14 17:21:06 -05:00
rudrajyoti biswas
7b2677ac5a #790 - Update XML with changes for string to number conversion.
Moved the code logic to a common utility to de-duplicate.
2023-10-14 10:05:36 +05:30
simonh5
29a7f4622d remove JSONAssert 2023-10-13 21:23:09 -05:00
Sean Leary
f346203cd6
Merge pull request #793 from stleary/revert-761
Reverting #761
2023-10-13 16:10:17 -05:00
Sean Leary
b180dbedbc Reverting #761 2023-10-13 16:04:14 -05:00
Sean Leary
cca6d1020f
Merge pull request #792 from stleary/pre-release-20231013
update the docs for release 20231013
2023-10-13 15:40:19 -05:00
Sean Leary
af5f780d5b update the docs for release 20231013 2023-10-13 15:30:31 -05:00
Sean Leary
495cec9037
Merge pull request #783 from rudrajyotib/master
optLong vs getLong inconsistencies
2023-10-12 22:06:11 -05:00
simonh5
e4aa7f1308 fix: change from JSONAssert to checking the similarity of JSONObjects 2023-10-12 21:09:27 -05:00
rudrajyoti biswas
56cb5f84c4 #653 - review comments updated. 2023-10-12 11:03:13 +05:30
rudrajyoti biswas
0cdc38ac24 #653 - review comments updated. 2023-10-12 00:53:36 +05:30
Rudrajyoti Biswas
d5277b126b
Merge branch 'stleary:master' into master 2023-10-11 19:17:21 +00:00
Simon Hofbauer
228598ca84
Merge pull request #6 from hofi1/bugfix/fix-flakyness-testToJSONObject_reversibility
fix: flakiness in JSONMLTest#testToJSONObject_reversibility
2023-10-10 18:20:20 -05:00
Simon Hofbauer
0a6fb1d578
Merge pull request #5 from hofi1/bugfix/fix-flakyness-org.json.junit.JSONObjectTest#valueToString
fix: flakiness in org.json.junit.JSONObjectTest#valueToString
2023-10-10 18:19:28 -05:00
Sean Leary
c4cd526c53
Merge pull request #779 from Madjosz/713_jsonobject_nonfinite
add validity check for JSONObject constructors
2023-10-08 17:08:32 -05:00
Sean Leary
776b5ccb85
Merge pull request #778 from Madjosz/fix_xml_test
Fix XMLTest.testIndentComplicatedJsonObjectWithArrayAndWithConfig() for Windows - in the test
2023-10-08 17:06:55 -05:00
Sean Leary
fb99c06bad
Merge branch 'master' into fix_xml_test 2023-10-08 17:03:35 -05:00
Sean Leary
bc09f90e90
Merge pull request #782 from mureinik/XMLTest-windows
Fix XMLTest.testIndentComplicatedJsonObjectWithArrayAndWithConfig() for Windows - in the test
2023-10-08 17:00:25 -05:00
Madjosz
c93014cb53 add validity check for JSONObject constructors
* fixes #713
* document JSONException in JavaDoc
* remove unused Comparable<T> boundary to reuse GenericBean in test
2023-10-07 09:38:54 +02:00
Madjosz
0e4a94d91d fix failing test XML test on Windows machines 2023-10-07 09:38:07 +02:00
rudrajyoti biswas
1a38879c90 #653 - optLong vs getLong inconsistencies
For exponential decimal conversion, number is not touched.
Leading zeros removed from numeric number strings before converting to number.
2023-10-06 21:34:00 +05:30
Allon Mureinik
4c8cac22a8 Use System.lineSeparator()
Use the built-in System.lineSeparator() instead of implementing it
ourselves with System.getProperty("line.separator") in order to clean
up the code and make it easier to maintain.
2023-10-05 19:47:33 +03:00
Allon Mureinik
fe45fa9cfb Fix XMLTest on Windows
XMLTest.testIndentComplicatedJsonObjectWithArrayAndWithConfig fails
when run on Windows due to mismatching linebreaks (that aren't
important for the test's functionality) between the actual and
expected strings.

For the actual strings, linebreaks are canonized to the platform's
native linebreak using `replaceAll("\\n|\\r\\n",
System.getProperty("line.separator")`. However, the expected result is
read from a file, and is left with the linebreaks that were originally
used to create it.

The solution is to perform the same canonization on both strings.

Closes #781
2023-10-05 15:36:07 +03:00
Sean Leary
79af389f7a
Merge pull request #774 from mccartney/removing-synchronized
Removing excessive synchronization
2023-10-04 07:40:10 -05:00
Sean Leary
1726b6cf55
Merge pull request #776 from mccartney/junit-4-13-2
JUnit 4.13.2
2023-10-04 07:39:26 -05:00
Sean Leary
beb2fb5706
Merge pull request #772 from eamonnmcmanus/complexkey
Disallow nested objects and arrays as keys in objects.
2023-10-01 11:04:40 -05:00
Grzegorz Olędzki
ff921db783 Junit 4.13.2 2023-09-30 21:53:36 +02:00
Grzegorz Olędzki
61bb60e752 Removing excessive synchronization 2023-09-30 21:36:11 +02:00
Sean Leary
ef68cdf810
Merge pull request #773 from eedijs/master
Add optJSONArray method to JSONObject with a default value
2023-09-30 11:47:01 -05:00
Éamonn McManus
eaa5611ba3
Merge branch 'stleary:master' into complexkey 2023-09-28 11:33:08 -07:00
Éamonn McManus
dbb113176b Add more test cases for unquoted text in objects and arrays. 2023-09-28 11:05:50 -07:00
Éamonn McManus
16967f322e Simplify the check for object keys that are themselves objects.
For object keys, we can just skip the part of `nextValue()` that parses values
that are objects or arrays. Then the existing logic for unquoted values will
already stop at `{` or `[`, and that will produce a `Missing value` exception.
2023-09-27 12:42:04 -07:00
Edijs
284a316838 Add optJSONArray and optJSONObject methods to JSONArray with a default value 2023-09-27 19:30:45 +03:00
Sean Leary
4e8231c512
Merge pull request #770 from eamonnmcmanus/testfixes
Small test fixes.
2023-09-25 20:37:44 -05:00
Edijs
db0fde2a56 Add optJSONArray method to JSONObject with a default value 2023-09-25 20:31:58 +03:00
Éamonn McManus
661114c50d Generalize the logic to disallow nested objects and arrays as keys in objects.
Fixes #771.
2023-09-20 10:50:48 -07:00
simonh5
ca88454f1c fix: flakiness in org.json.junit.JSONObjectTest#valueToString 2023-09-19 14:28:06 -05:00
Éamonn McManus
3e688afc66 Small test fixes.
One test method was missing `@Test` so it was never run.

One test method used another test class as the base for finding a test
resource. While this works in practice with Maven, it is not strictly
right.
2023-09-19 07:38:13 -07:00
simonh5
becc1631e6 fix: flakiness in JSONMLTest#testToJSONObject_reversibility 2023-09-18 20:20:13 -05:00
Sean Leary
01727fd0ed
Merge pull request #769 from jscrdev/fixed-warnings
Addressed Java 17 compile warnings
2023-09-16 08:30:44 -05:00
Valentyn Kolesnikov
74cd73f97c Addressed compile warnings 2023-09-08 07:34:00 +03:00
Sean Leary
c29d4881e0
Merge pull request #741 from jscrdev/setup-java-11
Configure Java 8 as the minimum required version
2023-09-03 17:17:04 -05:00
Sean Leary
7c1b6531e7
Update CONTRIBUTING.md
Updated for Hacktoberfest 2023
2023-09-03 11:35:15 -05:00
Valentyn Kolesnikov
db122e5d3a
Merge branch 'master' into setup-java-11 2023-09-03 18:40:40 +03:00
Sean Leary
a309931d20
Merge pull request #761 from bowbahdoe/master
Add module-info
2023-09-03 10:35:21 -05:00
Valentyn Kolesnikov
e27da22e05
Update build.gradle 2023-08-29 05:00:13 +03:00
Valentyn Kolesnikov
af6d07cecb Resolved Gradle build dependency 2023-08-29 03:22:20 +03:00
Sean Leary
64093366b3
Merge pull request #764 from johnjaylward/CodeQl_Pipeline_Update
Update CodeQL action version
2023-08-28 19:20:36 -05:00
John J. Aylward
9b69ec49ad update CodeQL action version 2023-08-28 12:51:52 -04:00
Valentyn Kolesnikov
2c674be1b6 Update pipeline.yml 2023-08-28 19:06:27 +03:00
Valentyn Kolesnikov
be33deb7d5 Update README.md 2023-08-28 19:04:30 +03:00
Valentyn Kolesnikov
48089a4da7 Update pipeline.yml 2023-08-28 19:04:30 +03:00
Valentyn Kolesnikov
a4e152f4f0 Update pipeline.yml 2023-08-28 19:03:43 +03:00
dburbrid
3dd8f2ecd5 Correction of bug when compiling/testing on Windows: Issue537 file must be read as UTF-8 (Issue 745) 2023-08-28 19:03:40 +03:00
Valentyn Kolesnikov
bae0b0dac9 Updated mockito 2023-08-28 19:01:47 +03:00
Valentyn Kolesnikov
e563dbcaaa Setup java 8 as minimum version 2023-08-28 19:00:00 +03:00
Ethan McCue
50dfcc59b3 Remove automatic module name 2023-08-16 11:25:15 -04:00
Ethan McCue
b2943eb395 Add module-info to maven build 2023-08-16 11:24:57 -04:00
Sean Leary
60662e2f83
Merge pull request #759 from eamonnmcmanus/eofnull
JSON parsing should detect embedded `\0` values
2023-08-05 08:33:26 -05:00
Éamonn McManus
2a4bc3420a Apply simplification suggested by @johnjaylward. 2023-08-01 14:38:45 -07:00
Éamonn McManus
b6ff0db984 Fix indentation in test. 2023-08-01 13:49:59 -07:00
Éamonn McManus
c8a9e15a57 Don't skip past \0 when parsing JSON objects.
A better solution might be to use -1 instead 0 to represent EOF everywhere,
which of course means changing `char` variables to `int`. The solution here is
enough to solve the immediate problem, though.

Fixes #758.
2023-08-01 13:11:25 -07:00
Sean Leary
402db6ad84
Merge pull request #753 from davejbur/add-object-methods-and-test
Updated new object methods
2023-07-14 20:03:13 -05:00
dburbrid
4951ec48c8 Renamed object methods from ...Obj to ...Object.
Added object method for optDoubleObject (returns Double vice double).
Added similar methods in JSONArray.
Added test methods.
2023-06-29 09:39:34 +01:00
Sean Leary
8ce0019a5d
Merge pull request #752 from davejbur/issue-745-compile-error
Correction of bug when compiling/testing on Windows
2023-06-28 20:45:05 -05:00
dburbrid
3d524349a1 Correction of bug when compiling/testing on Windows: Issue537 file must be read as UTF-8 (Issue 745) 2023-06-26 09:33:03 +01:00
Sean Leary
a963115ac2
Update pom.xml for maven deploy
Deploy failed on the mac pro with: gpg: signing failed: Inappropriate ioctl for device

Somehow I had a different gpg version installed. This change fixed it.
2023-06-18 12:58:32 -05:00
Sean Leary
f959baa3cb
Merge pull request #749 from stleary/pre-release-20230618
Prep for release 20230618
2023-06-18 12:24:27 -05:00
Sean Leary
c048b36516
Update pom.xml for 20230618 2023-06-18 12:18:36 -05:00
Sean Leary
f6e5bfa2db
Update RELEASES.md for 20230618 2023-06-18 12:17:56 -05:00
Sean Leary
084b24cbe7
Update README.md for 20230618 2023-06-18 12:16:14 -05:00
Sean Leary
22ccf1b8e5
Merge pull request #740 from michael-o/proper-encoding
JSONTokener(InputStream) violates rfc8259#section-8.1 (#739)
2023-05-28 14:11:41 -05:00
Michael Osipov
133c0cc75f JSONTokener(InputStream) violates rfc8259#section-8.1 (#739)
Always use UTF-8 when an InputStream is passed.

This fixes #739.
2023-05-24 11:45:25 +02:00
Sean Leary
0578285036
Merge pull request #734 from superMaaax/fix_flaky
Fixed Flaky Tests Caused by JSON permutations
2023-03-27 16:25:57 -05:00
superMaaax
48fb5261fe Fixed Flaky Tests Caused by JSON permutations
###Description
Flaky Tests found using NonDex by running the commands -
mvn -pl . edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=org.json.junit.XMLTest#testIndentComplicatedJsonObject

mvn -pl . edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=org.json.junit.XMLTest#testIndentSimpleJsonArray

mvn -pl . edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=org.json.junit.XMLTest#testIndentSimpleJsonObject

The logged failure was-

[ERROR] Failures:
[ERROR] XMLTest.testIndentSimpleJsonObject:1193 expected:<...>
<employee>
<[married>true</married>
<name>sonoo</name>
<salary>56000</salary]>
</employee>
</Te...> but was:<...>
<employee>
<[name>sonoo</name>
<salary>56000</salary>
<married>true</married]>
</employee>
</Te...>

The issue is the same for all three tests, so here I only show the failure message for the third test (to reduce the length of the error message).

### Investigation

The tests fail with a comparison error while comparing an expected JSON String and the result from the value returned from XML.toString(). The toString function of XML makes no guarantees as to the iteration order of the attributes in the object. This makes the test outcome non-deterministic, and the test fails whenever the function returns a mismatch in order of the elements in the JSON String. To fix this, the expected and actual keys should be checked in a more deterministic way so that the assertions do not fail.

### Fix

Expected and Actual values can be converted into JSONObject and the similar function can be used to compare these objects. As this function compares the values inside the JSONObjects without needing order, the test becomes deterministic and ensures that the flakiness from the test is removed.

The PR does not introduce a breaking change.
2023-03-21 20:58:32 -05:00
Sean Leary
8353b9c3f0
Merge pull request #731 from JoaoGFarias/patch-1
Removing commented out code in JSONObject optDouble()
2023-03-11 19:28:01 -06:00
Sean Leary
fe22b242b5
Merge pull request #733 from haribabu-dev/jsontokener_closable
JSONTokener implemented java.io.Closeable
2023-03-11 19:26:55 -06:00
HariBabu t
7eca507d13 Removed overriding closable interface. 2023-03-07 13:58:30 +08:00
HariBabu t
e1eabc9c27 JSONTokener implemented java.io.Closeable 2023-03-04 23:08:32 +08:00
JoĂŁo Farias
0d436d92e2
Removing commented out code 2023-03-02 16:39:11 +01:00
Sean Leary
45bcba518f
Merge pull request #729 from TamasPergerDWP/f-parserconfig
Refactor ParserConfiguration class hierarchy
2023-02-28 12:49:42 -06:00
Sean Leary
47fb49b6a8
Update for release 20230227 2023-02-27 07:21:11 -06:00
Sean Leary
0df034c9fd
Update for release 20230227 2023-02-27 07:20:10 -06:00
Sean Leary
f0a05e6911
Update README.md 2023-02-27 07:17:51 -06:00
Tamas Perger
24093491a8 refactor: introduce ParserConfiguration class hierarchy 2023-02-21 19:13:07 +00:00
Sean Leary
1275f6809d
Merge pull request #723 from TamasPergerDWP/master
JSONML should be protected from stack overflow exceptions caused by recursion, resolving #722
2023-02-17 13:47:36 -06:00
Tamas Perger
9234eab00a refactor: make JSONMLParserConfiguration all-args constructor private, enforcing the builder pattern. 2023-02-13 01:09:29 +00:00
Tamas Perger
72f4c3e646 refactor: rename XMLtoJSONMLParserConfiguration to JSONMLParserConfiguration 2023-02-12 01:32:34 +00:00
Tamas Perger
df2d6f8363 fix: introduce optional XMLtoJSONMLParserConfiguration parameter for JSONML.toJSONArray(...) functions, to facilitate max nesting depth override. 2023-02-11 01:52:13 +00:00
Tamas Perger
a6e412bded fix: limit the nesting depth in JSONML
Limit the XML nesting depth for CVE-2022-45688 when using the JsonML transform.
2023-02-10 01:46:44 +00:00
Tamas Perger
2391d248cc fix: amend XMLParserConfiguration.clone() to include the new maxNestingDepth param.
Amend Javadoc for XML and XMLParserConfiguration classes.
2023-02-10 01:45:34 +00:00
Sean Leary
401495ae86
Merge pull request #720 from cleydyr/issue-708
Limit the XML nesting depth for CVE-2022-45688
2023-02-05 19:30:04 -06:00
Cleydyr de Albuquerque
448e204186 docs: remove wrong description of parse method 2023-02-02 20:16:16 +01:00
Cleydyr de Albuquerque
eb56704e68 fix: set default maximum nesting depth as 512 2023-02-02 18:15:03 +01:00
Cleydyr de Albuquerque
651511f500 tests: add new test to verify that an XML having the permitted nesting depth can be converted 2023-02-01 20:22:47 +01:00
Cleydyr de Albuquerque
a14cb12c85 refactor: keep consistence with other tests and tidy up constant 2023-02-01 20:22:32 +01:00
Cleydyr de Albuquerque
f566a1d9ee fix: limit the nesting depth 2023-02-01 16:26:58 +01:00
Sean Leary
5920eca2d7
Merge pull request #711 from 6d64/revert-pull-707-interviewbit-spam
Revert pull 707 - interviewbit spam
2022-11-30 20:20:39 -06:00
6d64
3b097d051a Revert pull 707 - interviewbit spam
Reverted commit that was added by a bot adding interviewbit spam to
repos on github
2022-12-01 03:21:26 +11:00
Sean Leary
4e630e58a4
Merge pull request #707 from ASAlishaa/patch-1
Added new resource to the repos
2022-11-17 19:14:11 -06:00
ASAlisha
b732188e4e
Added new resource to this repos.
Added resource in the correct format.
2022-11-15 16:31:05 +05:30
ASAlisha
5369442671
Added new resource to the repos
Added new useful JSON resource.
2022-11-14 03:26:18 +05:30
Sean Leary
bb1138762a
Merge pull request #703 from TomerPacific/feature/update-release-for-JSONMap-Change
Update Releases.md for JSONObject(Map): Throws NPE if key is null
2022-11-05 17:39:13 -05:00
Sean Leary
6a732ec99d
Merge pull request #704 from niranjanib/fix-javadoc-not-visible-in-website
move javadoc comments above the interface definition to make it visible
2022-11-05 17:38:15 -05:00
Niranjani
c798c76ddd move javadoc comments above the interface definition to make it visible
Fix #670
2022-10-30 22:10:38 +05:30
unknown
23d5e52a53 feature/update-release-for-JSONMap-Change adding breaking change for JSONMap to corresponding release 2022-10-28 08:45:54 +03:00
Sean Leary
98df35449a
Merge pull request #696 from bmk15897/fix-flaky-test
Update JSONPointerTest for NonDex compatibility
2022-10-15 08:24:01 -05:00
Sean Leary
1be6ee31a7
Merge pull request #694 from DeaneOC/Pretty-Print-XML-Functionality
Pretty print XML
2022-10-13 21:46:26 -05:00
Bharati Kulkarni
a2d3d3c9b5 Fix Flaky Test 2022-10-11 14:33:43 -05:00
Dean
bf9219386a
Merge branch 'master' of https://github.com/stleary/JSON-java into Pretty-Print-XML-Functionality 2022-10-10 11:12:49 +01:00
Dean
85495facbd
Corrected test 2022-10-10 11:12:35 +01:00
Dean
7aba3ac941
System line seperator now being used in JUnit test 2022-10-10 11:09:42 +01:00
Sean Leary
d51250f6b0
Merge pull request #692 from InACommandBlock/patch-1
Example.md syntax highlight and indentation
2022-10-09 22:28:36 -05:00
Dean
9cb8e153bf
Added JavaDocs 2022-10-07 17:57:07 +01:00
Dean
80c1479ad8
Merge branch 'master' of https://github.com/stleary/JSON-java into Pretty-Print-XML-Functionality 2022-10-07 17:56:54 +01:00
Sean Leary
444335d12a
Merge pull request #691 from hendrixjoseph/issue-657-unit-tests-should-check-various-number-formats
create unit tests for various number formats
2022-10-07 11:18:41 -05:00
Dean
a2c0562e04
Removed unused import 2022-10-07 15:04:09 +01:00
Dean
153972afdf
Adding resources 2022-10-07 10:35:14 +01:00
Dean
4a8ff28fd8
Reduced Test code length by using resources 2022-10-07 10:35:06 +01:00
Dean
fa457a4113
Test cases for XML toString indentation 2022-10-06 12:01:26 +01:00
Dean
b7f708b222
Altered XML toString to allow indentation param 2022-10-06 12:01:13 +01:00
TheCommandBlock
12411b7981
Update Examples.md
Co-authored-by: JAYSE <104235500+JayseMayne@users.noreply.github.com>
2022-10-06 03:18:03 +02:00
TheCommandBlock
61801c623e
Minor Adjustments Example.md
Added syntax highlighting, standardised indentation
2022-10-06 00:48:34 +02:00
hendrixjoseph
1915aab7c4 create unit tests for various number formats 2022-10-04 14:32:41 -04:00
Sean Leary
8439039da7
Update pom.xml
For the 20220924 release
2022-09-24 16:25:18 -05:00
Sean Leary
a6bdd081eb
Update RELEASES.md 2022-09-24 16:13:11 -05:00
Sean Leary
a30d71fdca
Update README.md 2022-09-24 16:11:12 -05:00
Sean Leary
cdd67b0aef
Merge pull request #688 from stleary/update-copyright
#688 update copyright
2022-08-26 21:07:52 -05:00
stleary
89f6e7f6a6 Merge branch 'master' into update-copyright 2022-08-26 20:59:00 -05:00
Sean Leary
346fb26f2d
Merge pull request #683 from spaffrath/Issue_682_JSONString_similarity
Issue 682 JSONString similarity
2022-08-26 20:57:22 -05:00
stleary
6daabb43ab update-copyright - Replace copyright and license restrictions with Public Domain 2022-08-23 20:00:25 -05:00
Sean Leary
57f785c42e
Merge pull request #687 from schw1804/patch-1
Fix typo
2022-08-23 17:13:10 -05:00
Joshua Schwartz
3eecd67a3b
Fix typo 2022-08-23 15:00:01 -05:00
Sean Leary
5a587bbdfd
Merge pull request #685 from stleary/map-unit-tests
JSONObject map type unit tests
2022-08-23 07:59:35 -05:00
stleary
e0534b3ec7 initial attempt to test for inconsistent map types in JSONObject 2022-08-20 16:14:34 -05:00
spaffrath
7dd9e01dae
Merge branch 'stleary:master' into Issue_682_JSONString_similarity 2022-08-20 07:51:30 -07:00
Sean Leary
88ca19042b
Merge pull request #684 from stleary/pipeline-fix-1
pipeline-fix-1 remove v7 build from pipeline
2022-08-20 08:33:23 -05:00
stleary
b4036e6a8e pipeline-fix-1 remove v7 build from pipeline 2022-08-13 12:50:10 -05:00
Scott Paffrath
89f16ad0af Issue 682 JSONString similarity 2022-08-05 11:00:33 -07:00
Sean Leary
6f92a3ab4e
Merge pull request #675 from johnjaylward/Iss-649-better-error-message
Updates value error messages to be consistent.
2022-03-24 20:32:31 -05:00
John J. Aylward
beae279b21 Updates tests to have updated message expectations 2022-03-21 13:06:19 -04:00
John J. Aylward
a642329314 Updates value error messages to be consistent.
Provide both the type and value that failed conversion. Tries not to
"toString" large value types like Arrays or Maps. For those types it
will just output the type and not a value.
2022-03-21 12:48:25 -04:00
Sean Leary
9abb35ad39
Update RELEASES.md 2022-03-20 09:34:12 -05:00
Sean Leary
c0a1d5f741
Update pom.xml 2022-03-20 09:28:19 -05:00
Sean Leary
04a765647e
Update README.md 2022-03-20 09:27:38 -05:00
Sean Leary
4f78ec666a
Update RELEASES.md 2022-03-20 09:25:53 -05:00
Sean Leary
7d6b76de37
Merge pull request #608 from artem-smotrakov/setup-codeql-scans
Include CodeQL scan in the commit checks
2022-02-06 12:19:41 -06:00
Sean Leary
5cfe216ffd
Update codeql-analysis.yml
...
2022-02-04 08:08:41 -06:00
Sean Leary
c33ad9c062
Merge pull request #660 from johnjaylward/Issue654StackOverflowError
Wrap StackOverflow with JSONException to fix Issue #654
2022-01-31 08:54:53 -06:00
John J. Aylward
7a124d857d Add test cases for invalid input 2022-01-26 12:19:53 -05:00
Sean Leary
f1b0210b8a
Update README.md 2021-12-05 10:36:03 -06:00
Sean Leary
8ef8e1463d
Update pom.xml 2021-12-05 09:12:55 -06:00
Sean Leary
48b6aa3e4c
Update RELEASES.md 2021-12-05 09:10:32 -06:00
Sean Leary
cff5cc6c74
Merge pull request #646 from Zetmas/feature/issue#595
XMLParserConfiguration support for xml to json arrays
2021-12-03 19:37:00 -06:00
Sean Leary
04e8ea84dc
Merge pull request #651 from cushon/i650
Use IdentityHashSet for cycle detection
2021-12-03 19:35:26 -06:00
Liam Miller-Cushon
812955e39d Use IdentityHashSet for cycle detection
Fixes https://github.com/stleary/JSON-java/issues/650
2021-11-26 20:07:21 -05:00
Sean Leary
bc623e36d6
Merge pull request #645 from Zetmas/feature/issue#632
Detect and handle circular references when parsing Java beans
2021-11-21 11:31:48 -06:00
Zach
5dd78bc0b9 Test case passed with tags with multiple entries set forceList 2021-11-19 21:22:38 -06:00
Zach
e638955034 Pass test case for empty tag with forceList 2021-11-19 21:05:05 -06:00
Zach
3f9b53fee4 longer forcelist tests 2021-11-19 20:55:10 -06:00
Zach
a0f90b776d Passed simple test 2021-11-19 20:46:15 -06:00
Zach
fafaeb7aa6 Added simple test case 2021-11-19 20:32:36 -06:00
Zach
e356739a2f Added forceList configuration to XMLParserConfiguration 2021-11-19 19:42:00 -06:00
Zach
fca7e17b38 Added test cases for self recursion and complex but no recursion 2021-11-18 14:53:22 -06:00
Zach
fb96e870a9 add test case and modified old ones 2021-11-17 20:00:12 -06:00
Zach
638273af7a long circle test 2021-11-17 19:41:00 -06:00
Zach
1ffcf3915c successful test 2021-11-17 19:35:53 -06:00
Zach
4565bddcbb data class for recursive test 2021-11-17 17:23:40 -06:00
Zach
b5bcb68968 added set check logic 2021-11-17 16:57:41 -06:00
Zach
7823d3a4f3 locate the pace for cyclic check 2021-11-17 15:28:01 -06:00
Sean Leary
d6227c83d7
Merge pull request #640 from katldewitt/561-backslashes
Address #561: Add unit tests for multiple backslashes
2021-11-02 11:44:49 -05:00
Sean Leary
f54b5e4b0d
Merge pull request #626 from loic5/patch-1
Create CODE_OF_CONDUCT.md
2021-10-29 15:49:43 -05:00
LoĂŻc Lengrand
30b3680050
Update CODE_OF_CONDUCT.md
I replaced the email address
2021-10-29 09:38:19 +02:00
katldewitt
3ed9154f63 fix: refactor tests
context: the backslash unit tests cannot be in the complete document as uriFragmentNotationRoot() will fail due to backslash handling
2021-10-28 05:59:22 -07:00
katldewitt
669316d29e chore: write unit tests for behavior 2021-10-28 05:45:23 -07:00
katldewitt
30a70c8886 chore: initial unit tests 2021-10-24 08:41:57 -07:00
Sean Leary
93f4b34890
Merge pull request #637 from Ronqn/master
Reorganized README.md
2021-10-17 20:44:46 -05:00
Ronqn
9c87d6e214 Updated README.md 2021-10-16 16:43:10 +02:00
Ronqn
f27e5fe04d Docs folder containing the contributions files 2021-10-16 16:42:55 +02:00
Sean Leary
2528e60b09
Merge pull request #634 from JanitSri/update-README
updated the README to include commands for Unix systems
2021-10-16 09:17:45 -05:00
Sean Leary
4e601fd46e
Merge pull request #631 from sreekesh93/techdebt/refactor-test
Refactor JSONPointerTest
2021-10-14 16:58:45 -05:00
Janit Sriganeshaelankovan
9f19c22b77 updated the README to include commands for Unix systems 2021-10-14 16:43:30 -04:00
sreekesh93
9000901a11 Fix test to support oreder mismatch 2021-10-11 19:55:31 +05:30
sreekesh93
f03eb56071 Fix test to support oreder mismatch 2021-10-11 19:46:27 +05:30
sreekesh93
b4bbc58644 Refactor JSONPointerTest 2021-10-11 10:42:31 +05:30
Sean Leary
cf43419015
Update pipeline.yml
replace hardcoded Ubuntu version with "Ubuntu-latest"
2021-10-09 10:14:47 -05:00
LoĂŻc Lengrand
e896497602
Create CODE_OF_CONDUCT.md
hello i propose to create a Code of conduct :)
2021-10-08 16:35:55 +02:00
Sean Leary
d284c81e16
Update README.md 2021-10-05 21:01:55 -05:00
Sean Leary
a526b41b67
Create CONTRIBUTING.md 2021-10-05 20:56:25 -05:00
Sean Leary
9f07853f19
Merge pull request #622 from pedrombmachado/patch-1
Update README.md
2021-08-28 15:38:21 -05:00
Pedro Machado
e29c541353
Update README.md
corrected the backward slash into forwarding slash
2021-08-28 21:28:31 +01:00
Sean Leary
de5f768cff
Merge pull request #621 from cushon/typos
Fix some typos
2021-08-25 20:10:30 -05:00
Liam Miller-Cushon
8ca8a80753 Fix some typos 2021-08-25 13:56:44 -07:00
Sean Leary
fb71d9d40f
Merge pull request #606 from artem-smotrakov/fix-javadoc
Fix javadoc
2021-08-17 20:40:04 -05:00
Sean Leary
b80141a19c
Merge pull request #607 from artem-smotrakov/add-security-policy
Added a security policy
2021-08-14 15:02:05 -05:00
Sean Leary
c0e467c848
Merge pull request #613 from stleary/fix-similar-check
Fixes Issue #611 JsonObject.similar() returns after number entry check
2021-07-26 18:12:44 -05:00
stleary
8680b10716 merge from master to pick up #616 and add one more test 2021-07-26 18:07:38 -05:00
stleary
2559114dbb Merge branch 'master' into fix-similar-check 2021-07-26 17:53:20 -05:00
Sean Leary
bb048e3ffb
Merge pull request #617 from johnjaylward/issue-616-similar-bug
Fixes #616 similar() problem comparing double vs BigDecimal
2021-07-26 17:47:03 -05:00
John Aylward
579784d73e correct error in converting doubles to big decimals 2021-07-22 23:46:31 -04:00
John Aylward
c03054b1a6 Add test to show bug 2021-07-22 22:57:15 -04:00
John Aylward
4e0faebe62 fix javadoc errors that prevent compilation in Eclipse 2021-07-22 22:54:46 -04:00
stleary
c6089e53f5 Fixes Issue #611 JsonArray.similar() returns after number entry check 2021-07-18 19:53:23 -05:00
stleary
cfbc306673 Fixes Issue #611 JsonObject.similar() returns after number entry check 2021-07-18 10:32:49 -05:00
Sean Leary
449ec8745e
Merge pull request #610 from tilds/optJSONObject-defaultValue
New JSONObject.optJSONObject method with defaultValue parameter
2021-06-28 22:01:37 -05:00
Niels Frederiksen
f91d0c8a52 New JSONObject.optJSONObject method with defaultValue parameter 2021-06-23 15:15:00 +02:00
stleary
4571978840 Merge branch 'master' of https://github.com/stleary/JSON-java 2021-06-22 19:46:44 -05:00
stleary
76ec2fe5a2 Revert accidentally changed file 2021-06-22 19:46:33 -05:00
Sean Leary
0200c984cc
Update README.md 2021-06-22 19:41:31 -05:00
stleary
8f3e5ade18 Add logo image 2021-06-22 19:34:22 -05:00
Artem Smotrakov
20b4f85efe
Updated build command in the CodeQL workflow 2021-05-31 15:30:20 +02:00
Artem Smotrakov
5bc8dae5d0
Setup CodeQL scans 2021-05-31 15:24:41 +02:00
Artem Smotrakov
8fa9be742c
Added a security policy 2021-05-31 15:16:27 +02:00
Artem Smotrakov
b48abe6558
Suppress java/unchecked-cast-in-equals warning for JSONObject.Null.equals() 2021-05-31 15:00:29 +02:00
Artem Smotrakov
97023e1098
Fix Javadoc formatting in JSONObject and XMLParserConfiguration 2021-05-31 14:53:59 +02:00
Sean Leary
143db39d27
Merge pull request #604 from ianlovejoy/master
Fixed incorrect cast getting float from array
2021-05-01 08:50:54 -05:00
Ian Lovejoy
75894086e5 Fixed incorrect cast getting float from array
Added test for getting float from array
2021-04-27 19:03:35 -07:00
Sean Leary
fa46da45f4
Merge pull request #601 from AISS-2021-L5-G02/master
Added some examples for new-comers in a Markdown file
2021-04-21 00:31:12 -05:00
TheNeoStormZ
f912e5d1c4
Merge pull request #2 from TheNeoStormZ/master
Changed JSONExamples to a Markdown file (and another place) with mino…
2021-04-02 19:31:42 +02:00
Pablo MarĂ­n GĂłmez
6bf3d38889 Changed JSONExamples to a Markdown file (and another place) with minor tweaks 2021-04-02 19:28:37 +02:00
TheNeoStormZ
c62df81b3e
Merge pull request #1 from TheNeoStormZ/master
Added some examples for new-comers
2021-04-02 11:28:25 +02:00
Pablo MarĂ­n GĂłmez
e1f69ff3fe Added some examples for new-comers 2021-04-02 11:25:57 +02:00
Sean Leary
50d619698f
Merge pull request #594 from anton0xf/patch-1
JSONStringer.java: fix max nesting level in javadoc
2021-03-18 19:42:49 -05:00
anton0xf
29103e3228
JSONStringer.java: fix max nesting level in javadoc 2021-03-14 22:45:38 +05:00
Sean Leary
2630676f36
Update README.md 2021-03-09 19:54:54 -06:00
Sean Leary
7299b201f4
Update pom.xml 2021-03-07 21:11:48 -06:00
Sean Leary
8cc1e9830d
Update README.md 2021-03-07 21:09:01 -06:00
Sean Leary
c43e21ae73
Merge pull request #588 from fossterer/563-jsonpointer-do-not-encode-quotes
JSONPointer should not process reverse solidus or double-quote chars in tokens
2021-03-06 10:00:32 -06:00
Shashank Sabniveesu
d6ccc64c79 Closes 563: As never defined in RFC 6901 Section 3, do not handle backslashes (\) and quotes(") as anything special 2021-02-28 16:03:14 -05:00
Sean Leary
7844eb79cd
Merge pull request #583 from ek08/fix
Checked the length of key for checker framework
2021-02-01 19:48:06 -06:00
Ehtesham
5b531faa49 Improved the logic for checking the length of key 2021-01-28 15:31:23 +05:30
Ehtesham
31ff8a2291 Checked the length of key for checker framework 2021-01-27 11:35:38 +05:30
Sean Leary
e33f463179
Merge pull request #581 from valfirst/patch-1
Use built-in Gradle shorthand notation for Maven Central repository
2021-01-10 18:35:31 -06:00
Valery Yatsynovich
e77a77e841
Use built-in Gradle shorthand notation for Maven Central repository 2020-12-29 14:16:46 +03:00
Sean Leary
26f48484fd
Merge pull request #577 from stranck/master
Added clear() methods to JSONObject and JSONArray
2020-12-07 16:54:18 -06:00
Stranck
efad1d73a7 Added UnitTests
(I hope they works :c)
2020-12-04 04:09:19 +01:00
Stranck
c7130d577a Oops 2020-12-04 01:09:18 +01:00
Stranck
d85eea53bb Update JSONArray.java 2020-12-04 01:07:29 +01:00
Stranck
57ad94ef5e Added clear() methods to JSONObject and JSONArray 2020-12-04 00:49:21 +01:00
Sean Leary
a57eff26d5
Merge pull request #575 from johnjaylward/fix-similar-compare-numbers
Fix similar compare numbers
2020-11-22 15:23:03 -06:00
John J. Aylward
68883b9ff8 update number handling to use new helper method for consistency. 2020-11-19 19:10:08 -05:00
John J. Aylward
11e6b1af7e fixes issue #573 by added specific compare of numeric types 2020-11-19 18:55:49 -05:00
John J. Aylward
e4b76d6588 Add test to demonstrate the issue. See #573 2020-11-19 18:18:27 -05:00
John J. Aylward
3a8193bea4 upgrade junit version 2020-11-19 18:18:02 -05:00
Sean Leary
6bf2692a94
Update README.md 2020-11-15 16:09:50 -06:00
Sean Leary
fdde43cd3b
Update README.md 2020-11-15 12:48:51 -06:00
Sean Leary
6b779f8ca7
Merge pull request #570 from stleary/update-readme
Readme - fix spelling and usage, per Grammarly
2020-10-23 23:05:38 -05:00
stleary
59b7a7adff fix spelling and usage, per Grammarly 2020-10-16 08:58:04 -05:00
Sean Leary
7abd89b4bc
Merge pull request #540 from kumar529/master
Added type conversion support
2020-09-17 07:37:31 -05:00
Rahul Kumar
56d4130a86 Added shallow copy for config map 2020-09-06 11:17:10 +05:30
Rahul Kumar
ed9658d5cb Corrected Javadoc 2020-09-04 16:51:55 +05:30
Rahul Kumar
310f18fcdc Addressed comment 2020-09-03 11:17:10 +05:30
Rahul Kumar
900a8cc945 Removed changes from depricated method 2020-08-06 07:29:32 +05:30
Rahul Kumar
0a8091c954 Added documentation 2020-08-05 22:25:45 +05:30
Rahul Kumar
61c1a882d6 Added configuration support for type conversion using Map 2020-08-03 08:54:59 +05:30
Rahul Kumar
250f74ef4d Added type conversion support 2020-08-03 08:18:20 +05:30
Sean Leary
5541a6d91d
Merge pull request #552 from johnjaylward/JSONArrayCopyConstructor
Updates for JSONArray.putAll methods
2020-08-01 09:19:29 -05:00
John J. Aylward
d30ecad7f8 Update README for best practices when using putAll on JSONArray 2020-07-30 10:13:01 -04:00
John J. Aylward
f35194bc1d Updates the addAll methods to have optional wrapping.
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.
```
2020-07-30 10:10:06 -04:00
John J. Aylward
5d828d2c0b update comments and increase speed of merging JSONArray objects 2020-07-30 10:10:06 -04:00
John J. Aylward
c175a9eb62 remove clone 2020-07-30 10:10:06 -04:00
John J. Aylward
3c9573cc3d update some javadoc 2020-07-30 10:10:06 -04:00
John J. Aylward
f37c2d67c5 Update for JSONArray.putAll methods
* 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
2020-07-30 10:10:06 -04:00
Sean Leary
6351fa63aa
Merge pull request #549 from stleary/rewrite-readme
Update readme.md
2020-07-28 23:48:01 -05:00
Sean Leary
870fa03a19
Merge pull request #529 from ethauvin/master
Added putAll(Collection) and putAll(Array) methods.
2020-07-25 12:45:44 -05:00
Sean Leary
555f712a8c
Update README.md 2020-07-25 12:41:03 -05:00
Sean Leary
db2d1714de
Update README.md 2020-07-25 12:40:41 -05:00
Sean Leary
650f52501a
Update README.md 2020-07-25 12:36:53 -05:00
Sean Leary
896674ae36
Update README.md 2020-07-25 12:35:58 -05:00
Sean Leary
8f0c3b0bf8
Update README.md 2020-07-25 12:35:12 -05:00
Sean Leary
0de8d0d2e0
Update README.md 2020-07-25 12:34:01 -05:00
Sean Leary
46fe58e912
Update README.md 2020-07-25 12:31:20 -05:00
Sean Leary
26cd17687f
Update README.md 2020-07-25 12:31:02 -05:00
stleary
879fba3f7f rewrite - first commit 2020-07-25 12:27:20 -05:00
stleary
98cd8ef8b2 fix CI build error 2020-07-24 03:24:41 -05:00
Sean Leary
78528102d0
Merge pull request #543 from johnjaylward/RefactorXmlConfiguration
Refactor XMLConfiguration to use Builder Pattern
2020-07-24 02:49:28 -05:00
Sean Leary
0e34d8d383
Merge pull request #539 from stleary/unit-tests-1.6
Bring Junit tests to Java 1.6 compatibility
2020-07-24 02:48:38 -05:00
Sean Leary
880402120c
Merge pull request #542 from johnjaylward/fixXmlHexEntityParse
Fix xml hex entity parse
2020-07-23 11:02:14 -05:00
Sean Leary
d10725dc92
Merge pull request #538 from stleary/readme-local-build
Explain local builds in the readme, fix a couple of typos
2020-07-23 11:00:25 -05:00
Erik C. Thauvin
0d13e56064 Added tests for consecutive calls to putAll. 2020-07-21 23:09:28 -07:00
Erik C. Thauvin
f1d354ce7b Increase array list capacity in addAll(collection) method to ensure it can hold additional elements. 2020-07-21 17:35:32 -07:00
Erik C. Thauvin
86e136afc9 Increase array list capacity in addAll method to ensure it can hold additional elements. 2020-07-21 17:11:24 -07:00
John J. Aylward
4f1c8b2d6f formatting 2020-07-21 11:30:35 -04:00
John J. Aylward
5a31f9ef5f Refs #541
Updates XML configuration to use a builder pattern instead of
constructors with many parameters
2020-07-21 11:08:40 -04:00
John J. Aylward
c136668f23 remove new lines from test file text blocks to prevent issues with the
parsing compare on different operating systems
2020-07-20 18:58:00 -04:00
John J. Aylward
e18f42becc fixes #537 corrects case-sensitive entity unescape 2020-07-20 18:38:35 -04:00
John J. Aylward
e0a6c2ef34 refs #537 Show error when unescaping all-caps entity directly 2020-07-20 18:36:52 -04:00
John J. Aylward
c98da43184 Refs #537 Add test cases to verify no issue 2020-07-20 18:25:51 -04:00
John J. Aylward
734f182242 Update error messages to use the built in assertEquals 2020-07-20 18:25:22 -04:00
stleary
c63e78bbc7 initial commit 2020-07-18 17:14:39 -05:00
stleary
db6ca7fbf3 even more formatting 2020-07-18 13:11:13 -05:00
stleary
9a3e7dd7c4 more formatting 2020-07-18 13:08:38 -05:00
stleary
79ff79ed70 initial commit 2020-07-18 13:05:55 -05:00
stleary
d14c7b9127 formatting 2020-07-18 13:02:51 -05:00
stleary
de4395dc5e initial commit 2020-07-18 12:59:34 -05:00
Sean Leary
6ddaa13c1e
Merge pull request #532 from johnjaylward/CheckBigDecimalSupport
Verifies BigDecimal support does not have a regression
2020-06-25 17:02:18 -05:00
John J. Aylward
f9908a6adb adds comment on test case to document why it was added. 2020-06-25 11:51:46 -04:00
John J. Aylward
ba6c4089ea fixes #531
Add test result to confirm that #531 is working in latest version.
2020-06-25 11:42:07 -04:00
Erik C. Thauvin
aa0a5a7245 Added putAll(Collection) and putAll(Array) methods. 2020-06-16 14:55:16 -07:00
Sean Leary
9de97438ac
Merge pull request #524 from viveksacademia4git/i516-JSONArray-ConstructParam-InitCapacity
Development for stleary#516 completed with rebased repository
2020-06-12 10:48:21 -05:00
Sean Leary
601114ee29
Merge pull request #527 from johnjaylward/GithubAction
Fixes for Unit tests and supports GitHub Actions
2020-06-05 18:39:48 -05:00
John J. Aylward
c11c006e88 fix tests to not depend on HashSet key order 2020-06-05 19:09:10 -04:00
John J. Aylward
96bf788515 update pipline to use matrix configuration 2020-06-05 18:55:48 -04:00
viveksacademia4git
f4261add91 Create pipeline.yml 2020-06-05 17:15:55 -04:00
Sean Leary
dced1b4a44
Merge pull request #526 from stleary/broken-unit-tests
comment out some broken unit tests
2020-06-03 21:25:50 -05:00
stleary
cf00d2f265 initial commit 2020-06-03 21:12:19 -05:00
Sean Leary
95c6373122
Merge pull request #525 from johnjaylward/unitTestFixes
Unit test fixes
2020-06-03 19:49:06 -05:00
John J. Aylward
b6ed0d4178 fix failing test case in Java1.7 2020-06-03 19:37:08 -04:00
John J. Aylward
75f656fd07 revert changes to build.gradle 2020-06-03 17:59:04 -04:00
viveksacademia4git
4b84ba2f66 Changes to make the Gradle work
- commented `java() {...}` within build.gradle
- added following files
   1. gradlew
   2. gradlew.bat (for windows)
   3. gradle/wrapper/gradle-wrapper.properties (for ./gradlew command execution)
   4. gradle/wrapper/gradle-wrapper.jar (for ./gradlew command execution)
2020-06-03 12:14:45 -04:00
vivek
d088cf014e Development for stleary#516 completed with rebased repository
- Introduced JSONObject(int) constructor.
   - int > Initial capacity of the underlying data structure

- Test for new introduced JSONArray(int) constructor.
   1. Checked with input parameter: 0
   2. Checked with input parameter: positive number
   3. Checked with positive number input parameter and compared length
   4. If input parameter is negative number JSONException is thrown:
         JSONArray initial capacity cannot be negative.
2020-06-03 11:46:48 +02:00
Sean Leary
19bb6fd606
Merge pull request #453 from johnjaylward/UseBigDecimalDefaultParse
changes number parsing to use BigDecimal as the backing type
2020-06-01 14:03:04 -05:00
Sean Leary
fee6ddb922
Merge pull request #521 from johnjaylward/CookieFlagSupport
Updates Cookie class to be more generic in attribute parsing and emit.
2020-05-29 09:59:27 -05:00
Sean Leary
5a32114792
Unified license for both src and test
All code in the project is covered by the original license
2020-05-27 08:23:09 -05:00
John J. Aylward
56d33b8061 changes number parsing to use BigDecimal as the backing type
* updated tests to support BigDecimal as the backing type for numbers
* updated some test resource handling to java7 try-with-resources format
* cleaned up some other minor compiler warnings
2020-05-26 10:10:36 -04:00
John J. Aylward
6029dece41 ensure key names are consistent when parsing the cookie string since
cookie-keys are not case sensitive, but json-keys are.
2020-05-26 09:11:10 -04:00
John J. Aylward
d334b58f45 Made more corrections to Cookie.ToString.
1. Made Cookie Name and Value properties case insensitive
2. Throws exception on illegal Cookie Name
3. Doesn't emit "false" flag values
4. Properly escape key-value attributes.
2020-05-26 08:55:19 -04:00
John J. Aylward
b4a75c7bf8 Updates Cookie class to be a more generic in attribute parsing and emit.
This is so the library can age better as new attributes are added to RFC
revisions.
2020-05-26 08:53:37 -04:00
Sean Leary
956bdfa5b7
Merge pull request #519 from stleary/gradle-support
Gradle support
2020-05-23 10:20:32 -05:00
stleary
8546e68e20 update readme 2020-05-22 11:44:21 -05:00
stleary
0832d1d873 gradle support 2020-05-22 11:24:20 -05:00
stleary
2b0a8838ef gradle support 2020-05-22 11:17:44 -05:00
Sean Leary
1da2b984cd
Update README.md 2020-05-22 10:50:04 -05:00
Sean Leary
78901383a4
Update README.md 2020-05-22 10:41:55 -05:00
Sean Leary
3737c987a2
Merge pull request #515 from BGehrels/merge-tests-and-pom-and-code
Merge tests and pom and code
2020-05-22 10:40:48 -05:00
Sean Leary
8e5b516f2b
Update README.md 2020-05-17 22:41:27 -05:00
Benjamin Gehrels
82202dbf65 Added Jar plugin version to get rid of a warning 2020-04-30 12:23:39 +02:00
Benjamin Gehrels
89d4681e41
Added information on how to release to the pom 2020-04-29 21:02:52 +02:00
Benjamin Gehrels
1265897f4e Merge remote-tracking branch 'tests/master' into upstream 2020-04-29 20:26:05 +02:00
Benjamin Gehrels
74e4932cfc Transform the repository into standard maven format and merge the pom.xml of the release repo 2020-04-29 19:24:44 +02:00
Sean Leary
f07ddd93e5
Merge pull request #96 from Alanscut/bean-test
improve the confused assert message
2019-12-30 12:31:58 -06:00
Alan Wang
08719d4b3a
Apply suggestions from code review
Co-Authored-By: Sean Leary <stleary@gmail.com>
2019-12-30 09:51:08 +08:00
Alanscut
16da56eb34 improve the confused assert message 2019-12-28 17:53:27 +08:00
Sean Leary
6b6e8e85d8
Merge pull request #502 from Alanscut/issue-500
update JSONTokener's brief: parse simple json text
2019-12-26 20:56:51 -06:00
Alanscut
6ecbeaa0d2 update JSONTokener's brief: parse simple json text 2019-12-25 11:38:38 +08:00
Sean Leary
3ac647a16f
Merge pull request #499 from Alanscut/copyright
Add copyright notice to JSONString, JSONException.
2019-12-23 08:31:01 -06:00
Alanscut
6f06801296 add copyright 2019-12-22 19:17:58 +08:00
Sean Leary
dd7056cb6d
Merge pull request #495 from harkue/master
fix typo
2019-11-20 11:20:18 -06:00
harkue
e62d763294 rename hasComma as a better name "needsComma" 2019-11-13 11:46:21 +08:00
harkue
4990c3a180 fix typo 2019-11-12 16:27:24 +08:00
Sean Leary
4b49bc94ce
Merge pull request #494 from spaffrath/replace_string_arrays_with_var_args
Replace JSONObject constructor string arrays with var args
2019-11-06 09:31:23 -06:00
Sean Leary
9afa90d9a9
Merge pull request #492 from ggavriilidis/ISSUE-491_clarify_intention_of_JSONArray_toList
Issue-491 - Clarify what the output of the method JSONArray toList is
2019-10-29 22:24:45 -05:00
gavriil
065f9a94bc Issue-491 - modified the comment of JSONArray toList method to clarify what the output of the method is 2019-10-29 21:35:58 +00:00
scott
223e328161 Replace JSONObject constructor string arrays with var args 2019-10-16 21:12:02 -07:00
Sean Leary
18eddf75c3
Merge pull request #95 from johnjaylward/StandardizeExceptionMessages
Test cases updates for standardized exception messages
2019-09-24 20:30:08 -05:00
Sean Leary
044b035847
Merge pull request #486 from johnjaylward/StandardizeExceptionMessages
Standardize Exception Messages
2019-09-24 20:29:17 -05:00
Sean Leary
b8fd9d0082
Merge pull request #94 from johnjaylward/FixMLInfiniteLoop
new test case for issue 484
2019-09-23 17:57:16 -05:00
Sean Leary
5b62cf13ff
Merge pull request #485 from johnjaylward/FixMLInfiniteLoop
Fix for #484
2019-09-23 17:56:53 -05:00
John J. Aylward
a24db2cce2 remove unused import 2019-09-17 11:15:25 -04:00
John J. Aylward
67e59888a2 add second case for data in #484 2019-09-17 11:14:41 -04:00
John J. Aylward
e9c27ab376 standardize exception messages 2019-09-17 11:08:26 -04:00
John J. Aylward
fb01575394 Test cases updates for standardized exception messages 2019-09-17 10:47:16 -04:00
John J. Aylward
3e7a0b13d1 new test case for issue 484 2019-09-17 10:36:48 -04:00
John J. Aylward
328e7d8944 corrects EOL error when the Meta tag isn't closed properly and we reach
the end of the input.
2019-09-17 10:33:26 -04:00
Sean Leary
2a6af29235
Merge pull request #483 from viniciusls/patch-1
Update README.md to point to latest version
2019-09-07 09:01:19 -05:00
VinĂ­cius Silva
af6d3c63bd
Update README.md to point to latest version
Update **Click here if you just want the latest release jar file** on README.md to point to latest version available on Maven Central.
2019-09-06 12:45:41 -03:00
Sean Leary
c3ea0249c9
Merge pull request #481 from johnjaylward/ClarifyParserExceptionsInReadMe
clarifies exception that the parser makes when reading JSON
2019-08-14 11:27:40 -05:00
John J. Aylward
b044b7db4d clarifies exception that the parser makes when reading JSON 2019-08-14 11:47:49 -04:00
Sean Leary
115f8b660b
Merge pull request #475 from gaul/static-methods
Make private methods static where possible
2019-08-04 11:18:29 -05:00
Andrew Gaul
f63d21fd13 Make private methods static where possible
This avoids an unneeded object reference.  Found via error-prone.
2019-07-26 15:24:05 -07:00
Sean Leary
c8ae720caf
Merge pull request #474 from gaul/stringbuilder
Prefer unsynchronized StringBuilder
2019-07-26 16:07:31 -05:00
Andrew Gaul
4d451468fd Prefer unsynchronized StringBuilder
StringBuffer provides unneeded synchronization.  Found via
error-prone.
2019-07-22 22:26:49 -07:00
Sean Leary
a03a01531a
Update README.md 2019-07-22 20:33:02 -05:00
Sean Leary
5b845f28cf
Update README.md
New RFC8259, no changes to in-doc references.
2019-05-08 20:27:25 -05:00
Sean Leary
6dcd82a72f
Merge pull request #93 from meiskalt7/xsiNilToNull
add test for xsi:nil to null conversion
2019-04-22 08:34:15 -05:00
Sean Leary
00e0e6c0a2
Merge pull request #467 from meiskalt7/addConfigurationForXsiNilConversionToNull
add configuration for xsi:nil="true" conversion to null
2019-04-22 08:33:16 -05:00
meiskalt7
fa173fa51a add test for xsi:nil to null conversion disabled 2019-04-21 00:53:39 +07:00
meiskalt7
614e8359b9 add test for xsi:nil to null conversion 2019-04-18 21:42:57 +07:00
meiskalt7
d5b278539e add configuration for xsi:nil="true" conversion to null 2019-04-09 19:49:32 +07:00
Sean Leary
437ce10ee3
Merge pull request #91 from johnjaylward/FixEOF
Tests for https://github.com/stleary/JSON-java/pull/452
2018-12-13 09:14:39 -06:00
Sean Leary
12bbe8cd9a
Merge pull request #452 from johnjaylward/FixEOF
Adds check for EOF
2018-12-13 09:14:10 -06:00
Sean Leary
cfec288fe8
Merge pull request #90 from stleary/tests-for-xml-config
xml parser config tests
2018-12-11 07:27:04 -06:00
Sean Leary
09dddb826e
Merge pull request #412 from johnjaylward/XmlConfig
Initial implementation of XMLParserConfig object for flexible XML Parsing
2018-12-11 07:26:50 -06:00
John J. Aylward
19e9bb6c07 Adds check for EOF 2018-12-10 11:45:53 -05:00
John J. Aylward
e7f7d348cd * updates tests to cover more cases of tokenizing
* uncomments tests that should now work
2018-12-10 11:45:10 -05:00
Sean Leary
e699abb1c6
Merge pull request #61 from johnjaylward/XmlEscape
Test cases Xml escapes
2018-12-08 20:09:03 -06:00
Sean Leary
fea0aca2ab
Update README.md 2018-12-08 19:54:06 -06:00
stleary
d0ea807884 xml parser config tests 2018-12-08 14:51:01 -06:00
Sean Leary
0d053a000d
Merge pull request #89 from stleary/update-timeNumberParsing-iterations
reduce number of iterations to shorten test time
2018-12-08 11:31:38 -06:00
stleary
e4186e072a reduce number of iterations to shorten test time 2018-12-08 11:29:44 -06:00
Sean Leary
4c64ad3d8a
Merge pull request #88 from johnjaylward/FixForBigDecimal
Updated testcases for PR440
2018-10-06 14:52:13 -05:00
Sean Leary
1a811f1ada
Merge pull request #440 from johnjaylward/FixForBigDecimal
Fixes #438 - Corrections to BigDecimal consistency
2018-10-06 14:51:57 -05:00
John J. Aylward
3e6c0a51bd update expected exception text in tests to match unified number getters 2018-10-04 16:02:50 -04:00
John J. Aylward
34cfe6df14 removes duplicate code in number getters 2018-10-04 16:02:14 -04:00
John J. Aylward
71c6dd1e34 remove unneeded casts 2018-10-02 15:33:33 -04:00
John J. Aylward
30c1bd16ba fix javadoc 2018-10-02 15:28:53 -04:00
John J. Aylward
bc347d2c19 cleanup of minor warnings 2018-10-02 15:28:24 -04:00
John J. Aylward
a63fa03062 * Fixes opt/getBigDecimal to be consistent
* Performance: Updates JSONWriter to use a regex to decide if writing as a number is best.
2018-10-02 15:28:24 -04:00
John J. Aylward
3b8b0a681c Update test cases to verify performance change and verify opt/getBigDecimal match 2018-10-02 12:38:17 -04:00
Sean Leary
16225efbdd
Merge pull request #432 from johnjaylward/patch-2
Update README.md
2018-08-15 08:32:32 -05:00
johnjaylward
b8a3342eb1
Update README.md
update maven search example.
2018-08-15 09:18:14 -04:00
Sean Leary
37f5bf28e9
Update README.md 2018-08-13 20:46:20 -05:00
Sean Leary
7a17ae0b3e
Merge pull request #421 from strkkk/add-emptiness-methods
add isEmpty and isNotEmpty methods
2018-05-26 09:56:23 -05:00
Sean Leary
dedb044f67
Merge pull request #86 from strkkk/add-isEmpty-method-usage
add usage of isEmpty method
2018-05-26 09:55:41 -05:00
Andrei Paikin
d00501eabd add usage of isEmpty method 2018-05-25 22:47:05 +03:00
Andrei Paikin
7cad4c3b26 partially revert changes 2018-05-25 22:17:03 +03:00
Andrei_Paikin
05074386d3 change length comparison to isEmpty method 2018-05-21 16:58:13 +03:00
Andrei Paikin
a490ebdb78 add isEmpty and isNotEmpty methods 2018-05-19 09:42:21 +03:00
Sean Leary
3c1535d724
Merge pull request #417 from stleary/fix-double-ctor
fix double ctor in JSONWriter
2018-05-16 08:46:01 -05:00
stleary
a6284df9c7 initial commit 2018-05-02 20:28:45 -05:00
Sean Leary
20d90bfb0b
Merge pull request #85 from johnjaylward/JSONPointerTrailingSlash
Test cases for issue described in Issue 410
2018-03-27 07:45:17 -05:00
Sean Leary
bfb300835f
Merge pull request #411 from johnjaylward/JSONPointerTrailingSlash
Fix for invalid processing of trailing / for JSON Pointer
2018-03-27 07:44:48 -05:00
John J. Aylward
ca9df04539 Initial implementation of XMLParserConfig object for more flexible XML parsing 2018-03-21 22:09:46 -04:00
John J. Aylward
3fe4a767e6 Fixes incorrect syntax for JSONPointer in test. 2018-03-20 22:15:25 -04:00
Sean Leary
06e9ad280f
Merge pull request #403 from paulpolushkin/idea-fix
ignore Intellij Idea project files
2018-03-19 19:10:29 -05:00
John J. Aylward
2362c930d1 Fixes #410. Invalid processing of trailing / for JSON Pointer 2018-03-19 09:57:06 -04:00
John J. Aylward
43f3f5e80b Add another test 2018-03-19 09:49:42 -04:00
John J. Aylward
f4201cf318 Test cases for issue described in https://github.com/stleary/JSON-java/issues/410. 2018-03-19 09:34:13 -04:00
Sean Leary
770cb9c4e5
Merge pull request #84 from johnjaylward/FixBeanKeyNameing
New test cases for Bean Name customization
2018-03-14 21:19:11 -05:00
Sean Leary
2a6b5bacc5
Merge pull request #406 from johnjaylward/FixBeanKeyNameing
Adds annotations to customize field names during Bean serialization
2018-03-14 21:18:23 -05:00
John J. Aylward
a509a28ed4 Cleans up the name check a little to be more permissive on what can be tagged with the new JSONPropertyName annotation.
Also updates the javadoc to reflect the new name allowances
2018-03-11 17:22:05 -04:00
Sean Leary
37f1f4c8ca
Merge pull request #83 from johnjaylward/FixNPE
add test cases for null keys
2018-03-11 15:59:21 -05:00
Sean Leary
1c1ef5b211
Merge pull request #405 from johnjaylward/FixNPE
Updates javadoc to match actual exceptions thrown.
2018-03-11 15:57:23 -05:00
John J. Aylward
193a3823b5 new test cases to support bean annotation 2018-03-11 16:56:07 -04:00
John J. Aylward
74b9a60f98 Adds annotation to support custom field names during Bean serialization 2018-03-11 16:28:24 -04:00
John J. Aylward
b63b976acb Updates javadoc to match actual exceptions thrown.
Also optimizes some boxing statements and returns.
2018-03-07 12:35:56 -05:00
John J. Aylward
aa5e80bc8d add test cases for null keys 2018-03-07 12:11:17 -05:00
Pavel Polushkin
97e180444d ignore Intellij Idea project files 2018-02-25 13:08:58 +03:00
Sean Leary
d402a99fd8
Merge pull request #400 from foldvari/master
XML toJSONObject(Reader reader)
2018-02-10 11:09:26 -06:00
György Földvári
7073bc8c47 XML toJSONObject(Readre reader) 2018-02-04 18:43:35 +01:00
Sean Leary
fc881e2631
Merge pull request #82 from billdeng/master
Correct the message to match the function
2018-02-02 23:56:36 -06:00
dengjianbao
cc2ed79e57 Correct the message to match the function 2018-02-02 22:54:08 +08:00
Sean Leary
61cdfefc36
Update README.md 2018-01-30 19:46:24 -06:00
Sean Leary
fbad2d0017
Merge pull request #392 from philippgille/patch-1
Remove wrong apostrophe
2018-01-20 03:39:07 -06:00
Philipp Gillé
15719886f7
Remove wrong apostrophe 2018-01-17 18:41:48 +01:00
Sean Leary
ca45b02ffc
Merge pull request #381 from fleipold/maven-badge
Adding maven badge to readme
2018-01-14 10:18:46 -06:00
Felix Leipold
b6efbabc32 Making links markdown links 2017-11-17 12:47:49 +01:00
Felix Leipold
9eb8c27724 Marking up class and method names as inline code 2017-11-17 12:33:50 +01:00
Felix Leipold
195963357c Make file names bold 2017-11-17 12:24:17 +01:00
Felix Leipold
28efdb4860 Moving Badge below title 2017-11-17 12:24:03 +01:00
Felix Leipold
c88653ca2e History with fixed font 2017-11-14 17:23:53 +01:00
Felix Leipold
b3068d9fe4 Marking file and class names with single quotes 2017-11-14 17:23:52 +01:00
Felix Leipold
dba4afd0cf Adding maven repo badge 2017-11-14 17:23:36 +01:00
Felix Leipold
26160e1619 Remove trailing whitespace 2017-11-14 17:23:36 +01:00
Felix Leipold
b7e2eee4d6 Renaming README to README.md 2017-11-14 17:23:36 +01:00
Sean Leary
77d142d494
Merge pull request #81 from johnjaylward/FixFalsePositiveSimilar
Test cases to verify Similar methods
2017-11-11 16:12:26 -06:00
Sean Leary
28e09dc493
Merge pull request #380 from johnjaylward/FixFalsePositiveSimilar
Fix for false positives in similar functions
2017-11-11 16:12:06 -06:00
John J. Aylward
dae88d7c5c fix method names 2017-11-06 10:35:49 -05:00
John J. Aylward
4a4b2db8c1 fix for issue #379 2017-11-06 10:28:28 -05:00
John J. Aylward
08d93f3eb5 test cases for issue https://github.com/stleary/JSON-java/issues/379 2017-11-06 10:27:45 -05:00
Sean Leary
f16682bf44
Merge pull request #375 from johnjaylward/FixExceptionWrapping
fixes wrapped exceptions
2017-11-02 21:42:29 -05:00
John J. Aylward
18952b5ac0 fixes wrapped exceptions 2017-11-02 22:32:24 -04:00
Sean Leary
bf26eba0d2
Merge pull request #80 from johnjaylward/UnclosedJSONArray
New test to verify unclosed array
2017-11-02 20:03:00 -05:00
Sean Leary
d2a66a4287
Merge pull request #373 from johnjaylward/UnclosedJSONArray
Fixes Unclosed json array stack overflow
2017-11-02 20:02:26 -05:00
Sean Leary
722003d479
Merge pull request #350 from johnjaylward/AndroidSupport
Updates for supporting the Android API
2017-10-30 11:33:10 -05:00
Sean Leary
936db93445
Update README.md 2017-10-30 08:46:43 -05:00
Sean Leary
e0801befe5
Update README.md 2017-10-30 08:45:41 -05:00
Sean Leary
ee3aa03da1
Update README.md 2017-10-30 08:44:21 -05:00
Sean Leary
578a442ef7
Update README.md 2017-10-30 08:43:56 -05:00
John J. Aylward
dfa37a298f Add more tests for unclosed arrays 2017-10-30 08:53:50 -04:00
John J. Aylward
bde6ba1c52 Updates exception expected message 2017-10-30 08:53:50 -04:00
John J. Aylward
52ecc89702 New test to verify unclosed array 2017-10-30 08:53:50 -04:00
John J. Aylward
ed8745cd63 fixes #372.
Corrects behavior of unclosed arrays
2017-10-30 08:18:59 -04:00
John J. Aylward
057e0c75ca Merge remote-tracking branch 'origin/master' into AndroidSupport 2017-10-27 13:28:20 -04:00
Sean Leary
cdf3cf7f81 Update README 2017-10-17 20:05:29 -05:00
Sean Leary
af3b7dc443 Merge pull request #79 from johnjaylward/FixXMLUnescape
New tests for XML unescaping
2017-08-27 10:59:36 -05:00
Sean Leary
2565abdaaa Merge pull request #362 from johnjaylward/FixXMLUnescape
Fixes XML Unescaping
2017-08-27 10:59:26 -05:00
John J. Aylward
2713f2e2a4 Adds testing for unicode entities 2017-08-19 18:45:53 -04:00
John J. Aylward
de855c50aa Fixes #361.
* Removes unescape from the XML class calls
* fixes bug with unescape method
* moves unescape logic into the XMLTokener class for more consistency
2017-08-19 18:23:07 -04:00
John J. Aylward
cb61bbf720 New tests for XML unescaping 2017-08-19 18:19:22 -04:00
Sean Leary
4cb1ae802a Merge pull request #360 from migueltt/tokener-fix
Creating a JSONObject from a string that contains a duplicate key (any level) throws a JSONException that includes location
2017-08-17 21:30:01 -05:00
Sean Leary
d0e2cf41a3 Merge pull request #78 from migueltt/tokener-error-message
Unit tests for constructor JSONObject(JSONTokener)
2017-08-17 21:29:13 -05:00
Miguel
b90bee0f22 Update error message location (+1)
`JSONTokener.back()` call removed from `JSONObject(JSONTokener)` constructor.
2017-08-14 13:05:23 -04:00
Miguel
2e0a8137bd Removed JSONTokener.back() 2017-08-14 13:01:31 -04:00
Miguel
f177c97258 Replacing tabs with 4-spaces 2017-08-10 19:12:41 -04:00
Miguel
68b262914d JSONObject(JSONTokener) now points to last character of duplicate key
Updating exception message accordingly (position -1)
2017-08-10 19:06:55 -04:00
Miguel
7d8353401a Adding JSONTokener.back() just before throwing JSONException
This forces JSONTokener.syntaxError(..) to point to the last character of the duplicate key.
2017-08-10 19:05:57 -04:00
Miguel
c365e2a774 Remov slf4j reference 2017-08-09 22:03:09 -04:00
Miguel
df466db7b9 Replacing tabs with 4 spaces 2017-08-09 21:59:08 -04:00
Miguel
1acb18091a Remove System.out.println 2017-08-09 21:57:10 -04:00
Miguel
7fed023080 Update to include error location when creating JSONObject from string/text 2017-08-09 21:52:36 -04:00
Miguel
fefd616d73 Unit tests for JSONTokener 2017-08-09 21:51:46 -04:00
Sean Leary
44c3e321b5 Merge pull request #77 from johnjaylward/FixJUnitGradleConfig
Fixes Gradle config so tests are only run once
2017-07-20 06:51:14 -05:00
John J. Aylward
f2f6ad3b1f * Fixes Gradle config so tests are only run once
* Adds missing test to the test suite
2017-07-19 20:34:59 -04:00
Sean Leary
cf411b3187 Merge pull request #75 from johnjaylward/PopulateMapMoreStrict
Populate map more strict
2017-07-19 18:57:55 -05:00
Sean Leary
d9b8507e6a Merge pull request #354 from johnjaylward/PopulateMapMoreStrict
Updates for populateMap based on discussion in #279 and #264
2017-07-19 18:57:32 -05:00
Sean Leary
d345bc528e Merge pull request #357 from johnjaylward/WriteJavadocUpdate
Update javadoc according to issue #356.
2017-07-15 18:51:18 -05:00
Sean Leary
1aeadd1765 Merge pull request #76 from johnjaylward/WriteJavadocUpdate
Update test for issue https://github.com/stleary/JSON-java/issues/356
2017-07-15 18:46:58 -05:00
John J. Aylward
aa562b5ec3 Update test for issue https://github.com/stleary/JSON-java/issues/356 2017-07-15 12:19:02 -04:00
John J. Aylward
6f238a3698 Update javadoc according to issue #356. 2017-07-15 12:17:27 -04:00
John J. Aylward
38d11227ee Adds exception tests 2017-07-09 19:05:00 -04:00
John J. Aylward
4dbc5ef803 fixes malformed javadoc 2017-07-09 18:48:40 -04:00
John J. Aylward
5c80c9157d fixes malformed javadoc 2017-07-09 18:47:09 -04:00
John J. Aylward
e94783f91b Updates javadocs 2017-07-09 18:19:27 -04:00
John J. Aylward
7bc8f41023 Add override of the generic getter to generate a Bridge method. 2017-07-09 18:10:09 -04:00
John J. Aylward
a129ebe8e4 Adds check for resources opened by our bean mapping 2017-07-09 18:09:14 -04:00
John J. Aylward
49117f33dc Adds new tests for testing bean->JSONObject mapping 2017-07-09 17:57:46 -04:00
John J. Aylward
0e3f23d7a1 reorganize classes so test data is separate from test cases 2017-07-09 16:48:01 -04:00
John J. Aylward
641b68dd55 updates javadoc. 2017-07-07 21:33:46 -04:00
John J. Aylward
643b25140f Updates for populateMap based on discussion in #279 and #264 2017-07-07 20:48:42 -04:00
John J. Aylward
3997a90d58 update constructor call to match Android implementation 2017-07-07 12:24:27 -04:00
John J. Aylward
1736a60ffe adds comment for the API change 2017-07-07 12:17:45 -04:00
John J. Aylward
e8b1b66888 Updates for supporting the Android API 2017-07-07 12:17:39 -04:00
Sean Leary
974a5f7d5d Merge pull request #74 from johnjaylward/AndroidSupport
Correct expected position information in error messages
2017-07-06 18:08:20 -05:00
Sean Leary
5024f2d210 Merge pull request #352 from johnjaylward/ErrorMessagePositionFixes
Error message position fixes
2017-07-06 18:07:50 -05:00
John J. Aylward
16baa323cf adds comments 2017-07-03 13:03:02 -04:00
John J. Aylward
52845366bd Fixes more position errors from stepping to new lines and then back. 2017-07-03 13:03:02 -04:00
John J. Aylward
899cf528df More test cases for position information 2017-06-24 13:10:14 -04:00
John J. Aylward
47ff774f5c Updates test coverage table 2017-06-23 23:55:22 -04:00
John J. Aylward
af39376d92 more fixes for testing postition information 2017-06-23 23:25:11 -04:00
John J. Aylward
e7e6ed9205 Fixes position reports on errors 2017-06-23 13:40:41 -04:00
John J. Aylward
0e612ba8a4 More test corrections for correct position reports in error messages 2017-06-21 19:56:00 -04:00
John J. Aylward
971614ac8b fix expected exception message 2017-06-21 18:28:04 -04:00
John J. Aylward
3081b4bd96 Fixes for failing tests due to android integration 2017-06-21 14:59:42 -04:00
Sean Leary
1add1247fa Merge pull request #348 from johnjaylward/ArrayPerformance
Capacity improvements for internal structures
2017-06-12 02:05:26 -05:00
Sean Leary
5b2e5e7579 Merge pull request #347 from ttulka/master
a comment added to explain the use of HashMap
2017-06-11 23:32:06 -05:00
Sean Leary
441fec7498 Merge pull request #73 from johnjaylward/BetterErrorHandling
Updates tests for better error handling changes
2017-06-11 14:12:56 -05:00
Sean Leary
c9ae1f17d7 Merge pull request #345 from johnjaylward/BetterErrorHandling
Adds JSONException for write value errors
2017-06-11 14:12:48 -05:00
Tomas Tulka
246350bbcd comment added to explain the reason that JSON object is unordered
to avoid implementators' misconceptions and tries to reimplement the
JSON object to keep the elements order
2017-06-09 09:00:17 +02:00
John J. Aylward
2fbe4d96cf change JSONObject(Map) constructor to use the default capacity when a null map is passed 2017-06-08 12:18:04 -04:00
John J. Aylward
3645f91b55 change JSONArray(Collection) constructor to use the default capacity when a null collection is passed 2017-06-08 12:15:03 -04:00
John J. Aylward
9c092753b0 * Updates array constructor and bulk operations to best guess capacity information
* Update JSONObject to allow best guess for initial capacity.
2017-06-08 11:22:23 -04:00
John J. Aylward
c5e4b91fa4 Updates tests for better error handling changes 2017-06-08 02:25:59 -04:00
Tomas Tulka
d0f5607998 a comment added to explain the use of HashMap
to avoid misconception of contributors about using HashMap to implement
a JSON object as a unordered collection by the definition
2017-06-08 08:03:14 +02:00
John J. Aylward
ad6bdd715d Adds JSONException for write value errors so serialization errors can be tracked easier 2017-06-05 20:51:57 -04:00
Sean Leary
ef7a5e40be Merge pull request #341 from johnjaylward/OptimizeLoops
Sorry for the late merge, somehow lost track of this pull request.
2017-05-31 20:51:20 -05:00
John J. Aylward
237bf0adb6 more comments 2017-05-31 18:31:02 -04:00
John J. Aylward
f76fbe7005 fixes comments 2017-05-31 18:13:40 -04:00
John J. Aylward
4f5bf16676 * Adds protected entrySet accessor to JSONObject
* Updates loops that request key/value pairs to use the new entrySet accessor
2017-05-23 12:48:44 -04:00
Sean Leary
93ca7b176f Merge pull request #71 from johnjaylward/OptimizeOpt
Adjustments to tests for https://github.com/stleary/JSON-java/pull/337
2017-05-22 22:59:37 -05:00
Sean Leary
fbd2be7431 Merge pull request #337 from johnjaylward/OptimizeOpt
Optimizes opt* functions
2017-05-22 22:59:04 -05:00
John J. Aylward
757b6edb03 Merge branch 'master' of github.com:stleary/JSON-java into OptimizeOpt 2017-05-21 13:12:24 -04:00
Sean Leary
f5d3086c55 Merge pull request #70 from johnjaylward/fixSpelling
test support for Numeric enhancements, Refactoring, Fix spelling:  stleary/JSON-java/pull/336
2017-05-20 12:37:58 -05:00
Sean Leary
f2b642a1ca Merge pull request #336 from johnjaylward/fixSpelling
Numeric enhancements, Refactoring, Fix spelling
2017-05-20 12:37:31 -05:00
John J. Aylward
04d76b638b split out tests for better readability 2017-05-19 15:01:37 -04:00
John J. Aylward
04d6e83fc2 * Missed JSONArray optFloat and optDouble for the revert
* prevents erasure of stack trace for rethrown exceptions
2017-05-19 09:49:22 -04:00
John J. Aylward
849b392c01 updates the getNumber/optNumber to not return invalid Doubles 2017-05-18 19:49:50 -04:00
John J. Aylward
a7f8ff24df correct string check for JSONObject optBigDecimal and optBigInteger 2017-05-18 14:41:42 -04:00
John J. Aylward
cfe6851d8c Adds testing for -0 with optNumber 2017-05-18 14:25:42 -04:00
John J. Aylward
1ab5260a7a * Adds methods getNUmber and getFloat to JSONArray and JSONObject
* Extracts the stringToNumber logic that the optNumber method uses to reuse it between classes
* Fixes -0 issue with optNumber/getNumber
2017-05-18 14:24:34 -04:00
John J. Aylward
c28a2bdf39 * reverts changes to getDouble and related optDouble and optFloat
* Updates optNumber to be smarter about which object it uses to parse strings
2017-05-18 13:07:32 -04:00
John J. Aylward
1967bee236 expands the coercion tests a little more 2017-05-18 12:11:43 -04:00
John J. Aylward
0150639119 update the new coercion test to use actual values and show the parseDouble method is not robust enough for large numbers 2017-05-18 11:58:28 -04:00
John J. Aylward
382f62e781 * Prevent exceptions in cases where the value is not a string.
* Don't call toString when we know it's a string, just cast
2017-05-18 11:41:51 -04:00
John J. Aylward
bdb1163445 Adds conversion tests to ensure downward type coercions are handled sanely 2017-05-18 11:38:42 -04:00
John J. Aylward
2867aaa8c8 Updates test cases to support new optFloat and optNumber 2017-05-17 12:33:59 -04:00
John J. Aylward
0c7bd725a6 fixes for javadoc 2017-05-17 11:34:37 -04:00
John J. Aylward
fcdb8671b2 grr, forgot to save changes on last commit 2017-05-17 11:32:44 -04:00
John J. Aylward
c46774cf13 * Update opt* methods for JSONArray
* Add support to JSONArray and JSONObject to optionally get raw number values
* Add support to JSONArray and JSONObject to optionally get float values
2017-05-17 11:29:26 -04:00
John J. Aylward
bd4b180f4e Support for float to BigDecimal in optBigDecimal 2017-05-17 10:51:06 -04:00
John J. Aylward
49d47e3ff2 Adjustments to tests for https://github.com/stleary/JSON-java/pull/337/ 2017-05-16 19:42:46 -04:00
John J. Aylward
a8d4e4734f adjustments to opt methods in reference to https://github.com/stleary/JSON-java/issues/334 2017-05-16 19:38:01 -04:00
John J. Aylward
1d040ec407 fixes errors with tests relating to https://github.com/stleary/JSON-java/pull/336 2017-05-16 18:16:07 -04:00
John J. Aylward
4865f51dd5 change float double literals to be more standard as 1.0f and 1.0d respectively 2017-05-16 15:38:54 -04:00
John J. Aylward
c870094f69 Fixes spelling in comments and removes compile time warnings 2017-05-16 15:35:05 -04:00
Sean Leary
cbd8b18c4a Update README 2017-05-16 00:29:00 -05:00
Sean Leary
c945b53308 Merge pull request #69 from johnjaylward/TestCleanup
Couple of the files were difficult to identify the changes, but it was worth it to add the new tests. Thanks!!!
2017-04-28 01:04:56 -05:00
John J. Aylward
c233ae709e comment out second unreliable test 2017-04-27 12:52:02 -04:00
John J. Aylward
95da4246a2 fix spelling in comment 2017-04-27 12:48:43 -04:00
John J. Aylward
9df5d34bbe * Update link in the README to the main JSON-Java repo
* Cleans up some warnings
* Adds new test for bug https://github.com/stleary/JSON-java/issues/332
* Adds some resource handling for string writers using pre-java1.7
support. I know StringWriters don't need a close method called, but the
tests should still handle their resources properly.
2017-04-27 12:39:42 -04:00
Sean Leary
f12fa9ba5f Update LICENSE 2017-04-18 08:32:10 -05:00
John J. Aylward
ae1e9e2b6a fix spelling in javadoc comment 2017-04-03 11:59:36 -04:00
Sean Leary
f6ab6d7b27 Merge pull request #68 from stleary/jsonpointer-query
unit tests for query-by-JSONPointer
2017-03-27 20:05:05 -05:00
Sean Leary
80e2ea2a80 Merge pull request #324 from dtalex/JSONPointerOnBeans
Allow user to invoke query and optQuery ,with a JSONPointer
2017-03-27 20:04:18 -05:00
stleary
d1a5f15f0c unit tests for query-by-JSONPointer 2017-03-26 15:03:09 -05:00
Sean Leary
82ff14ed8d Merge pull request #66 from stleary/document-unquoted-strings
add a test for unquoted values
2017-02-26 11:10:38 -06:00
stleary
e41972a574 add a test for unquoted values 2017-02-26 11:09:41 -06:00
alessandro rao
2917104b53 Allow user to invoke query and optQuery ,with a JSONPointer,directly
from JSONArray or JSONObject fix JSONArray
2017-02-25 14:35:02 +01:00
alessandro rao
9e0fc5e680 Allow user to invoke query and optQuery ,with a JSONPointer,directly
from JSONArray or JSONObject
2017-02-25 13:27:50 +01:00
Sean Leary
a66abf22a8 Merge pull request #64 from stleary/locale-tests-for-non-EN-keys
Locale tests for non en keys
2017-02-19 21:34:40 -06:00
Sean Leary
724fb888f7 Merge pull request #317 from johnjaylward/fixLocale
make sure locale independent data is not upper/lowercased incorrectly…
2017-02-19 21:34:17 -06:00
stleary
f41e1d012a tests for locale-independent keys 2017-02-16 20:49:37 -06:00
stleary
928179a1f3 locale tests 2017-02-14 08:30:22 -06:00
John J. Aylward
eb806f4c14 make sure locale independent data is not upper/lowercased incorrectly. See #315 2017-02-10 10:07:28 -05:00
Sean Leary
5ff8b4cb08 Merge pull request #304 from omarzina/master
[FIX] Update README
2016-12-05 08:58:35 -06:00
joumar
5ef4f58ef1 [FIX] Update README
Fixed C&P typo
2016-12-05 11:55:24 -03:00
Sean Leary
413bb53b48 Merge pull request #288 from johnjaylward/XmlEscape
Bug fixes for XML Encoding and Decoding
2016-11-24 10:01:14 -06:00
Sean Leary
df9c27c53f Merge pull request #62 from erosb/master
testcase for stleary/JSON-java#292
2016-10-08 10:07:53 -05:00
Sean Leary
237376eca6 Merge pull request #292 from erosb/master
Provides "#" string evaluation support for JSON Pointer
2016-10-08 10:07:31 -05:00
Bence Erős
97e3d6c7ce testcase for stleary/JSON-java#292 and adding .idea to .gitiignore 2016-10-05 14:59:36 +02:00
Bence Erős
e0616a129e fixing #291 2016-10-05 14:57:42 +02:00
John J. Aylward
93ffca36c3 fixes spacing 2016-09-28 20:23:30 -04:00
John J. Aylward
e477d7002b fixes object comparison 2016-09-28 20:22:12 -04:00
John J. Aylward
fb1db9341e Changes encoding to better match the XML spec section 2.2 2016-09-28 20:15:58 -04:00
John J. Aylward
adb0478f66 properly unescape tokens in JSONML for reversability. 2016-09-22 16:23:09 -04:00
John J. Aylward
f6a00e94c7 adds test for unicode that has surrogate pairs 2016-09-22 16:12:00 -04:00
John J. Aylward
f58a0f4684 fixes code point appends to string builder 2016-09-22 16:10:49 -04:00
John J. Aylward
c11e09959c Fixes code point output when unescaping code points. XML escapes are an entire code point, not surrogate pairs like in JSON. 2016-09-22 15:40:26 -04:00
John J. Aylward
68f92eb395 Adds more javadoc. 2016-09-22 14:40:39 -04:00
John J. Aylward
2b87f334d0 Update test cases to support ISO Control encoding changes. 2016-09-22 14:13:48 -04:00
John J. Aylward
34652a8706 Updates to iterate on code points instead of characters and changes the encoding to only encode control characters as defined by ISO standard. 2016-09-22 14:13:14 -04:00
John J. Aylward
5027a283c1 Adds test for escaping from a JSONObject to XML 2016-09-22 13:09:32 -04:00
John J. Aylward
c8563ff93d new test case for XML changes 2016-09-22 12:38:30 -04:00
John J. Aylward
a2d3b59394 Implements unicode escaping similar to JSONObject.
* Removes deprecation on XML.stringToValue(). It now provides unescaping for strings to convert XML entities back into values.
* New unescape function to handle XML entities -> value conversion.
2016-09-22 12:38:06 -04:00
Sean Leary
474711c4ea Merge pull request #60 from stleary/fix-number-tests
fixed merge issues
2016-09-15 21:38:36 -05:00
stleary
58aebaa14f fixed merge issues 2016-09-15 21:31:28 -05:00
Sean Leary
c24be0e4ea Merge pull request #274 from johnjaylward/NumberOutputFix
Fix for number output bug.
2016-09-09 11:42:35 -05:00
John J. Aylward
88f65c5bea Merge branch 'master' of github.com:stleary/JSON-java into NumberOutputFix
# Conflicts:
#	JSONObject.java
2016-08-26 11:32:35 -04:00
Sean Leary
3570890be7 Merge pull request #57 from johnjaylward/EnumCleanup
test updates to make sure Enums are handled consistently.
2016-08-19 11:43:20 -05:00
Sean Leary
ebe69df8e4 Merge pull request #271 from johnjaylward/EnumCleanup
Update enum support to be more fully featured.
2016-08-19 10:28:04 -05:00
Sean Leary
59761f6f64 Merge pull request #58 from johnjaylward/SimplifyNumberWrap
Adds tests for numbers
2016-08-17 12:12:32 -05:00
John J. Aylward
2f2cd4dfc5 Fix for number output bug.
java.lang.Number is currently output without any validation. For all java.* Numbers, this is fine, but for custom Number implementations like Complex or Fraction, the resulting JSON output may be invalid.

For example: If a Fraction implementation defines its' toString method as `return numerator + "/" + denominator`, then the resulting JSON output would be something like this:

```json
{ "fraction" : 1/2 }
```

This is not valid JSON.

This commit verifies that the string representation of the number is close to a JSON formatted number by use of the BigDecimal constructor. If the constructor throws a NumberFormatException, then the string value is instead quoted as a string. The example above would instead output like the following:

```json
{ "fraction" : "1/2" }
```
2016-08-17 12:54:30 -04:00
John J. Aylward
0b1dbe9369 fixes test to not depend on key order 2016-08-17 12:15:16 -04:00
John J. Aylward
a66b97f60b fix test 2016-08-17 11:31:44 -04:00
johnjaylward
cbd0418704 Update JSONObjectTest.java
fixes test to be applicable
2016-08-16 21:33:54 -04:00
John J. Aylward
bbd3fd5571 Adds tests for numbers 2016-08-16 20:52:41 -04:00
John J. Aylward
349a209df3 Merge remote-tracking branch 'upstream/master' into EnumCleanup 2016-08-15 10:25:27 -04:00
John J. Aylward
7851e9b2e8 revert back changes to Number support 2016-08-15 10:24:38 -04:00
Sean Leary
7232a95c0b Update JSONObject.java
Fixed some typos committed in #249, since reverted, tracking issue is #263
2016-08-15 01:58:54 -05:00
Sean Leary
f96f505188 Update JSONArray.java
Fixed a Javadoc typo, originally fixed in #249, since reverted. This is to address issue #263
2016-08-15 01:53:08 -05:00
John J. Aylward
91107e3e82 Adds support to JSONObject wrap and write methods to explicitly handle Enums.
The new way enums are handled is to always place the actual enum in the
JSONObject/JSONArray. When writing, we always write the actual "name"
of the enum, so even with a toString override on the enum class, the
value remains consistant and compatible with the optEnum/getEnum methods.

The constructor JSONObject(Object) functions the same way as before when
passing an enum and is consistent with other "value" types. For example,
when creating a JSONObject with Long, Boolean, BigDecimal as the constructor
parameter, the value will be treated as a "bean".
2016-08-11 12:22:31 -04:00
John J. Aylward
5779400f26 test updates to make sure Enums are handled consistently. 2016-08-11 12:21:49 -04:00
Sean Leary
c400de3cfe Merge pull request #53 from run2000/master
valueToString() and write() tests
2016-08-10 21:55:33 -05:00
Sean Leary
4e8e24d49d Merge pull request #259 from run2000/appendable_v2
JSONWriter uses Appendable (v2)
2016-08-10 21:55:10 -05:00
Sean Leary
f881b61c81 Update XML.java
Removed a problematic JavaDoc in the header comment to a deprecated method
2016-08-10 15:35:26 -05:00
Sean Leary
a418d07460 Merge pull request #55 from johnjaylward/verifyOptMissingKeys
Updates tests to include all opt methods and verify for missing keys.
2016-08-10 09:04:27 -05:00
John J. Aylward
8bae09f81b removes unnecessary comparison to true 2016-08-09 16:11:46 -04:00
John J. Aylward
80e36eb63c Fixes error messages 2016-08-09 15:59:27 -04:00
John J. Aylward
a2c311527b Updates tests to include all opt methods and verify for missing keys. 2016-08-09 15:54:06 -04:00
Nicholas Cull
0c157cae75 JSONWriter uses Appendable. 2016-08-08 19:40:10 +10:00
Sean Leary
62524b531d Merge pull request #52 from johnjaylward/OptionalTypeConversion
updates Test cases to support new JSONML and XML conversion options
2016-07-31 21:09:34 -05:00
run2000
e57881f8fa Fail when exceptions are not thrown as expected
The idiom was started in the first few methods, but not continued further down where JSONException was expected. False success may have resulted.
2016-07-25 09:44:43 +10:00
Nicholas Cull
efe33a1e37 Fix comment. 2016-07-24 19:57:01 +10:00
Nicholas Cull
1246e12827 Factor out Writer from Appendable tests. 2016-07-24 19:39:52 +10:00
Nicholas Cull
ffcfa66d77 Add JSONString test class.
This set of tests demonstrates what happens when JSONString returns various results from its toJSONString() method. Tests for null returns and exceptions thrown. Also tests what happens for non-JSONString objects. The intent is to cover JSONObject's valueToString() and writeValue() methods.
2016-07-24 18:56:08 +10:00
Sean Leary
5d8ea6fa4e Update README.md 2016-07-23 10:13:21 -05:00
Sean Leary
cdfdaba95b Update README.md 2016-07-23 10:12:33 -05:00
Sean Leary
2307f6f85e Update README.md 2016-07-23 10:12:04 -05:00
Sean Leary
6b4edbd40c Update README.md 2016-07-23 10:02:19 -05:00
Nicholas Cull
ae77b5cd83 Tests for deep copy and mutability of toList() and toMap().
Both toMap() and toList() return deep copies, which are also mutable. That is, any changes to the JSONObject or JSONArray do not affect the newly create Map or List, and vice-versa. The resulting objects can be altered.
2016-07-23 22:51:50 +10:00
Nicholas Cull
72c2b911bf Tests for toString(), write(), toList(), and toMap().
Explicitly test variations of toString() and write() for different indent levels, and different method overloads. Also create some tests for the new toList() and toMap() methods for coverage improvements to JSONArray and JSONObject.
2016-07-23 22:33:19 +10:00
Nicholas Cull
c3ba4bdbe5 Nesting depth test works as expected. 2016-07-23 19:12:51 +10:00
John J. Aylward
215321cd28 updates Test cases to support new JSONML and XML conversion options 2016-07-18 15:04:03 -04:00
Sean Leary
71c1eba1e7 Merge pull request #51 from johnjaylward/VerifyOptConversions
Verify opt method conversions for JSONArray and JSONObject
2016-07-08 22:31:48 -05:00
John J. Aylward
c2de224711 Verify opt method conversions for JSONArray and JSONObject 2016-07-08 16:58:58 -04:00
Sean Leary
01af31718e Merge pull request #50 from johnjaylward/issue240
Tests for Issue #240 in JSON-Java
2016-06-17 09:36:42 -05:00
John J. Aylward
1204ea9dcf fixes a typo 2016-06-17 00:04:27 -04:00
John J. Aylward
c5deff636b updates README for new project layout 2016-06-16 23:59:34 -04:00
John J. Aylward
46a1c9acf9 Adds test case to confirm the parsing of control characters 2016-06-16 13:02:08 -04:00
John J. Aylward
80f9e48e64 Moves src folder to simplify build.gradle configuration. If JSON-Java source is merged, it's src fold would now be src/main/java/org.json/ instead of src/main/org.json as well. 2016-06-16 12:20:54 -04:00
johnjaylward
0e0f3f2167 Merge pull request #1 from stleary/master
update from origin
2016-06-16 11:44:09 -04:00
Sean Leary
40f170b508 Merge pull request #49 from madsager/master
Add test that an invalid escape sequence results in a JSONException a…
2016-06-07 21:29:25 -05:00
Mads Ager
c7fdada0fd Add test that an invalid escape sequence results in a JSONException and not a NumberFormatException. 2016-06-02 16:41:43 +02:00
Sean Leary
51bcbebaa8 Merge pull request #48 from erosb/master
unittests for stleary/JSON-Java#233
2016-05-20 21:12:12 -05:00
Bence Erős
a1893ebc02 unittests for stlear/JSON-Java#233 2016-05-16 14:54:01 +02:00
stleary
8ed0362683 convert remaining JsonPath expressions to JSONPointer 2016-05-14 13:38:46 -05:00
stleary
15f48a0500 convert tests to use JSONPointer where practical 2016-05-14 11:59:24 -05:00
stleary
45cbc66f5b add coverage for JSONObject, JSONArray queryFrom() 2016-05-14 09:26:03 -05:00
stleary
06ae87c456 exclude resources from test 2016-05-13 23:22:54 -05:00
Sean Leary
7038ea884e Merge pull request #47 from stleary/add-to-test-suite-and-fix-resource
add JSONPointerTest to test suite, fix resource for gradle build
2016-05-13 23:17:10 -05:00
stleary
0112d82755 add JSONPointerTest to test suite, fix resource for gradle build 2016-05-13 23:13:06 -05:00
Sean Leary
46044bfc51 Merge pull request #46 from erosb/master
Tests for JSON Pointers
2016-05-13 22:47:14 -05:00
Sean Leary
a9ff159c78 Update README.md 2016-05-13 15:17:22 -05:00
Sean Leary
b843d67a92 Update README.md 2016-05-07 07:03:50 -05:00
Sean Leary
691734f342 Update README.md 2016-05-07 07:03:30 -05:00
Sean Leary
ccc7a7af29 Update README.md 2016-05-07 07:02:50 -05:00
Bence Erős
adb3118d31 added test for checking if the JSONPointer is immutable 2016-05-05 16:00:15 +02:00
Bence Erős
2eed4be5fc one more test for null-check in Builder#append(String) 2016-05-03 23:42:26 +02:00
Bence Erős
6edc093803 adding unittests for JSPONPointer#toString(), toURIFragment() and its builder class 2016-05-03 23:20:17 +02:00
Sean Leary
77d0873abd Merge pull request #45 from captainIowa/master
Added unit tests for escaped quotes.
2016-05-01 22:55:49 -05:00
Sean Leary
052ce94a34 Update README.md 2016-05-01 22:53:53 -05:00
stleary
4a3565afb3 unit test integration 2016-05-01 22:47:23 -05:00
Bence Erős
e748c60eb1 tests for improved failure handling 2016-04-26 23:31:43 +02:00
Bence Erős
f857dda5d8 removing some deprecated commented code 2016-04-26 23:03:01 +02:00
Bence Erős
66f740eb45 rolling back unwanted gitignore change in previous commit 2016-04-26 23:02:26 +02:00
Bence Erős
6211384f87 tests for url fragment notation handling, moving test document to separate file 2016-04-26 23:01:18 +02:00
Brian Russell
e00191798e Added unit tests for escaped quotes. 2016-04-24 23:04:12 -04:00
Bence Erős
9c47ba299d initial test for JSONPointer class 2016-04-18 21:49:14 +02:00
Sean Leary
8f16e065c5 Merge pull request #39 from johnjaylward/FixNegativeZero
Fix negative zero
2016-01-30 15:47:06 -06:00
John J. Aylward
974c09b22a Fixes typo in assert 2016-01-27 15:02:37 -05:00
John J. Aylward
bd958e0830 fixes formatting 2016-01-27 11:36:15 -05:00
John J. Aylward
67d888e9be Adds test cases to verify that -0 and -0.0 are processed as Double 2016-01-27 11:32:11 -05:00
Sean Leary
d3b197b1b9 Merge pull request #37 from stleary/move-files-to-maven-friendly-dirs
Move files to maven friendly dirs. Hope it works...
2016-01-05 20:46:43 -06:00
stleary
706d898648 latest 2016-01-03 21:39:44 -06:00
stleary
ace08f1944 latest 2016-01-03 21:39:30 -06:00
stleary
280ce71285 tabs to spaces 2016-01-01 13:54:47 -06:00
Sean Leary
147343c51b Merge pull request #29 from johnjaylward/HandleArraysConsistently
Add tests to verify arrays are handled consistently.
2016-01-01 13:46:02 -06:00
Sean Leary
dc8c9e382d Merge pull request #35 from stleary/more-todo-cleanup
clean up a few more todos
2015-12-30 13:52:55 -06:00
stleary
871a3e46d7 clean up a few more todos 2015-12-30 13:50:51 -06:00
Sean Leary
4df6984233 Merge pull request #34 from stleary/util-cleanup
util cleanup
2015-12-30 01:03:31 -06:00
stleary
c88d06eede util cleanup 2015-12-30 01:01:43 -06:00
Sean Leary
0dc886d11b Merge pull request #33 from stleary/Fix-todos-and-cleanup
Fix some todos, clean up some tests, improve coverage
2015-12-30 00:03:37 -06:00
stleary
fc318a765c Fix some todos, clean up some tests, improve coverage 2015-12-30 00:00:58 -06:00
Sean Leary
0990f340db Update README.md 2015-12-30 00:00:14 -06:00
Sean Leary
4ddd6a19a7 Merge pull request #32 from stleary/refactor-test-classes-from-JSONObjectTest
refactor test classes to their own modules
2015-12-29 18:01:35 -06:00
stleary
7f83a51718 refactor test classes to their own modules 2015-12-29 17:56:43 -06:00
Sean Leary
95cf86688d Update README.md 2015-12-28 12:25:40 -06:00
Sean Leary
91fcd6092f Update README.md 2015-12-28 12:25:11 -06:00
Sean Leary
54cd97ded1 Update README.md 2015-12-28 12:24:46 -06:00
Sean Leary
633ab108e7 Update README.md 2015-12-28 12:22:29 -06:00
Sean Leary
472439546a Update README.md 2015-12-28 12:20:43 -06:00
Sean Leary
cfec741090 Merge pull request #31 from stleary/json-path-for-validation
Replace util compare method with JsonPath
2015-12-28 12:11:47 -06:00
stleary
abe421e6bb clean up code 2015-12-28 12:07:44 -06:00
stleary
48c872f66f Replace util compare method with JsonPath 2015-12-28 11:12:41 -06:00
stleary
7187006bae Replace util compare method with JsonPath 2015-12-27 17:01:42 -06:00
stleary
d329b6514c Replace util compare method with JsonPath 2015-12-27 15:17:01 -06:00
stleary
a5390a0685 Replace util compare method with JsonPath 2015-12-26 19:02:02 -06:00
stleary
c6204a9f01 Replace util compare method with JsonPath 2015-12-26 13:21:06 -06:00
Sean Leary
c578216844 Merge pull request #30 from stleary/confirmValueToStringFix
Fix tabs, add valueToString() test to JSONObjectTest
2015-10-31 04:00:52 -05:00
stleary
38cbc31624 Fix tabs, add valueToString() test to JSONObjectTest 2015-10-31 03:58:04 -05:00
Sean Leary
6406c7a379 Merge pull request #28 from johnjaylward/FixCtorGenerics
Test cases for PR #153 in JSON-Java
2015-10-29 18:08:21 -05:00
John J. Aylward
3850b5fd25 Add tests to verify arrays are handled consistently. 2015-10-26 18:35:53 -04:00
Sean Leary
0dbd9be0f1 Merge pull request #26 from johnjaylward/FixXMLNPE
Fixes NPE in XML for pull request #160 in the json-java project
2015-10-18 10:45:42 -05:00
John J. Aylward
4a2f9b8cd3 Adds test cases for corrected generic constructors and put methods 2015-10-14 15:15:24 -04:00
John J. Aylward
cb63a968fa fixes test case to validate the input/output of the function being tested 2015-10-12 14:49:18 -04:00
John J. Aylward
4b0db65877 Fixes NPE in XML 2015-10-12 14:33:43 -04:00
stleary
1a5718dc39 Commenting out some code until JSON-java supports XML.toJSONObject(Reader) 2015-09-27 23:55:32 -05:00
Sean Leary
3f78a85908 Merge pull request #22 from stleary/xml-reader-remote
sample tests for XML.toJSONObject(Reader)
2015-08-23 20:08:02 -05:00
Sean Leary
9dd0ca7b81 Merge pull request #23 from seanThomasLeary/master
Update README.md
2015-08-23 18:54:54 -05:00
seanThomasLeary
045fc74688 Update README.md 2015-08-23 18:54:10 -05:00
stleary
1f6e07c914 sample tests for XML.toJSONObject(Reader) 2015-08-19 19:16:22 -05:00
stleary
8f71e01ae3 Add method comments so JavaDoc will pick them up. 2015-08-09 18:30:16 -05:00
stleary
ccbec8127c Added some class documentation 2015-08-09 18:24:47 -05:00
stleary
1081ae092b Move method comments so JavaDoc will pick them up. 2015-08-09 18:19:51 -05:00
stleary
58d72fe20f Verify exception messages. Move method comments so JavaDoc will pick them up. 2015-08-09 18:19:32 -05:00
stleary
8e48caeb3d Verify exception messages. Move method comments so JavaDoc will pick them up. 2015-08-08 15:12:20 -05:00
stleary
4a3bbedc32 Verify exception messages. Move method comments so JavaDoc will pick them up. 2015-08-08 14:09:52 -05:00
stleary
41bfdad91f Move method comments so JavaDoc will pick them up. 2015-08-08 12:10:52 -05:00
stleary
6f5bcb32e5 Unit tests for JSON-Java HTTP.java. See RFC7230 2015-08-08 12:10:18 -05:00
stleary
9ce62b9540 Move method comments so JavaDoc will pick them up. 2015-08-08 10:30:20 -05:00
stleary
f66cc8d5c4 Verify exception messages. Move method comments so JavaDoc will pick them up. 2015-08-08 10:22:17 -05:00
stleary
a0108f3e8e Verify exception messages. Move method comments so JavaDoc will pick them up. 2015-08-08 09:32:15 -05:00
stleary
ee0a53d494 Verify exception messages. Move method comments so JavaDoc will pick them up. 2015-08-08 08:13:22 -05:00
stleary
f69466f4c2 recreate original documented issue 2015-07-22 21:21:23 -05:00
stleary
1f4e836863 few more enum support tests 2015-07-22 20:24:45 -05:00
stleary
8ac8c34e9f tests for enum-support 2015-07-22 20:12:10 -05:00
stleary
ec7eb25565 Merge branch 'master' of github.com:stleary/JSON-Java-unit-test 2015-07-22 19:47:38 -05:00
stleary
4e38ed01e5 tests for enum-support 2015-07-22 19:47:12 -05:00
Sean Leary
752f66746b Update README.md 2015-07-21 09:12:16 -05:00
stleary
0361cc58d6 one more test - and a bug? 2015-07-20 23:31:52 -05:00
stleary
b39c3df766 document behavior of content keyword 2015-07-20 23:14:15 -05:00
stleary
b9c6f335ee fixed comment location 2015-07-19 09:04:10 -05:00
stleary
f48b6439f6 manual merge of pull request #18 2015-07-19 09:02:27 -05:00
stleary
2c026eb5f8 Fixed test shouldHandleIllegalJSONNodeNames 2015-07-19 08:56:20 -05:00
Sean Leary
0d2d0e3f6c Merge pull request #19 from JaXt0r/illegal_JSON-node-names_during_conversion_to_XML
Showing issue of illegal node names with possible underscore-replacement. (Will currently assterted to an Exception).
2015-07-19 08:48:32 -05:00
JaXt0r
5eadebb797 Showing issue of illegal node names with possible underscore-replacement. (Will currently assterted to an Exception). 2015-07-19 14:24:06 +02:00
stleary
16fa69c0f6 investigate XML.toString() behavior with null JSONObject values 2015-07-17 22:04:01 -05:00
stleary
b06182cb73 investigate XML.toString() behavior with null JSONObject values 2015-07-17 22:01:52 -05:00
stleary
0056b1af94 investigate XML.toString() behavior with null JSONObject values 2015-07-17 21:58:42 -05:00
stleary
6cca292020 investigate XML.toString() behavior with null JSONObject values 2015-07-17 21:55:50 -05:00
Sean Leary
ab143af146 Update README.md 2015-07-07 23:20:55 -05:00
Sean Leary
27b22b4724 Update README.md 2015-07-07 23:19:37 -05:00
Sean Leary
7ed1f78f5f Update README.md 2015-07-07 23:18:31 -05:00
Sean Leary
6dd85ad5b6 Update README.md 2015-07-07 23:16:18 -05:00
Sean Leary
99927c5516 Update README.md 2015-07-07 23:15:06 -05:00
Sean Leary
3de0a0a70e Update README.md 2015-07-07 23:13:59 -05:00
Sean Leary
e056fc0881 Update README.md 2015-07-06 22:33:52 -05:00
stleary
355e832337 latest 2015-07-06 22:31:48 -05:00
stleary
6c48db010f bigInt and bigDec behavior 2015-06-20 23:35:48 -05:00
stleary
8c1a0c47b7 fixed test comment 2015-06-17 20:18:51 -05:00
Sean Leary
d27bf852e6 Merge pull request #16 from stleary/big-numbers
Document bigInt and bigDec behavior to determine what can be changed
2015-06-17 20:11:19 -05:00
stleary
c5173e7cc3 ip 2015-06-17 20:09:31 -05:00
stleary
9a9973c9ca Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test into more-numbers 2015-06-17 03:01:22 -05:00
stleary
0640856462 unexpected double behavior 2015-06-17 02:59:43 -05:00
Sean Leary
cb7b602f35 Update README.md 2015-06-13 14:53:43 -05:00
Sean Leary
44f98e6a13 Update README.md 2015-06-13 13:30:06 -05:00
stleary
994a19b831 Merge branch 'master' of github.com:stleary/JSON-Java-unit-test into continue-unit-testing 2015-06-07 22:22:51 -05:00
stleary
56aa2f8607 ongoing unit test improvement 2015-06-07 22:22:42 -05:00
stleary
9cf532828d confirm current behavior 2015-06-07 22:22:14 -05:00
Sean Leary
a5b00a5244 Merge pull request #14 from stleary/iterable-JSONArray
test iterable JSONArray
2015-06-07 10:52:51 -05:00
stleary
969e2d4fd5 test iterable 2015-06-04 22:29:55 -05:00
Sean Leary
f6bdc908d8 Update README.md 2015-06-03 22:55:35 -05:00
Sean Leary
67a0c734b6 Update README.md 2015-06-03 22:54:12 -05:00
Sean Leary
86f4bda2d4 Merge pull request #13 from stleary/enum-support
support enum testing
2015-06-03 22:52:38 -05:00
stleary
6b03f1bbe7 support enum testing 2015-06-03 22:50:08 -05:00
stleary
32ea7e0ba3 tests should succeed 2015-05-28 20:43:47 -05:00
Sean Leary
e9ea5ca98f Merge pull request #12 from FritzMock/master
Hidden typecast for Float objects in JSONobject.increment(String key)
2015-05-28 20:21:09 -05:00
dieter
fa79826f0c Better show what has to be expected and what goes wrong 2015-05-27 16:33:42 +02:00
dieter
88756c0490 Hidden typecast for Float objects in JSONobject.increment(String key) 2015-05-27 15:51:30 +02:00
Sean Leary
dc7c59b23b Merge pull request #11 from stleary/fix-JSONObjectTest
fix so numeric behavior is documented but tests succeed
2015-05-24 23:40:02 -05:00
stleary
60e84bff92 fix so numeric behavior is documented but tests succeed 2015-05-24 23:36:48 -05:00
Sean Leary
c72ac516a0 Merge pull request #10 from FritzMock/master
Playing numbers
2015-05-24 17:33:38 -05:00
dieter
327c0e177e Playing numbers 2015-05-22 12:47:28 +02:00
Sean Leary
a9dd8e7b1d Update README.md 2015-05-09 15:26:15 -05:00
stleary
481ecd7964 Merge branch 'master' of github.com:stleary/JSON-Java-unit-test 2015-05-09 15:25:21 -05:00
stleary
f2ef541c2d still in progress, 94% coverage 2015-05-09 15:25:06 -05:00
Sean Leary
0a995318e7 Delete MyBean.java 2015-05-09 15:24:21 -05:00
Sean Leary
fb36918d85 Update README.md 2015-05-08 23:30:41 -05:00
stleary
fcb8048038 deepened the testing a little bit, slow going 2015-05-07 23:04:44 -05:00
stleary
49d4985828 More trickery from the bean 2015-05-07 23:04:26 -05:00
stleary
ad440b4f11 Merge branch 'master' of github.com:stleary/JSON-Java-unit-test 2015-05-06 22:17:27 -05:00
stleary
95b8cd5b03 test improvements, in progress 2015-05-06 22:16:08 -05:00
Sean Leary
fbd07da05a Update README.md 2015-05-06 14:37:52 -05:00
stleary
6195bd248b added unit tests for suppress warning coverage 2015-05-05 21:53:51 -05:00
Sean Leary
43396cf603 Merge pull request #6 from stleary/JSONMLTest-for-toString-issue
Jsonml test for to string issue
2015-05-02 14:19:16 -05:00
Sean Leary
31614fe826 Update README.md 2015-04-27 15:01:27 -05:00
Sean Leary
31cadbd810 Merge pull request #7 from stleary/Rework-CookieListTest
Rework cookie list test
2015-04-27 14:56:59 -05:00
stleary
912350ec75 96.5% coverage 2015-04-27 14:56:01 -05:00
stleary
65ae3e663f Improving test case quality 2015-04-27 10:04:41 -05:00
Sean Leary
f115d6a3b8 Update README.md 2015-04-26 17:53:39 -05:00
Sean Leary
ee06176ab2 Update README.md 2015-04-26 17:49:04 -05:00
stleary
da2e548f56 98.9% coverage 2015-04-26 17:46:52 -05:00
Sean Leary
d2e19cc78c Update README.md 2015-04-24 16:40:42 -05:00
Sean Leary
571b1a79bb Update README.md 2015-04-24 00:27:34 -05:00
Sean Leary
3112e32089 Update README.md 2015-04-24 00:26:26 -05:00
Sean Leary
102d273be3 Update README.md 2015-04-24 00:25:53 -05:00
Sean Leary
15b5306f48 Update README.md 2015-04-23 22:01:33 -05:00
stleary
9f500c242c Merge branch 'master' of github.com:/stleary/JSON-Java-unit-test 2015-04-23 21:47:28 -05:00
stleary
9bca907208 added JSONArrayTest 2015-04-23 21:47:15 -05:00
Sean Leary
890fd4a397 Update README.md 2015-04-23 21:46:13 -05:00
stleary
30c86811c0 improved object comparison 2015-04-23 21:42:04 -05:00
stleary
5acbee2719 98% coverage 2015-04-23 21:41:46 -05:00
stleary
35a4fefd2e test JSONML.toString(JSONArray) 2015-04-19 17:11:51 -05:00
stleary
f0d175c5b2 Added JSONArrayTest 2015-04-19 17:11:05 -05:00
stleary
9df929963f added a trivial XML string compare method - still needs work 2015-04-19 17:10:47 -05:00
Sean Leary
d9e04ec5b6 Update README.md 2015-04-14 11:01:29 -05:00
Sean Leary
9e78cfc48d Update README.md 2015-04-14 11:00:42 -05:00
Sean Leary
0409c9bfb2 Update README.md 2015-04-14 10:59:19 -05:00
stleary
d75a96ae59 95.9% coverage 2015-04-14 01:12:08 -05:00
Sean Leary
e5c01e4ff8 Update README.md 2015-04-13 22:29:27 -05:00
Sean Leary
98cdaf6a39 Update README.md 2015-04-13 22:28:57 -05:00
Sean Leary
67fbfa12ea Update README.md 2015-04-13 22:27:48 -05:00
Sean Leary
9bffd5b3ca Update README.md 2015-04-13 22:25:13 -05:00
Sean Leary
51e8a2d1e5 Update README.md 2015-04-13 21:45:31 -05:00
stleary
76c30539cc 95.9% coverage 2015-04-13 21:39:26 -05:00
stleary
46a43b7b0d Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test 2015-04-12 23:34:45 -05:00
stleary
6a2c974581 90.9% coverage 2015-04-12 23:34:23 -05:00
Sean Leary
a857869522 Update README.md 2015-04-12 19:36:01 -05:00
Sean Leary
9835285f0c Update README.md 2015-04-12 19:35:34 -05:00
stleary
c4d9a9c5f9 90.8% coverage 2015-04-12 19:29:32 -05:00
stleary
dcaf5fa23a ip 2015-04-10 19:42:34 -05:00
stleary
2784c614d4 ip 2015-04-10 08:21:09 -05:00
stleary
bef37079dc in progress 2015-04-09 18:02:45 -05:00
stleary
a9bce1d6b2 in progress 2015-04-08 22:23:39 -05:00
stleary
22d5fd3aed in progress 2015-04-06 19:01:54 -05:00
Sean Leary
2219b5919b Update README.md 2015-04-04 14:05:06 -05:00
stleary
8168e6f52a 93.8% coverage 2015-04-04 14:01:52 -05:00
stleary
b2e0a77ae0 98.7% coverage 2015-04-04 14:01:29 -05:00
stleary
2db11cd4db add JSONStringerTest 2015-04-04 14:00:57 -05:00
Sean Leary
03d1f0af72 Update README.md 2015-04-03 19:18:13 -05:00
Sean Leary
702a918271 Update README.md 2015-04-03 19:16:45 -05:00
stleary
76cb83643d add http test 2015-04-03 19:12:41 -05:00
stleary
400bbd7fbf 98.7% coverage 2015-04-03 19:12:15 -05:00
stleary
837b7c3037 Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test 2015-04-03 14:47:12 -05:00
stleary
f7b51414b8 96.5% coverage 2015-04-03 14:46:51 -05:00
Sean Leary
83ac581f3d Update README.md 2015-04-03 14:46:45 -05:00
stleary
970e7a45a9 added cookielisttest 2015-04-03 14:36:40 -05:00
stleary
519c21c8b0 96.5% coverage 2015-04-03 14:36:18 -05:00
stleary
3406acd0aa 97.5% coverage 2015-04-03 14:35:59 -05:00
Sean Leary
ac8b1b098a Update README.md 2015-04-03 11:29:16 -05:00
stleary
5ee4a3fc12 fixed comment test 83.2% coverage 2015-04-02 21:44:35 -05:00
stleary
5fc222229f Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test 2015-04-02 21:42:11 -05:00
stleary
e80ded6ebe fixed comment test 83.2% coverage 2015-04-02 21:31:15 -05:00
Sean Leary
45d7503e24 Update README.md 2015-04-01 01:23:04 -05:00
stleary
de13c7de86 coverage 84.9% 2015-04-01 01:12:22 -05:00
stleary
9a6215c3be in progress 2015-03-31 22:53:52 -05:00
stleary
ef7e0c7d08 in progress 2015-03-30 08:14:34 -05:00
stleary
bc07b5196b starting jsonml test 2015-03-27 17:52:41 -05:00
Sean Leary
1ff945de69 Update README.md 2015-03-26 23:05:59 -05:00
Sean Leary
210bb41ba1 Update README.md 2015-03-26 23:05:07 -05:00
stleary
89f359e4f8 coverage XMLTest 81.2% / XMLTokener 82.2% 2015-03-26 22:58:11 -05:00
stleary
a18e9f7a25 in progress 2015-03-25 18:53:52 -05:00
stleary
2df27fc6e7 in progress 2015-03-25 08:27:29 -05:00
stleary
4c6da0e6f9 In progress 2015-03-23 19:23:22 -05:00
stleary
4fbe651e57 XMLTest, in progress 2015-03-22 20:37:24 -05:00
stleary
8b9c3cbf47 XMLTest, in progress 2015-03-22 20:36:55 -05:00
stleary
964cb540fb completed 94.8% coverage 2015-03-22 17:59:43 -05:00
Sean Leary
2876b27ec5 Update README.md 2015-03-22 17:48:21 -05:00
stleary
407e7fb8d6 Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test 2015-03-21 13:44:48 -05:00
stleary
30c31db095 Reverting to 4a5809910b until I have figured out the best way to refactor the code 2015-03-21 13:44:29 -05:00
stleary
231c3de79e Update README.md 2015-03-21 13:41:25 -05:00
stleary
d0223c2d08 Update README.md 2015-03-21 13:35:24 -05:00
stleary
25596c9578 Update README.md 2015-03-21 13:34:04 -05:00
stleary
e4ef254d8f Update README.md 2015-03-21 13:33:12 -05:00
stleary
e4ebd8c443 Update README.md 2015-03-21 13:32:47 -05:00
stleary
f8c37b1e05 Update README.md 2015-03-21 13:27:38 -05:00
stleary
e150039261 Update README.md 2015-03-21 13:23:49 -05:00
stleary
8374382947 Update README.md 2015-03-21 13:22:54 -05:00
stleary
2b0a9cc7c8 Update README.md 2015-03-21 13:19:58 -05:00
stleary
42ad66b032 Update README.md 2015-03-21 13:19:32 -05:00
stleary
09b5562ad9 Update README.md 2015-03-21 13:18:56 -05:00
stleary
b0ce7f3bd9 Update README.md 2015-03-21 13:15:46 -05:00
stleary
1bde00ed4c Update README.md 2015-03-21 13:14:23 -05:00
stleary
dca3726bf1 Update README.md 2015-03-21 13:13:44 -05:00
stleary
01a2fad7fb Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test 2015-03-20 18:01:52 -05:00
stleary
68e01afd7e first checkin 2015-03-20 18:01:27 -05:00
stleary
441a00afc9 CDLTest still in progress 2015-03-20 15:34:47 -05:00
stleary
b5b4961a9d cdltest refactor, in progress 2015-03-20 07:34:03 -05:00
stleary
fd56452f6b Update README.md 2015-03-19 17:35:16 -05:00
stleary
8d9783d574 Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test 2015-03-19 17:31:27 -05:00
stleary
e899a2970d PropertTest.java coverage 94.8% 2015-03-19 17:30:44 -05:00
stleary
fac377fc13 Update README.md 2015-03-19 16:12:47 -05:00
stleary
ab08db4ad6 CookieTest 97.5% coverage 2015-03-19 16:09:29 -05:00
stleary
b557180bca more cookie code, in progress 2015-03-19 11:27:45 -05:00
stleary
d75ad1f0c0 Merge branch 'master' of https://github.com/stleary/JSON-Java-unit-test 2015-03-18 22:40:40 -05:00
stleary
df68a7b593 test suite and cookie test 2015-03-18 22:39:54 -05:00
stleary
3d3325aaca Update README.md 2015-03-18 21:51:43 -05:00
stleary
d613203eec Update README.md 2015-03-18 21:51:08 -05:00
stleary
4a5809910b final, for now, 94.8% coverage 2015-03-18 20:54:46 -05:00
stleary
a859e4f547 few more tests 2015-03-18 18:16:19 -05:00
stleary
5fc0c4e1df 72% coverage! 2015-03-18 12:40:20 -05:00
stleary
6c5e25dcb9 added embedded quotes and escapes 2015-03-18 10:13:13 -05:00
stleary
5b56b57074 updating cdltest 2015-03-17 21:47:53 -05:00
stleary
03192b0162 adding this file 2015-03-17 00:38:08 -05:00
stleary
7559b574dd Add LICENSE file via addalicense.com 2015-03-16 12:06:41 -05:00
stleary
03bb6d08be Create README.md 2015-03-16 12:00:24 -05:00
111 changed files with 33219 additions and 5251 deletions

43
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@ -0,0 +1,43 @@
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '18 18 * * 1'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
- run: "mvn clean compile -Dmaven.test.skip=true -Dmaven.site.skip=true -Dmaven.javadoc.skip=true"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

228
.github/workflows/pipeline.yml vendored Normal file
View File

@ -0,0 +1,228 @@
# This workflow will build a Java project with Maven
# For more information see: https://docs.github.com/en/actions/learn-github-actions or https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
name: Java CI with Maven
on:
push:
# branches: [ master ]
pull_request:
branches: [ master ]
jobs:
# old-school build and jar method. No tests run or compiled.
build-1_6:
name: Java 1.6
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup java
uses: actions/setup-java@v1
with:
java-version: 1.6
- name: Compile Java 1.6
run: |
mkdir -p target/classes
javac -version
javac -source 1.6 -target 1.6 -d target/classes/ src/main/java/org/json/*.java
- name: Create java 1.6 JAR
run: |
jar cvf target/org.json.jar -C target/classes .
- name: Upload JAR 1.6
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Create java 1.6 JAR
path: target/*.jar
build-8:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 1
matrix:
# build against supported Java LTS versions:
java: [ 8 ]
name: Java ${{ matrix.java }}
steps:
- uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
cache: 'maven'
- name: Compile Java ${{ matrix.java }}
run: mvn clean compile -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true -D maven.javadoc.skip=true
- name: Run Tests ${{ matrix.java }}
run: |
mvn test -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Build Test Report ${{ matrix.java }}
if: ${{ always() }}
run: |
mvn surefire-report:report-only -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
mvn site -D generateReports=false -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Upload Test Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Results ${{ matrix.java }}
path: target/surefire-reports/
- name: Upload Test Report ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Report ${{ matrix.java }}
path: target/site/
- name: Package Jar ${{ matrix.java }}
run: mvn clean package -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true
- name: Upload Package Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Package Jar ${{ matrix.java }}
path: target/*.jar
build-11:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 1
matrix:
# build against supported Java LTS versions:
java: [ 11 ]
name: Java ${{ matrix.java }}
steps:
- uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
cache: 'maven'
- name: Compile Java ${{ matrix.java }}
run: mvn clean compile -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true -D maven.javadoc.skip=true
- name: Run Tests ${{ matrix.java }}
run: |
mvn test -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Build Test Report ${{ matrix.java }}
if: ${{ always() }}
run: |
mvn surefire-report:report-only -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
mvn site -D generateReports=false -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Upload Test Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Results ${{ matrix.java }}
path: target/surefire-reports/
- name: Upload Test Report ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Report ${{ matrix.java }}
path: target/site/
- name: Package Jar ${{ matrix.java }}
run: mvn clean package -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true
- name: Upload Package Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Package Jar ${{ matrix.java }}
path: target/*.jar
build-17:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 1
matrix:
# build against supported Java LTS versions:
java: [ 17 ]
name: Java ${{ matrix.java }}
steps:
- uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
cache: 'maven'
- name: Compile Java ${{ matrix.java }}
run: mvn clean compile -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true -D maven.javadoc.skip=true
- name: Run Tests ${{ matrix.java }}
run: |
mvn test -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Build Test Report ${{ matrix.java }}
if: ${{ always() }}
run: |
mvn surefire-report:report-only -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
mvn site -D generateReports=false -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Upload Test Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Results ${{ matrix.java }}
path: target/surefire-reports/
- name: Upload Test Report ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Report ${{ matrix.java }}
path: target/site/
- name: Package Jar ${{ matrix.java }}
run: mvn clean package -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true
- name: Upload Package Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Package Jar ${{ matrix.java }}
path: target/*.jar
build-21:
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 1
matrix:
# build against supported Java LTS versions:
java: [ 21 ]
name: Java ${{ matrix.java }}
steps:
- uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
cache: 'maven'
- name: Compile Java ${{ matrix.java }}
run: mvn clean compile -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true -D maven.javadoc.skip=true
- name: Run Tests ${{ matrix.java }}
run: |
mvn test -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Build Test Report ${{ matrix.java }}
if: ${{ always() }}
run: |
mvn surefire-report:report-only -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
mvn site -D generateReports=false -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }}
- name: Upload Test Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Results ${{ matrix.java }}
path: target/surefire-reports/
- name: Upload Test Report ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Test Report ${{ matrix.java }}
path: target/site/
- name: Package Jar ${{ matrix.java }}
run: mvn clean package -D maven.compiler.source=${{ matrix.java }} -D maven.compiler.target=${{ matrix.java }} -D maven.test.skip=true -D maven.site.skip=true
- name: Upload Package Results ${{ matrix.java }}
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: Package Jar ${{ matrix.java }}
path: target/*.jar

18
.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
# ignore eclipse project files
.project
.classpath
# ignore vscode files
.vscode
# ignore Intellij Idea project files
.idea
*.iml
/target/
/bin/
build
.settings/
/.gradle/
/gradle/
/gradlew
/gradlew.bat
.gitmodules

284
CDL.java
View File

@ -1,284 +0,0 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/**
* This provides static methods to convert comma delimited text into a
* JSONArray, and to convert a JSONArray into comma delimited text. Comma
* delimited text is a very popular format for data interchange. It is
* understood by most database, spreadsheet, and organizer programs.
* <p>
* Each row of text represents a row in a table or a data record. Each row
* ends with a NEWLINE character. Each row contains one or more values.
* Values are separated by commas. A value can contain any character except
* for comma, unless is is wrapped in single quotes or double quotes.
* <p>
* The first row usually contains the names of the columns.
* <p>
* A comma delimited list can be converted into a JSONArray of JSONObjects.
* The names for the elements in the JSONObjects can be taken from the names
* in the first row.
* @author JSON.org
* @version 2016-05-01
*/
public class CDL {
/**
* Get the next value. The value can be wrapped in quotes. The value can
* be empty.
* @param x A JSONTokener of the source text.
* @return The value string, or null if empty.
* @throws JSONException if the quoted string is badly formed.
*/
private static String getValue(JSONTokener x) throws JSONException {
char c;
char q;
StringBuffer sb;
do {
c = x.next();
} while (c == ' ' || c == '\t');
switch (c) {
case 0:
return null;
case '"':
case '\'':
q = c;
sb = new StringBuffer();
for (;;) {
c = x.next();
if (c == q) {
//Handle escaped double-quote
if(x.next() != '\"')
{
x.back();
break;
}
}
if (c == 0 || c == '\n' || c == '\r') {
throw x.syntaxError("Missing close quote '" + q + "'.");
}
sb.append(c);
}
return sb.toString();
case ',':
x.back();
return "";
default:
x.back();
return x.nextTo(',');
}
}
/**
* Produce a JSONArray of strings from a row of comma delimited values.
* @param x A JSONTokener of the source text.
* @return A JSONArray of strings.
* @throws JSONException
*/
public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
JSONArray ja = new JSONArray();
for (;;) {
String value = getValue(x);
char c = x.next();
if (value == null ||
(ja.length() == 0 && value.length() == 0 && c != ',')) {
return null;
}
ja.put(value);
for (;;) {
if (c == ',') {
break;
}
if (c != ' ') {
if (c == '\n' || c == '\r' || c == 0) {
return ja;
}
throw x.syntaxError("Bad character '" + c + "' (" +
(int)c + ").");
}
c = x.next();
}
}
}
/**
* Produce a JSONObject from a row of comma delimited text, using a
* parallel JSONArray of strings to provides the names of the elements.
* @param names A JSONArray of names. This is commonly obtained from the
* first row of a comma delimited text file using the rowToJSONArray
* method.
* @param x A JSONTokener of the source text.
* @return A JSONObject combining the names and values.
* @throws JSONException
*/
public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
throws JSONException {
JSONArray ja = rowToJSONArray(x);
return ja != null ? ja.toJSONObject(names) : null;
}
/**
* Produce a comma delimited text row from a JSONArray. Values containing
* the comma character will be quoted. Troublesome characters may be
* removed.
* @param ja A JSONArray of strings.
* @return A string ending in NEWLINE.
*/
public static String rowToString(JSONArray ja) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ja.length(); i += 1) {
if (i > 0) {
sb.append(',');
}
Object object = ja.opt(i);
if (object != null) {
String string = object.toString();
if (string.length() > 0 && (string.indexOf(',') >= 0 ||
string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 ||
string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
sb.append('"');
int length = string.length();
for (int j = 0; j < length; j += 1) {
char c = string.charAt(j);
if (c >= ' ' && c != '"') {
sb.append(c);
}
}
sb.append('"');
} else {
sb.append(string);
}
}
}
sb.append('\n');
return sb.toString();
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string,
* using the first row as a source of names.
* @param string The comma delimited text.
* @return A JSONArray of JSONObjects.
* @throws JSONException
*/
public static JSONArray toJSONArray(String string) throws JSONException {
return toJSONArray(new JSONTokener(string));
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string,
* using the first row as a source of names.
* @param x The JSONTokener containing the comma delimited text.
* @return A JSONArray of JSONObjects.
* @throws JSONException
*/
public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
return toJSONArray(rowToJSONArray(x), x);
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string
* using a supplied JSONArray as the source of element names.
* @param names A JSONArray of strings.
* @param string The comma delimited text.
* @return A JSONArray of JSONObjects.
* @throws JSONException
*/
public static JSONArray toJSONArray(JSONArray names, String string)
throws JSONException {
return toJSONArray(names, new JSONTokener(string));
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string
* using a supplied JSONArray as the source of element names.
* @param names A JSONArray of strings.
* @param x A JSONTokener of the source text.
* @return A JSONArray of JSONObjects.
* @throws JSONException
*/
public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
throws JSONException {
if (names == null || names.length() == 0) {
return null;
}
JSONArray ja = new JSONArray();
for (;;) {
JSONObject jo = rowToJSONObject(names, x);
if (jo == null) {
break;
}
ja.put(jo);
}
if (ja.length() == 0) {
return null;
}
return ja;
}
/**
* Produce a comma delimited text from a JSONArray of JSONObjects. The
* first row will be a list of names obtained by inspecting the first
* JSONObject.
* @param ja A JSONArray of JSONObjects.
* @return A comma delimited text.
* @throws JSONException
*/
public static String toString(JSONArray ja) throws JSONException {
JSONObject jo = ja.optJSONObject(0);
if (jo != null) {
JSONArray names = jo.names();
if (names != null) {
return rowToString(names) + toString(names, ja);
}
}
return null;
}
/**
* Produce a comma delimited text from a JSONArray of JSONObjects using
* a provided list of names. The list of names is not included in the
* output.
* @param names A JSONArray of strings.
* @param ja A JSONArray of JSONObjects.
* @return A comma delimited text.
* @throws JSONException
*/
public static String toString(JSONArray names, JSONArray ja)
throws JSONException {
if (names == null || names.length() == 0) {
return null;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < ja.length(); i += 1) {
JSONObject jo = ja.optJSONObject(i);
if (jo != null) {
sb.append(rowToString(jo.toJSONArray(names)));
}
}
return sb.toString();
}
}

76
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at jsonjava060@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

22
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,22 @@
# Contribution Guidelines
Feel free to work on any open issue, you don't need to ask permission first. This year, the hacktoberfest label will be added to any PR and associated issue during the month of October.
If you discover an issue you would like to work on, you can add a new issue to the list. If it meets our criteria, it will be available to work on (if not, it will be closed after review).
# Who is allowed to submit pull requests for this project?
Anyone can submit pull requests for code, tests, or documentation.
# How do you decide which pull requests to accept?
* Does it call out a bug that needs to be fixed? If so, it goes to the top of the list.
* Does it fix a major user inconvenience? These are given high priority as well.
* Does it align with the specs? If not, it will probably not be accepted. It turns out there are gray areas in the specs. If this is in a gray area, it will likely be given the benefit of the doubt.
* Does it break the existing behavior of the lib? If so, it will not be accepted, unless it fixes an egregious bug. This is happening less frequently now.
# For more guidance, see these links:
[README.md (includes build instructions)](https://github.com/stleary/JSON-java#readme)
[FAQ - all your questions answered](https://github.com/stleary/JSON-java/wiki/FAQ)

View File

@ -1,169 +0,0 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/**
* Convert a web browser cookie specification to a JSONObject and back.
* JSON and Cookies are both notations for name/value pairs.
* @author JSON.org
* @version 2015-12-09
*/
public class Cookie {
/**
* Produce a copy of a string in which the characters '+', '%', '=', ';'
* and control characters are replaced with "%hh". This is a gentle form
* of URL encoding, attempting to cause as little distortion to the
* string as possible. The characters '=' and ';' are meta characters in
* cookies. By convention, they are escaped using the URL-encoding. This is
* only a convention, not a standard. Often, cookies are expected to have
* encoded values. We encode '=' and ';' because we must. We encode '%' and
* '+' because they are meta characters in URL encoding.
* @param string The source string.
* @return The escaped result.
*/
public static String escape(String string) {
char c;
String s = string.trim();
int length = s.length();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i += 1) {
c = s.charAt(i);
if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
sb.append('%');
sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
sb.append(Character.forDigit((char)(c & 0x0f), 16));
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* Convert a cookie specification string into a JSONObject. The string
* will contain a name value pair separated by '='. The name and the value
* will be unescaped, possibly converting '+' and '%' sequences. The
* cookie properties may follow, separated by ';', also represented as
* name=value (except the secure property, which does not have a value).
* The name will be stored under the key "name", and the value will be
* stored under the key "value". This method does not do checking or
* validation of the parameters. It only converts the cookie string into
* a JSONObject.
* @param string The cookie specification string.
* @return A JSONObject containing "name", "value", and possibly other
* members.
* @throws JSONException
*/
public static JSONObject toJSONObject(String string) throws JSONException {
String name;
JSONObject jo = new JSONObject();
Object value;
JSONTokener x = new JSONTokener(string);
jo.put("name", x.nextTo('='));
x.next('=');
jo.put("value", x.nextTo(';'));
x.next();
while (x.more()) {
name = unescape(x.nextTo("=;"));
if (x.next() != '=') {
if (name.equals("secure")) {
value = Boolean.TRUE;
} else {
throw x.syntaxError("Missing '=' in cookie parameter.");
}
} else {
value = unescape(x.nextTo(';'));
x.next();
}
jo.put(name, value);
}
return jo;
}
/**
* Convert a JSONObject into a cookie specification string. The JSONObject
* must contain "name" and "value" members.
* If the JSONObject contains "expires", "domain", "path", or "secure"
* members, they will be appended to the cookie specification string.
* All other members are ignored.
* @param jo A JSONObject
* @return A cookie specification string
* @throws JSONException
*/
public static String toString(JSONObject jo) throws JSONException {
StringBuilder sb = new StringBuilder();
sb.append(escape(jo.getString("name")));
sb.append("=");
sb.append(escape(jo.getString("value")));
if (jo.has("expires")) {
sb.append(";expires=");
sb.append(jo.getString("expires"));
}
if (jo.has("domain")) {
sb.append(";domain=");
sb.append(escape(jo.getString("domain")));
}
if (jo.has("path")) {
sb.append(";path=");
sb.append(escape(jo.getString("path")));
}
if (jo.optBoolean("secure")) {
sb.append(";secure");
}
return sb.toString();
}
/**
* Convert <code>%</code><i>hh</i> sequences to single characters, and
* convert plus to space.
* @param string A string that may contain
* <code>+</code>&nbsp;<small>(plus)</small> and
* <code>%</code><i>hh</i> sequences.
* @return The unescaped string.
*/
public static String unescape(String string) {
int length = string.length();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; ++i) {
char c = string.charAt(i);
if (c == '+') {
c = ' ';
} else if (c == '%' && i + 2 < length) {
int d = JSONTokener.dehexchar(string.charAt(i + 1));
int e = JSONTokener.dehexchar(string.charAt(i + 2));
if (d >= 0 && e >= 0) {
c = (char)(d * 16 + e);
i += 2;
}
}
sb.append(c);
}
return sb.toString();
}
}

View File

@ -1,89 +0,0 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import java.util.Iterator;
/**
* Convert a web browser cookie list string to a JSONObject and back.
* @author JSON.org
* @version 2015-12-09
*/
public class CookieList {
/**
* Convert a cookie list into a JSONObject. A cookie list is a sequence
* of name/value pairs. The names are separated from the values by '='.
* The pairs are separated by ';'. The names and the values
* will be unescaped, possibly converting '+' and '%' sequences.
*
* To add a cookie to a cooklist,
* cookielistJSONObject.put(cookieJSONObject.getString("name"),
* cookieJSONObject.getString("value"));
* @param string A cookie list string
* @return A JSONObject
* @throws JSONException
*/
public static JSONObject toJSONObject(String string) throws JSONException {
JSONObject jo = new JSONObject();
JSONTokener x = new JSONTokener(string);
while (x.more()) {
String name = Cookie.unescape(x.nextTo('='));
x.next('=');
jo.put(name, Cookie.unescape(x.nextTo(';')));
x.next();
}
return jo;
}
/**
* Convert a JSONObject into a cookie list. A cookie list is a sequence
* of name/value pairs. The names are separated from the values by '='.
* The pairs are separated by ';'. The characters '%', '+', '=', and ';'
* in the names and values are replaced by "%hh".
* @param jo A JSONObject
* @return A cookie list string
* @throws JSONException
*/
public static String toString(JSONObject jo) throws JSONException {
boolean b = false;
Iterator<String> keys = jo.keys();
String string;
StringBuilder sb = new StringBuilder();
while (keys.hasNext()) {
string = keys.next();
if (!jo.isNull(string)) {
if (b) {
sb.append(';');
}
sb.append(Cookie.escape(string));
sb.append("=");
sb.append(Cookie.escape(jo.getString(string)));
b = true;
}
}
return sb.toString();
}
}

433
Examples.md Normal file
View File

@ -0,0 +1,433 @@
<h1>Examples</h1>
<p>Imports used in the examples: </p>
```java
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
```
<p>This document's intention is to explain to new-comers the basics of this project</p>
<h2>Part 1: Creating a JSON document</h2>
<h3>Using JSONArray</h3>
```java
private static void JSONExampleArray1() {
//We create a JSONObject from a String containing an array using JSONArray
//Firstly, we declare an Array in a String
String arrayStr =
"["+"true,"+"false,"+ "\"true\","+ "\"false\","+"\"hello\","+"23.45e-4,"+
"\"23.45\","+"42,"+"\"43\","+"["+"\"world\""+"],"+
"{"+
"\"key1\":\"value1\","+
"\"key2\":\"value2\","+
"\"key3\":\"value3\","+
"\"key4\":\"value4\""+
"},"+
"0,"+"\"-1\""+
"]";
//Then, we initializate the JSONArray thanks to its constructor
JSONArray array = new JSONArray(arrayStr);
System.out.println("Values array: "+ array);
//We convert that array into a JSONObject, but first, we need the labels, so we need another JSONArray with the labels.
//Here we will use an auxiliary function to get one for the example.
JSONArray list = listNumberArray(array.length());
System.out.println("Label Array: "+ list.toString());
//Now, we construct the JSONObject using both the value array and the label array.
JSONObject object = array.toJSONObject(list);
System.out.println("Final JSONOBject: " + object);
}
//This method creates an JSONArray of labels in which those are generated by their positions
private static JSONArray listNumberArray(int max){
JSONArray res = new JSONArray();
for (int i=0; i<max;i++) {
//The value of the labels must be an String in order to make it work
res.put(String.valueOf(i));
}
return res;
}
```
```java
private static void JSONExampleArray2() {
//We can also create an Array without a String by creating an empty array and adding elements to it
JSONArray array = new JSONArray();
//Adding elements with .put()
array.put("value");
array.put(5);
array.put(-23.45e67);
array.put(true);
//We convert it to JSONObject providing a label arrray like last time
JSONArray list = listNumberArray(array.length());
JSONObject object = array.toJSONObject(list);
System.out.println("Final JSONOBject: " + object);
}
```
<h3>Using JSONStringer</h3>
```java
private static void JSONExampleStringer() {
//We initializate the JSONStringer
JSONStringer jsonStringer = new JSONStringer();
//Now we start the process of adding elements with .object()
jsonStringer.object();
//We can now add elements as keys and values with .values () and .key()
jsonStringer.key("trueValue").value(true);
jsonStringer.key("falseValue").value(false);
jsonStringer.key("nullValue").value(null);
jsonStringer.key("stringValue").value("hello world!");
jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!");
jsonStringer.key("intValue").value(42);
jsonStringer.key("doubleValue").value(-23.45e67);
//We end this prcedure with .ednObject
jsonStringer.endObject();
//Once we have a JSONStringer, we convert it to JSONObject generating a String and using JSONObject's contructor.
String str = jsonStringer.toString();
JSONObject jsonObject = new JSONObject(str);
System.out.println("Final JSONOBject: " + jsonObject);
}
```
<h3>Using JSONObject</h3>
```java
private static void JSONExampleObject1() {
//We can create a JSONObject from a String with the class builder
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
System.out.println("Final JSONObject: " + example);
}
```
```java
private static void JSONExampleObject2() {
//We can also create a JSONObject directly without messing around with any of the other functions.
JSONObject example = new JSONObject();
//Now we add the keys and values in a similar way as the Stringer method
example.put("key", "value");
//As you can see, the first entry is the key and the second would be its associeted value.
example.put("key2", 5);
example.put("key3", -23.45e67);
example.put("trueValue", true);
//We can't add null values thougth
//example.put("nullValue", null); //This is not possible
System.out.println("Final JSONOBject: " + example);
}
```
```java
private static void JSONExampleObject3() {
//We can also create a JSONObject with a Java Map
//YoU will need a Map whose keys are Strings. The values can be whatever you want
Map<String,Double> map = new HashMap<String, Double>();
map.put("key1", 1.0);
map.put("key2", -23.45e67);
//We create the JSONObject with the map with its class builder
JSONObject example = new JSONObject(map);
System.out.println("Final JSONOBject: " + example);
}
```
<h3>Using JSONWriter</h3>
```java
private static void JSONExamplWriter() {
//This method works in a very similar way to Object and Stringer in the construction of the JSON.
//The difference is that it needs a Java object called "Appendable" like StringBuilder
StringBuilder write = new StringBuilder();
JSONWriter jsonWriter = new JSONWriter(write);
//We behave now the same way as Stringer
jsonWriter.object();
jsonWriter.key("trueValue").value(true);
jsonWriter.key("falseValue").value(false);
jsonWriter.key("nullValue").value(null);
jsonWriter.key("stringValue").value("hello world!");
jsonWriter.key("complexStringValue").value("h\be\tllo w\u1234orld!");
jsonWriter.key("intValue").value(42);
jsonWriter.key("doubleValue").value(-23.45e67);
jsonWriter.endObject();
//The resoult should be in the "write" object
System.out.println("JSON: " + write.toString());
//The difference is that we don't get a JSONObject in this one.
}
```
```java
private static void JSONExampleTokener() {
//A partir de una String podemos crear un JSONTokener, que lo podemos usar alternativamente para JSONArray,JSONObject
String string = "this is not a valid JSON string";
JSONTokener token = new JSONTokener(string);
//Now you can use the token in JSONObject and Array the same way as a String
JSONObject object = new JSONObject(token);
JSONArray array = new JSONArray(token);
}
```
<h2>Part 2: Conversion methods</h2>
<p>We don't need to have a JSON document to work. This project also admits conversions from other type of files.</p>
<p>Secondly, we can also convert from JSON to those type of files.</p>
<h3>Extra: Conversion to JSONArray</h3>
```java
private static void JSONObjectToArray() {
//We start with a JSONObject
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
//We need a list of key strings like the reverse operation
JSONArray keyStrings = listNumberArray(example.length());
//Then we convert to the Array using both elelements
JSONArray array = example.toJSONArray(keyStrings);
System.out.println("Final JSONArray: " + array);
}
```
<h3>XML Conversions</h3>
```java
private static void XMLToExampleConversion() {
//We start with a JSONObject
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
//We obtain a String with XML format with toString()
String output = XML.toString(example);
System.out.println("Final XML: " + output);
}
```
```java
private static void XMLFromExampleConversion() {
//We start with a string with the XML format
String string = "<0>value</0><1>5</1><2>-2.345E+68</2><3>true</3>";
//We obtain a JSONObject with toJSONOBject()
JSONObject output = XML.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
```
<h3>Cookie Conversions</h3>
```java
private static void CookieToExampleConversion() {
//We start with a JSONObject
//The JSONOBject needs to entries that gives the cookie a name and gives the field "name" a name too.
//The Cokkie format doesn't support booleans
String string = "{\"name\":\"Cookie-Name\",\"value\":\"name\",\"1\":5,\"2\":-2.345E68,\"3\":'true'}";
JSONObject example = new JSONObject(string);
//We obtain a String with Cookie format with toString()
String output = Cookie.toString(example);
System.out.println("Final Cookie: " + output);
}
```
```java
private static void CookieFromExampleConversion() {
//We start with a string with the Cookie format
String string = "Cookie-Name=name;1=5;2=-2.345E%2b68;3=true";
//We obtain a JSONObject with toJSONOBject()
JSONObject output = Cookie.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
```
<h3>HTTP Conversions</h3>
```java
private static void HTTPToExampleConversion() {
//We start with a JSONObject
//The JSONObject must have the minimun header for a HTTP request or header
String string = "{\"Method\":\"POST\",\"Request-URI\":'/',\"HTTP-Version\":'HTTP/1.1',\"Value1\":true,\"Value2\":2,\"Value3\":-2.345E68}";
JSONObject example = new JSONObject(string);
//We obtain a String with HTTP format with toString()
String output = HTTP.toString(example);
System.out.println("Final HTTP: " + output);
}
```
```java
private static void HTTPFromExampleConversion() {
//We start with a string with the HTTP format
String string = "Final HTTP: POST '/' HTTP/1.1 Value3: -2.345E+68 Value1: true Value2: 2";
//We obtain a JSONObject with toJSONOBject()
JSONObject output = HTTP.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
```
<h3>CDL Conversions</h3>
```java
private static void CDLToExampleConversion() {
//We start with some JSONObjects with the same values in the keys but different values in the "values"
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
String string2 = "{\"0\":\"value2\",\"1\":6,\"2\":-8.345E68,\"3\":false}";
JSONObject example2 = new JSONObject(string2);
//We need now a JSONArray with those JSONObjects
JSONArray array = new JSONArray();
array.put(example);
array.put(example2);
//We obtain a String with XML format with toString()
String output = CDL.toString(array);
System.out.println("Final CDL: \r\n" + output);
}
```
```java
private static void CDLFromExampleConversion() {
//We start wtih a String with the CDL format
String string = "0,1,2,3\n"
+ "value,5,-2.345E+68,true\n"
+ "value2,6,-8.345E+68,false";
//We obtain a JSONArray with toJSONOBject()
JSONArray output = CDL.toJSONArray(string);
System.out.println("Final JSONArray: " + output);
}
```
<h3>Properties Conversions</h3>
```java
private static Properties PropertyToExampleConversion() {
//We start with a JSONObject
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
//We obtain a String with Properties format with toString()
Properties output = Property.toProperties(example);
System.out.println("Final Properties: " + output);
return output;
}
```
```java
private static void PropertyFromExampleConversion() {
//We start with a Properties object
Properties input = PropertyToExampleConversion();
//We obtain a JSONObject with toJSONOBject()
JSONObject output = Property.toJSONObject(input);
System.out.println("Final JSONObject: " + output);
}
```
<h2>List of all examples methods</h2>
```java
public static void main(String[] args) {
//JSONObjectToArray();
//JSONExampleArray1();
//JSONExampleArray2();
//JSONExampleStringer();
//JSONExampleObject1();
//JSONExampleObject2();
//JSONExampleObject3();
//JSONExamplWriter();
//XMLToExampleConversion();
//XMLFromExampleConversion();
//CookieToExampleConversion();
//CookieFromExampleConversion();
//HTTPToExampleConversion();
//HTTPFromExampleConversion();
//CDLToExampleConversion();
//CDLFromExampleConversion();
//PropertyToExampleConversion();
//PropertyFromExampleConversion();
}
```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +0,0 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/**
* The JSONPointerException is thrown by {@link JSONPointer} if an error occurs
* during evaluating a pointer.
*
* @author JSON.org
* @version 2016-05-13
*/
public class JSONPointerException extends JSONException {
private static final long serialVersionUID = 8872944667561856751L;
public JSONPointerException(String message) {
super(message);
}
public JSONPointerException(String message, Throwable cause) {
super(message, cause);
}
}

21
LICENSE
View File

@ -1,21 +1,2 @@
Copyright (c) 2002 JSON.org
Public Domain.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,72 +0,0 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Properties;
/**
* Converts a Property file data into JSONObject and back.
* @author JSON.org
* @version 2015-05-05
*/
public class Property {
/**
* Converts a property file object into a JSONObject. The property file object is a table of name value pairs.
* @param properties java.util.Properties
* @return JSONObject
* @throws JSONException
*/
public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException {
JSONObject jo = new JSONObject();
if (properties != null && !properties.isEmpty()) {
Enumeration<?> enumProperties = properties.propertyNames();
while(enumProperties.hasMoreElements()) {
String name = (String)enumProperties.nextElement();
jo.put(name, properties.getProperty(name));
}
}
return jo;
}
/**
* Converts the JSONObject into a property file object.
* @param jo JSONObject
* @return java.util.Properties
* @throws JSONException
*/
public static Properties toProperties(JSONObject jo) throws JSONException {
Properties properties = new Properties();
if (jo != null) {
Iterator<String> keys = jo.keys();
while (keys.hasNext()) {
String name = keys.next();
properties.put(name, jo.getString(name));
}
}
return properties;
}
}

111
README
View File

@ -1,111 +0,0 @@
JSON in Java [package org.json]
JSON is a light-weight, language independent, data interchange format.
See http://www.JSON.org/
The files in this package implement JSON encoders/decoders in Java.
It also includes the capability to convert between JSON and XML, HTTP
headers, Cookies, and CDL.
This is a reference implementation. There is a large number of JSON packages
in Java. Perhaps someday the Java community will standardize on one. Until
then, choose carefully.
The license includes this restriction: "The software shall be used for good,
not evil." If your conscience cannot live with that, then choose a different
package.
The package compiles on Java 1.6-1.8.
JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
to produce a map-like object. The object provides methods for manipulating its
contents, and for producing a JSON compliant object serialization.
JSONArray.java: The JSONObject can parse text from a String or a JSONTokener
to produce a vector-like object. The object provides methods for manipulating
its contents, and for producing a JSON compliant array serialization.
JSONTokener.java: The JSONTokener breaks a text into a sequence of individual
tokens. It can be constructed from a String, Reader, or InputStream.
JSONException.java: The JSONException is the standard exception type thrown
by this package.
JSONPointer.java: Implementation of
[JSON Pointer (RFC 6901)](https://tools.ietf.org/html/rfc6901). Supports
JSON Pointers both in the form of string representation and URI fragment
representation.
JSONString.java: The JSONString interface requires a toJSONString method,
allowing an object to provide its own serialization.
JSONStringer.java: The JSONStringer provides a convenient facility for
building JSON strings.
JSONWriter.java: The JSONWriter provides a convenient facility for building
JSON text through a writer.
CDL.java: CDL provides support for converting between JSON and comma
delimited lists.
Cookie.java: Cookie provides support for converting between JSON and cookies.
CookieList.java: CookieList provides support for converting between JSON and
cookie lists.
HTTP.java: HTTP provides support for converting between JSON and HTTP headers.
HTTPTokener.java: HTTPTokener extends JSONTokener for parsing HTTP headers.
XML.java: XML provides support for converting between JSON and XML.
JSONML.java: JSONML provides support for converting between JSONML and XML.
XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text.
Unit tests are maintained in a separate project. Contributing developers can test
JSON-java pull requests with the code in this project:
https://github.com/stleary/JSON-Java-unit-test
Numeric types in this package comply with ECMA-404: The JSON Data Interchange Format
(http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf) and
RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format
(https://tools.ietf.org/html/rfc7159#section-6).
This package fully supports Integer, Long, and Double Java types. Partial support
for BigInteger and BigDecimal values in JSONObject and JSONArray objects is provided
in the form of get(), opt(), and put() API methods.
Although 1.6 compatibility is currently supported, it is not a project goal and may be
removed in some future release.
In compliance with RFC7159 page 10 section 9, the parser is more lax with what is valid
JSON than the Generator. For Example, the tab character (U+0009) is allowed when reading
JSON Text strings, but when output by the Generator, tab is properly converted to \t in
the string. Other instances may occur where reading invalid JSON text does not cause an
error to be generated. Malformed JSON Texts such as missing end " (quote) on strings or
invalid number formats (1.2e6.3) will cause errors as such documents can not be read
reliably.
Release history:
20160810 Revert code that was breaking opt*() methods.
20160807 This release contains a bug in the JSONObject.opt*() and JSONArray.opt*() methods,
it is not recommended for use.
Java 1.6 compatability fixed, JSONArray.toList() and JSONObject.toMap(),
RFC4180 compatibility, JSONPointer, some exception fixes, optional XML type conversion.
Contains the latest code as of 7 Aug, 2016
20160212 Java 1.6 compatibility, OSGi bundle. Contains the latest code as of 12 Feb, 2016.
20151123 JSONObject and JSONArray initialization with generics. Contains the
latest code as of 23 Nov, 2015.
20150729 Checkpoint for Maven central repository release. Contains the latest code
as of 29 July, 2015.
JSON-java releases can be found by searching the Maven repository for groupId "org.json"
and artifactId "json". For example:
https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22

122
README.md Normal file
View File

@ -0,0 +1,122 @@
![Json-Java logo](https://github.com/stleary/JSON-java/blob/master/images/JsonJava.png?raw=true)
<sub><sup>image credit: Ismael Pérez Ortiz</sup></sub>
JSON in Java [package org.json]
===============================
[![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json)
[![Java CI with Maven](https://github.com/stleary/JSON-java/actions/workflows/pipeline.yml/badge.svg)](https://github.com/stleary/JSON-java/actions/workflows/pipeline.yml)
[![CodeQL](https://github.com/stleary/JSON-java/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stleary/JSON-java/actions/workflows/codeql-analysis.yml)
**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20250517/json-20250517.jar)**
# Overview
[JSON](http://www.JSON.org/) is a light-weight language-independent data interchange format.
The JSON-Java package is a reference implementation that demonstrates how to parse JSON documents into Java objects and how to generate new JSON documents from the Java classes.
Project goals include:
* Reliable and consistent results
* Adherence to the JSON specification
* Easy to build, use, and include in other projects
* No external dependencies
* Fast execution and low memory footprint
* Maintain backward compatibility
* Designed and tested to use on Java versions 1.6 - 21
The files in this package implement JSON encoders and decoders. The package can also convert between JSON and XML, HTTP headers, Cookies, and CDL.
# If you would like to contribute to this project
For more information on contributions, please see [CONTRIBUTING.md](https://github.com/stleary/JSON-java/blob/master/docs/CONTRIBUTING.md)
Bug fixes, code improvements, and unit test coverage changes are welcome! Because this project is currently in the maintenance phase, the kinds of changes that can be accepted are limited. For more information, please read the [FAQ](https://github.com/stleary/JSON-java/wiki/FAQ).
# Build Instructions
The org.json package can be built from the command line, Maven, and Gradle. The unit tests can be executed from Maven, Gradle, or individually in an IDE e.g. Eclipse.
**Building from the command line**
*Build the class files from the package root directory src/main/java*
```shell
javac org/json/*.java
```
*Create the jar file in the current directory*
```shell
jar cf json-java.jar org/json/*.class
```
*Compile a program that uses the jar (see example code below)*
```shell
javac -cp .;json-java.jar Test.java (Windows)
javac -cp .:json-java.jar Test.java (Unix Systems)
```
*Test file contents*
```java
import org.json.JSONObject;
public class Test {
public static void main(String args[]){
JSONObject jo = new JSONObject("{ \"abc\" : \"def\" }");
System.out.println(jo);
}
}
```
*Execute the Test file*
```shell
java -cp .;json-java.jar Test (Windows)
java -cp .:json-java.jar Test (Unix Systems)
```
*Expected output*
```json
{"abc":"def"}
```
**Tools to build the package and execute the unit tests**
Execute the test suite with Maven:
```shell
mvn clean test
```
Execute the test suite with Gradlew:
```shell
gradlew clean build test
```
*Optional* Execute the test suite in strict mode with Gradlew:
```shell
gradlew testWithStrictMode
```
*Optional* Execute the test suite in strict mode with Maven:
```shell
mvn test -P test-strict-mode
```
# Notes
For more information, please see [NOTES.md](https://github.com/stleary/JSON-java/blob/master/docs/NOTES.md)
# Files
For more information on files, please see [FILES.md](https://github.com/stleary/JSON-java/blob/master/docs/FILES.md)
# Release history:
For the release history, please see [RELEASES.md](https://github.com/stleary/JSON-java/blob/master/docs/RELEASES.md)

5
SECURITY.md Normal file
View File

@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please follow the instructions in the ["How are vulnerabilities and exploits handled?"](https://github.com/stleary/JSON-java/wiki/FAQ#how-are-vulnerabilities-and-exploits-handled) section in the FAQ.

494
XML.java
View File

@ -1,494 +0,0 @@
package org.json;
/*
Copyright (c) 2015 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import java.util.Iterator;
/**
* This provides static methods to convert an XML text into a JSONObject, and to
* covert a JSONObject into an XML text.
*
* @author JSON.org
* @version 2016-01-30
*/
@SuppressWarnings("boxing")
public class XML {
/** The Character '&amp;'. */
public static final Character AMP = '&';
/** The Character '''. */
public static final Character APOS = '\'';
/** The Character '!'. */
public static final Character BANG = '!';
/** The Character '='. */
public static final Character EQ = '=';
/** The Character '>'. */
public static final Character GT = '>';
/** The Character '&lt;'. */
public static final Character LT = '<';
/** The Character '?'. */
public static final Character QUEST = '?';
/** The Character '"'. */
public static final Character QUOT = '"';
/** The Character '/'. */
public static final Character SLASH = '/';
/**
* Replace special characters with XML escapes:
*
* <pre>
* &amp; <small>(ampersand)</small> is replaced by &amp;amp;
* &lt; <small>(less than)</small> is replaced by &amp;lt;
* &gt; <small>(greater than)</small> is replaced by &amp;gt;
* &quot; <small>(double quote)</small> is replaced by &amp;quot;
* </pre>
*
* @param string
* The string to be escaped.
* @return The escaped string.
*/
public static String escape(String string) {
StringBuilder sb = new StringBuilder(string.length());
for (int i = 0, length = string.length(); i < length; i++) {
char c = string.charAt(i);
switch (c) {
case '&':
sb.append("&amp;");
break;
case '<':
sb.append("&lt;");
break;
case '>':
sb.append("&gt;");
break;
case '"':
sb.append("&quot;");
break;
case '\'':
sb.append("&apos;");
break;
default:
sb.append(c);
}
}
return sb.toString();
}
/**
* Throw an exception if the string contains whitespace. Whitespace is not
* allowed in tagNames and attributes.
*
* @param string
* A string.
* @throws JSONException Thrown if the string contains whitespace or is empty.
*/
public static void noSpace(String string) throws JSONException {
int i, length = string.length();
if (length == 0) {
throw new JSONException("Empty string.");
}
for (i = 0; i < length; i += 1) {
if (Character.isWhitespace(string.charAt(i))) {
throw new JSONException("'" + string
+ "' contains a space character.");
}
}
}
/**
* Scan the content following the named tag, attaching it to the context.
*
* @param x
* The XMLTokener containing the source string.
* @param context
* The JSONObject that will include the new material.
* @param name
* The tag name.
* @return true if the close tag is processed.
* @throws JSONException
*/
private static boolean parse(XMLTokener x, JSONObject context, String name, boolean keepStrings)
throws JSONException {
char c;
int i;
JSONObject jsonobject = null;
String string;
String tagName;
Object token;
// Test for and skip past these forms:
// <!-- ... -->
// <! ... >
// <![ ... ]]>
// <? ... ?>
// Report errors for these forms:
// <>
// <=
// <<
token = x.nextToken();
// <!
if (token == BANG) {
c = x.next();
if (c == '-') {
if (x.next() == '-') {
x.skipPast("-->");
return false;
}
x.back();
} else if (c == '[') {
token = x.nextToken();
if ("CDATA".equals(token)) {
if (x.next() == '[') {
string = x.nextCDATA();
if (string.length() > 0) {
context.accumulate("content", string);
}
return false;
}
}
throw x.syntaxError("Expected 'CDATA['");
}
i = 1;
do {
token = x.nextMeta();
if (token == null) {
throw x.syntaxError("Missing '>' after '<!'.");
} else if (token == LT) {
i += 1;
} else if (token == GT) {
i -= 1;
}
} while (i > 0);
return false;
} else if (token == QUEST) {
// <?
x.skipPast("?>");
return false;
} else if (token == SLASH) {
// Close tag </
token = x.nextToken();
if (name == null) {
throw x.syntaxError("Mismatched close tag " + token);
}
if (!token.equals(name)) {
throw x.syntaxError("Mismatched " + name + " and " + token);
}
if (x.nextToken() != GT) {
throw x.syntaxError("Misshaped close tag");
}
return true;
} else if (token instanceof Character) {
throw x.syntaxError("Misshaped tag");
// Open tag <
} else {
tagName = (String) token;
token = null;
jsonobject = new JSONObject();
for (;;) {
if (token == null) {
token = x.nextToken();
}
// attribute = value
if (token instanceof String) {
string = (String) token;
token = x.nextToken();
if (token == EQ) {
token = x.nextToken();
if (!(token instanceof String)) {
throw x.syntaxError("Missing value");
}
jsonobject.accumulate(string,
keepStrings ? token : JSONObject.stringToValue((String) token));
token = null;
} else {
jsonobject.accumulate(string, "");
}
} else if (token == SLASH) {
// Empty tag <.../>
if (x.nextToken() != GT) {
throw x.syntaxError("Misshaped tag");
}
if (jsonobject.length() > 0) {
context.accumulate(tagName, jsonobject);
} else {
context.accumulate(tagName, "");
}
return false;
} else if (token == GT) {
// Content, between <...> and </...>
for (;;) {
token = x.nextContent();
if (token == null) {
if (tagName != null) {
throw x.syntaxError("Unclosed tag " + tagName);
}
return false;
} else if (token instanceof String) {
string = (String) token;
if (string.length() > 0) {
jsonobject.accumulate("content",
keepStrings ? token : JSONObject.stringToValue(string));
}
} else if (token == LT) {
// Nested element
if (parse(x, jsonobject, tagName,keepStrings)) {
if (jsonobject.length() == 0) {
context.accumulate(tagName, "");
} else if (jsonobject.length() == 1
&& jsonobject.opt("content") != null) {
context.accumulate(tagName,
jsonobject.opt("content"));
} else {
context.accumulate(tagName, jsonobject);
}
return false;
}
}
}
} else {
throw x.syntaxError("Misshaped tag");
}
}
}
}
/**
* This method has been deprecated in favor of the
* {@link JSONObject.stringToValue(String)} method. Use it instead.
*
* @deprecated Use {@link JSONObject#stringToValue(String)} instead.
* @param string String to convert
* @return JSON value of this string or the string
*/
@Deprecated
public static Object stringToValue(String string) {
return JSONObject.stringToValue(string);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject. Some information may be lost in this transformation because
* JSON is a data format and XML is a document format. XML uses elements,
* attributes, and content text, while JSON uses unordered collections of
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
* "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code>
* are ignored.
*
* @param string
* The source string.
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown if there is an errors while parsing the string
*/
public static JSONObject toJSONObject(String string) throws JSONException {
return toJSONObject(string, false);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject. Some information may be lost in this transformation because
* JSON is a data format and XML is a document format. XML uses elements,
* attributes, and content text, while JSON uses unordered collections of
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
* "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code>
* are ignored.
*
* All values are converted as strings, for 1, 01, 29.0 will not be coerced to
* numbers but will instead be the exact value as seen in the XML document.
*
* @param string
* The source string.
* @param keepStrings If true, then values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown if there is an errors while parsing the string
*/
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
JSONObject jo = new JSONObject();
XMLTokener x = new XMLTokener(string);
while (x.more() && x.skipPast("<")) {
parse(x, jo, null, keepStrings);
}
return jo;
}
/**
* Convert a JSONObject into a well-formed, element-normal XML string.
*
* @param object
* A JSONObject.
* @return A string.
* @throws JSONException Thrown if there is an error parsing the string
*/
public static String toString(Object object) throws JSONException {
return toString(object, null);
}
/**
* Convert a JSONObject into a well-formed, element-normal XML string.
*
* @param object
* A JSONObject.
* @param tagName
* The optional name of the enclosing tag.
* @return A string.
* @throws JSONException Thrown if there is an error parsing the string
*/
public static String toString(Object object, String tagName)
throws JSONException {
StringBuilder sb = new StringBuilder();
JSONArray ja;
JSONObject jo;
String key;
Iterator<String> keys;
String string;
Object value;
if (object instanceof JSONObject) {
// Emit <tagName>
if (tagName != null) {
sb.append('<');
sb.append(tagName);
sb.append('>');
}
// Loop thru the keys.
jo = (JSONObject) object;
keys = jo.keys();
while (keys.hasNext()) {
key = keys.next();
value = jo.opt(key);
if (value == null) {
value = "";
} else if (value.getClass().isArray()) {
value = new JSONArray(value);
}
string = value instanceof String ? (String) value : null;
// Emit content in body
if ("content".equals(key)) {
if (value instanceof JSONArray) {
ja = (JSONArray) value;
int i = 0;
for (Object val : ja) {
if (i > 0) {
sb.append('\n');
}
sb.append(escape(val.toString()));
i++;
}
} else {
sb.append(escape(value.toString()));
}
// Emit an array of similar keys
} else if (value instanceof JSONArray) {
ja = (JSONArray) value;
for (Object val : ja) {
if (val instanceof JSONArray) {
sb.append('<');
sb.append(key);
sb.append('>');
sb.append(toString(val));
sb.append("</");
sb.append(key);
sb.append('>');
} else {
sb.append(toString(val, key));
}
}
} else if ("".equals(value)) {
sb.append('<');
sb.append(key);
sb.append("/>");
// Emit a new tag <k>
} else {
sb.append(toString(value, key));
}
}
if (tagName != null) {
// Emit the </tagname> close tag
sb.append("</");
sb.append(tagName);
sb.append('>');
}
return sb.toString();
}
if (object != null) {
if (object.getClass().isArray()) {
object = new JSONArray(object);
}
if (object instanceof JSONArray) {
ja = (JSONArray) object;
for (Object val : ja) {
// XML does not have good support for arrays. If an array
// appears in a place where XML is lacking, synthesize an
// <array> element.
sb.append(toString(val, tagName == null ? "array" : tagName));
}
return sb.toString();
}
}
string = (object == null) ? "null" : escape(object.toString());
return (tagName == null) ? "\"" + string + "\""
: (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName
+ ">" + string + "</" + tagName + ">";
}
}

139
build.gradle Normal file
View File

@ -0,0 +1,139 @@
/*
* This file was generated by the Gradle 'init' task.
*/
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'jacoco'
apply plugin: 'maven-publish'
// for now, publishing to maven is still a manual process
//plugins {
// id 'java'
//id 'maven-publish'
// }
repositories {
mavenLocal()
mavenCentral()
maven {
url = uri('https://oss.sonatype.org/content/repositories/snapshots')
}
}
// To view the report open build/reports/jacoco/test/html/index.html
jacocoTestReport {
reports {
html.required = true
}
}
test {
finalizedBy jacocoTestReport
}
dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation 'com.jayway.jsonpath:json-path:2.9.0'
testImplementation 'org.mockito:mockito-core:4.2.0'
}
subprojects {
tasks.withType(Javadoc).all { enabled = false }
}
group = 'org.json'
version = 'v20250517-SNAPSHOT'
description = 'JSON in Java'
sourceCompatibility = '1.8'
configurations.all {
}
java {
withSourcesJar()
withJavadocJar()
}
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
// Add these imports at the top of your build.gradle file
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.StandardCopyOption
// Your existing build configurations...
// Add a new task to modify the file
task modifyStrictMode {
doLast {
println "Modifying JSONParserConfiguration.java to enable strictMode..."
def filePath = project.file('src/main/java/org/json/JSONParserConfiguration.java')
if (!filePath.exists()) {
throw new GradleException("Could not find file: ${filePath.absolutePath}")
}
// Create a backup of the original file
def backupFile = new File(filePath.absolutePath + '.bak')
Files.copy(filePath.toPath(), backupFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
// Read and modify the file content
def content = filePath.text
def modifiedContent = content.replace('// this.strictMode = true;', 'this.strictMode = true;')
// Write the modified content back to the file
filePath.text = modifiedContent
println "File modified successfully at: ${filePath.absolutePath}"
}
}
// Add a task to restore the original file
task restoreStrictMode {
doLast {
println "Restoring original JSONParserConfiguration.java..."
def filePath = project.file('src/main/java/org/json/JSONParserConfiguration.java')
def backupFile = new File(filePath.absolutePath + '.bak')
if (backupFile.exists()) {
Files.copy(backupFile.toPath(), filePath.toPath(), StandardCopyOption.REPLACE_EXISTING)
backupFile.delete()
println "Original file restored successfully at: ${filePath.absolutePath}"
} else {
println "Backup file not found at: ${backupFile.absolutePath}. No restoration performed."
}
}
}
// Create a task to run the workflow
task testWithStrictMode {
dependsOn modifyStrictMode
finalizedBy restoreStrictMode
doLast {
// This will trigger a clean build and run tests with strictMode enabled
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
exec {
executable 'cmd'
args '/c', 'gradlew.bat', 'clean', 'build'
}
} else {
exec {
executable './gradlew'
args 'clean', 'build'
}
}
}
}

22
docs/CONTRIBUTING.md Normal file
View File

@ -0,0 +1,22 @@
# Contribution Guidelines
Feel free to work on any issue with a #hacktoberfest label.
If you discover an issue you would like to work on, you can add a new issue to the list. If it meets our criteria, a hacktoberfest label will be added.
# Who is allowed to submit pull requests for this project?
Anyone can submit pull requests for code, tests, or documentation.
# How do you decide which pull requests to accept?
* Does it call out a bug that needs to be fixed? If so, it goes to the top of the list.
* Does it fix a major user inconvenience? These are given high priority as well.
* Does it align with the specs? If not, it will probably not be accepted. It turns out there are gray areas in the specs. If this is in a gray area, it will likely be given the benefit of the doubt.
* Does it break the existing behavior of the lib? If so, it will not be accepted, unless it fixes an egregious bug. This is happening less frequently now.
# For more guidance, see these links:
[README.md (includes build instructions)](https://github.com/stleary/JSON-java#readme)
[FAQ - all your questions answered](https://github.com/stleary/JSON-java/wiki/FAQ)

62
docs/FILES.md Normal file
View File

@ -0,0 +1,62 @@
# Files
**JSONObject.java**: The `JSONObject` can parse text from a `String` or a `JSONTokener`
to produce a map-like object. The object provides methods for manipulating its
contents, and for producing a JSON compliant object serialization.
**JSONArray.java**: The `JSONArray` can parse text from a String or a `JSONTokener`
to produce a vector-like object. The object provides methods for manipulating
its contents, and for producing a JSON compliant array serialization.
**JSONTokener.java**: The `JSONTokener` breaks a text into a sequence of individual
tokens. It can be constructed from a `String`, `Reader`, or `InputStream`. It also can
parse text from a `String`, `Number`, `Boolean` or `null` like `"hello"`, `42`, `true`,
`null` to produce a simple json object.
**JSONException.java**: The `JSONException` is the standard exception type thrown
by this package.
**JSONPointer.java**: Implementation of
[JSON Pointer (RFC 6901)](https://tools.ietf.org/html/rfc6901). Supports
JSON Pointers both in the form of string representation and URI fragment
representation.
**JSONPropertyIgnore.java**: Annotation class that can be used on Java Bean getter methods.
When used on a bean method that would normally be serialized into a `JSONObject`, it
overrides the getter-to-key-name logic and forces the property to be excluded from the
resulting `JSONObject`.
**JSONPropertyName.java**: Annotation class that can be used on Java Bean getter methods.
When used on a bean method that would normally be serialized into a `JSONObject`, it
overrides the getter-to-key-name logic and uses the value of the annotation. The Bean
processor will look through the class hierarchy. This means you can use the annotation on
a base class or interface and the value of the annotation will be used even if the getter
is overridden in a child class.
**JSONString.java**: The `JSONString` interface requires a `toJSONString` method,
allowing an object to provide its own serialization.
**JSONStringer.java**: The `JSONStringer` provides a convenient facility for
building JSON strings.
**JSONWriter.java**: The `JSONWriter` provides a convenient facility for building
JSON text through a writer.
**CDL.java**: `CDL` provides support for converting between JSON and comma
delimited lists.
**Cookie.java**: `Cookie` provides support for converting between JSON and cookies.
**CookieList.java**: `CookieList` provides support for converting between JSON and
cookie lists.
**HTTP.java**: `HTTP` provides support for converting between JSON and HTTP headers.
**HTTPTokener.java**: `HTTPTokener` extends `JSONTokener` for parsing HTTP headers.
**XML.java**: `XML` provides support for converting between JSON and XML.
**JSONML.java**: `JSONML` provides support for converting between JSONML and XML.
**XMLTokener.java**: `XMLTokener` extends `JSONTokener` for parsing XML text.

87
docs/NOTES.md Normal file
View File

@ -0,0 +1,87 @@
# Notes
**Recent directory structure change**
_Due to a recent commit - [#515 Merge tests and pom and code](https://github.com/stleary/JSON-java/pull/515) - the structure of the project has changed from a flat directory containing all of the Java files to a directory structure that includes unit tests and several tools used to build the project jar and run the unit tests. If you have difficulty using the new structure, please open an issue so we can work through it._
**Implementation notes**
Numeric types in this package comply with
[ECMA-404: The JSON Data Interchange Format](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf) and
[RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259#section-6).
This package fully supports `Integer`, `Long`, and `Double` Java types. Partial support
for `BigInteger` and `BigDecimal` values in `JSONObject` and `JSONArray` objects is provided
in the form of `get()`, `opt()`, and `put()` API methods.
Although 1.6 compatibility is currently supported, it is not a project goal and might be
removed in some future release.
In compliance with RFC8259 page 10 section 9, the parser is more lax with what is valid
JSON then the Generator. For Example, the tab character (U+0009) is allowed when reading
JSON Text strings, but when output by the Generator, the tab is properly converted to \t in
the string. Other instances may occur where reading invalid JSON text does not cause an
error to be generated. Malformed JSON Texts such as missing end " (quote) on strings or
invalid number formats (1.2e6.3) will cause errors as such documents can not be read
reliably.
Some notable exceptions that the JSON Parser in this library accepts are:
* Unquoted keys `{ key: "value" }`
* Unquoted values `{ "key": value }`
* Unescaped literals like "tab" in string values `{ "key": "value with an unescaped tab" }`
* Numbers out of range for `Double` or `Long` are parsed as strings
Recent pull requests added a new method `putAll` on the JSONArray. The `putAll` method
works similarly to other `put` methods in that it does not call `JSONObject.wrap` for items
added. This can lead to inconsistent object representation in JSONArray structures.
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) };
// these will be wrapped
JSONArray jArr = new JSONArray(myArr);
// these will not be wrapped
jArr.putAll(new SomeBean[]{ new SomeBean(3), new SomeBean(4) });
```
For structure 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();
// these will not be wrapped
jArr.putAll(myArr);
// 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) };
// these will be wrapped
JSONArray jArr = new JSONArray(myArr);
// these will be wrapped
jArr.putAll(new JSONArray(new SomeBean[]{ new SomeBean(3), new SomeBean(4) }));
// our jArr is now consistent.
```
**Unit Test Conventions**
Test filenames should consist of the name of the module being tested, with the suffix "Test".
For example, <b>Cookie.java</b> is tested by <b>CookieTest.java</b>.
<b>The fundamental issues with JSON-Java testing are:</b><br>
* <b>JSONObjects</b> are unordered, making simple string comparison ineffective.
* Comparisons via **equals()** is not currently supported. Neither <b>JSONArray</b> nor <b>JSONObject</b> override <b>hashCode()</b> or <b>equals()</b>, so comparison defaults to the <b>Object</b> equals(), which is not useful.
* Access to the <b>JSONArray</b> and <b>JSONObject</b> internal containers for comparison is not currently available.
<b>General issues with unit testing are:</b><br>
* Just writing tests to make coverage goals tends to result in poor tests.
* Unit tests are a form of documentation - how a given method works is demonstrated by the test. So for a code reviewer or future developer looking at code a good test helps explain how a function is supposed to work according to the original author. This can be difficult if you are not the original developer.
* It is difficult to evaluate unit tests in a vacuum. You also need to see the code being tested to understand if a test is good.
* Without unit tests, it is hard to feel confident about the quality of the code, especially when fixing bugs or refactoring. Good tests prevent regressions and keep the intent of the code correct.
* If you have unit test results along with pull requests, the reviewer has an easier time understanding your code and determining if it works as intended.

62
docs/RELEASES.md Normal file
View File

@ -0,0 +1,62 @@
# Release history:
JSON-java releases can be found by searching the Maven repository for groupId "org.json"
and artifactId "json". For example:
[https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav](https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav)
~~~
20250517 Strict mode hardening and recent commits
20250107 Restore moditect in pom.xml
20241224 Strict mode opt-in feature, and recent commits. This release does not contain module-info.class.
It is not recommended if you need this feature.
20240303 Revert optLong/getLong changes, and recent commits.
20240205 Recent commits.
20231013 First release with minimum Java version 1.8. Recent commits, including fixes for CVE-2023-5072.
20230618 Final release with Java 1.6 compatibility. Future releases will require Java 1.8 or greater.
20230227 Fix for CVE-2022-45688 and recent commits
20220924 New License - public domain, and some minor updates
20220320 Wrap StackOverflow with JSONException
20211205 Recent commits and some bug fixes for similar()
20210307 Recent commits and potentially breaking fix to JSONPointer
20201115 Recent commits and first release after project structure change
20200518 Recent commits and snapshot before project structure change
20190722 Recent commits
20180813 POM change to include Automatic-Module-Name (#431)
JSONObject(Map) now throws an exception if any of a map keys are null (#405)
20180130 Recent commits
20171018 Checkpoint for recent commits.
20170516 Roll up recent commits.
20160810 Revert code that was breaking opt*() methods.
20160807 This release contains a bug in the JSONObject.opt*() and JSONArray.opt*() methods,
it is not recommended for use.
Java 1.6 compatability fixed, JSONArray.toList() and JSONObject.toMap(),
RFC4180 compatibility, JSONPointer, some exception fixes, optional XML type conversion.
Contains the latest code as of 7 Aug 2016
20160212 Java 1.6 compatibility, OSGi bundle. Contains the latest code as of 12 Feb 2016.
20151123 JSONObject and JSONArray initialization with generics. Contains the latest code as of 23 Nov 2015.
20150729 Checkpoint for Maven central repository release. Contains the latest code
as of 29 July 2015.
~~~

5
docs/SECURITY.md Normal file
View File

@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please follow the instructions in the ["How are vulnerabilities and exploits handled?"](https://github.com/stleary/JSON-java/wiki/FAQ#how-are-vulnerabilities-and-exploits-handled) section in the FAQ.

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

183
gradlew vendored Executable file
View File

@ -0,0 +1,183 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

103
gradlew.bat vendored Normal file
View File

@ -0,0 +1,103 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

BIN
images/JsonJava.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

254
pom.xml Normal file
View File

@ -0,0 +1,254 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20250517</version>
<packaging>bundle</packaging>
<name>JSON in Java</name>
<description>
JSON is a light-weight, language independent, data interchange format.
See http://www.JSON.org/
The files in this package implement JSON encoders/decoders in Java.
It also includes the capability to convert between JSON and XML, HTTP
headers, Cookies, and CDL.
This is a reference implementation. There are a large number of JSON packages
in Java. Perhaps someday the Java community will standardize on one. Until
then, choose carefully.
</description>
<url>https://github.com/douglascrockford/JSON-java</url>
<scm>
<url>https://github.com/douglascrockford/JSON-java.git</url>
<connection>scm:git:git://github.com/douglascrockford/JSON-java.git</connection>
<developerConnection>scm:git:git@github.com:douglascrockford/JSON-java.git</developerConnection>
</scm>
<licenses>
<license>
<name>Public Domain</name>
<url>https://github.com/stleary/JSON-java/blob/master/LICENSE</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>Douglas Crockford</name>
<email>douglas@crockford.com</email>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<distributionManagement>
<repository>
<id>ossrh</id>
<name>Central Repository OSSRH</name>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.9</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>
org.json
</Export-Package>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-Xlint:unchecked</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>org.moditect</groupId>
<artifactId>moditect-maven-plugin</artifactId>
<version>1.0.0.Final</version>
<executions>
<execution>
<id>add-module-infos</id>
<phase>package</phase>
<goals>
<goal>add-module-info</goal>
</goals>
<configuration>
<jvmVersion>9</jvmVersion>
<module>
<moduleInfoSource>
module org.json {
exports org.json;
}
</moduleInfoSource>
</module>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>test-strict-mode</id>
<build>
<plugins>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<!-- Enable strict mode -->
<execution>
<id>enable-strict-mode</id>
<phase>process-sources</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<file>src/main/java/org/json/JSONParserConfiguration.java</file>
<replacements>
<replacement>
<token>// this.strictMode = true;</token>
<value>this.strictMode = true;</value>
</replacement>
</replacements>
</configuration>
</execution>
<!-- Restore original code after tests -->
<execution>
<id>restore-original</id>
<phase>test</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<file>src/main/java/org/json/JSONParserConfiguration.java</file>
<replacements>
<replacement>
<token>this.strictMode = true;</token>
<value>// this.strictMode = true;</value>
</replacement>
</replacements>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,397 @@
package org.json;
/*
Public Domain.
*/
/**
* This provides static methods to convert comma (or otherwise) delimited text into a
* JSONArray, and to convert a JSONArray into comma (or otherwise) delimited text. Comma
* delimited text is a very popular format for data interchange. It is
* understood by most database, spreadsheet, and organizer programs.
* <p>
* Each row of text represents a row in a table or a data record. Each row
* ends with a NEWLINE character. Each row contains one or more values.
* Values are separated by commas. A value can contain any character except
* for comma, unless it is wrapped in single quotes or double quotes.
* <p>
* The first row usually contains the names of the columns.
* <p>
* A comma delimited list can be converted into a JSONArray of JSONObjects.
* The names for the elements in the JSONObjects can be taken from the names
* in the first row.
* @author JSON.org
* @version 2016-05-01
*/
public class CDL {
/**
* Constructs a new CDL object.
*/
public CDL() {
}
/**
* Get the next value. The value can be wrapped in quotes. The value can
* be empty.
* @param x A JSONTokener of the source text.
* @param delimiter used in the file
* @return The value string, or null if empty.
* @throws JSONException if the quoted string is badly formed.
*/
private static String getValue(JSONTokener x, char delimiter) throws JSONException {
char c;
char q;
StringBuilder sb;
do {
c = x.next();
} while (c == ' ' || c == '\t');
if (c == 0) {
return null;
} else if (c == '"' || c == '\'') {
q = c;
sb = new StringBuilder();
for (;;) {
c = x.next();
if (c == q) {
//Handle escaped double-quote
char nextC = x.next();
if (nextC != '\"') {
// if our quote was the end of the file, don't step
if (nextC > 0) {
x.back();
}
break;
}
}
if (c == 0 || c == '\n' || c == '\r') {
throw x.syntaxError("Missing close quote '" + q + "'.");
}
sb.append(c);
}
return sb.toString();
} else if (c == delimiter) {
x.back();
return "";
}
x.back();
return x.nextTo(delimiter);
}
/**
* Produce a JSONArray of strings from a row of comma delimited values.
* @param x A JSONTokener of the source text.
* @return A JSONArray of strings.
* @throws JSONException if a called function fails
*/
public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
return rowToJSONArray(x, ',');
}
/**
* Produce a JSONArray of strings from a row of comma delimited values.
* @param x A JSONTokener of the source text.
* @param delimiter custom delimiter char
* @return A JSONArray of strings.
* @throws JSONException if a called function fails
*/
public static JSONArray rowToJSONArray(JSONTokener x, char delimiter) throws JSONException {
JSONArray ja = new JSONArray();
for (;;) {
String value = getValue(x,delimiter);
char c = x.next();
if (value != null) {
ja.put(value);
} else if (ja.length() == 0 && c != delimiter) {
return null;
} else {
// This line accounts for CSV ending with no newline
ja.put("");
}
for (;;) {
if (c == delimiter) {
break;
}
if (c != ' ') {
if (c == '\n' || c == '\r' || c == 0) {
return ja;
}
throw x.syntaxError("Bad character '" + c + "' (" +
(int)c + ").");
}
c = x.next();
}
}
}
/**
* Produce a JSONObject from a row of comma delimited text, using a
* parallel JSONArray of strings to provides the names of the elements.
* @param names A JSONArray of names. This is commonly obtained from the
* first row of a comma delimited text file using the rowToJSONArray
* method.
* @param x A JSONTokener of the source text.
* @return A JSONObject combining the names and values.
* @throws JSONException if a called function fails
*/
public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) throws JSONException {
return rowToJSONObject(names, x, ',');
}
/**
* Produce a JSONObject from a row of comma delimited text, using a
* parallel JSONArray of strings to provides the names of the elements.
* @param names A JSONArray of names. This is commonly obtained from the
* first row of a comma delimited text file using the rowToJSONArray
* method.
* @param x A JSONTokener of the source text.
* @param delimiter custom delimiter char
* @return A JSONObject combining the names and values.
* @throws JSONException if a called function fails
*/
public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x, char delimiter) throws JSONException {
JSONArray ja = rowToJSONArray(x, delimiter);
return ja != null ? ja.toJSONObject(names) : null;
}
/**
* Produce a comma delimited text row from a JSONArray. Values containing
* the comma character will be quoted. Troublesome characters may be
* removed.
* @param ja A JSONArray of strings.
* @return A string ending in NEWLINE.
*/
public static String rowToString(JSONArray ja) {
return rowToString(ja, ',');
}
/**
* Produce a comma delimited text row from a JSONArray. Values containing
* the comma character will be quoted. Troublesome characters may be
* removed.
* @param ja A JSONArray of strings.
* @param delimiter custom delimiter char
* @return A string ending in NEWLINE.
*/
public static String rowToString(JSONArray ja, char delimiter) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ja.length(); i += 1) {
if (i > 0) {
sb.append(delimiter);
}
Object object = ja.opt(i);
if (object != null) {
String string = object.toString();
if (string.length() > 0 && (string.indexOf(delimiter) >= 0 ||
string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 ||
string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
sb.append('"');
int length = string.length();
for (int j = 0; j < length; j += 1) {
char c = string.charAt(j);
if (c >= ' ' && c != '"') {
sb.append(c);
}
}
sb.append('"');
} else {
sb.append(string);
}
}
}
sb.append('\n');
return sb.toString();
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string,
* using the first row as a source of names.
* @param string The comma delimited text.
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(String string) throws JSONException {
return toJSONArray(string, ',');
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string,
* using the first row as a source of names.
* @param string The comma delimited text.
* @param delimiter custom delimiter char
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(String string, char delimiter) throws JSONException {
return toJSONArray(new JSONTokener(string), delimiter);
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string,
* using the first row as a source of names.
* @param x The JSONTokener containing the comma delimited text.
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
return toJSONArray(x, ',');
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string,
* using the first row as a source of names.
* @param x The JSONTokener containing the comma delimited text.
* @param delimiter custom delimiter char
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(JSONTokener x, char delimiter) throws JSONException {
return toJSONArray(rowToJSONArray(x, delimiter), x, delimiter);
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string
* using a supplied JSONArray as the source of element names.
* @param names A JSONArray of strings.
* @param string The comma delimited text.
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(JSONArray names, String string) throws JSONException {
return toJSONArray(names, string, ',');
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string
* using a supplied JSONArray as the source of element names.
* @param names A JSONArray of strings.
* @param string The comma delimited text.
* @param delimiter custom delimiter char
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(JSONArray names, String string, char delimiter) throws JSONException {
return toJSONArray(names, new JSONTokener(string), delimiter);
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string
* using a supplied JSONArray as the source of element names.
* @param names A JSONArray of strings.
* @param x A JSONTokener of the source text.
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(JSONArray names, JSONTokener x) throws JSONException {
return toJSONArray(names, x, ',');
}
/**
* Produce a JSONArray of JSONObjects from a comma delimited text string
* using a supplied JSONArray as the source of element names.
* @param names A JSONArray of strings.
* @param x A JSONTokener of the source text.
* @param delimiter custom delimiter char
* @return A JSONArray of JSONObjects.
* @throws JSONException if a called function fails
*/
public static JSONArray toJSONArray(JSONArray names, JSONTokener x, char delimiter) throws JSONException {
if (names == null || names.length() == 0) {
return null;
}
JSONArray ja = new JSONArray();
for (;;) {
JSONObject jo = rowToJSONObject(names, x, delimiter);
if (jo == null) {
break;
}
ja.put(jo);
}
if (ja.length() == 0) {
return null;
}
// The following block accounts for empty datasets (no keys or vals)
if (ja.length() == 1) {
JSONObject j = ja.getJSONObject(0);
if (j.length() == 1) {
String key = j.keys().next();
if ("".equals(key) && "".equals(j.get(key))) {
return null;
}
}
}
return ja;
}
/**
* Produce a comma delimited text from a JSONArray of JSONObjects. The
* first row will be a list of names obtained by inspecting the first
* JSONObject.
* @param ja A JSONArray of JSONObjects.
* @return A comma delimited text.
* @throws JSONException if a called function fails
*/
public static String toString(JSONArray ja) throws JSONException {
return toString(ja, ',');
}
/**
* Produce a comma delimited text from a JSONArray of JSONObjects. The
* first row will be a list of names obtained by inspecting the first
* JSONObject.
* @param ja A JSONArray of JSONObjects.
* @param delimiter custom delimiter char
* @return A comma delimited text.
* @throws JSONException if a called function fails
*/
public static String toString(JSONArray ja, char delimiter) throws JSONException {
JSONObject jo = ja.optJSONObject(0);
if (jo != null) {
JSONArray names = jo.names();
if (names != null) {
return rowToString(names, delimiter) + toString(names, ja, delimiter);
}
}
return null;
}
/**
* Produce a comma delimited text from a JSONArray of JSONObjects using
* a provided list of names. The list of names is not included in the
* output.
* @param names A JSONArray of strings.
* @param ja A JSONArray of JSONObjects.
* @return A comma delimited text.
* @throws JSONException if a called function fails
*/
public static String toString(JSONArray names, JSONArray ja) throws JSONException {
return toString(names, ja, ',');
}
/**
* Produce a comma delimited text from a JSONArray of JSONObjects using
* a provided list of names. The list of names is not included in the
* output.
* @param names A JSONArray of strings.
* @param ja A JSONArray of JSONObjects.
* @param delimiter custom delimiter char
* @return A comma delimited text.
* @throws JSONException if a called function fails
*/
public static String toString(JSONArray names, JSONArray ja, char delimiter) throws JSONException {
if (names == null || names.length() == 0) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ja.length(); i += 1) {
JSONObject jo = ja.optJSONObject(i);
if (jo != null) {
sb.append(rowToString(jo.toJSONArray(names), delimiter));
}
}
return sb.toString();
}
}

View File

@ -0,0 +1,210 @@
package org.json;
import java.util.Locale;
/*
Public Domain.
*/
/**
* Convert a web browser cookie specification to a JSONObject and back.
* JSON and Cookies are both notations for name/value pairs.
* See also: <a href="https://tools.ietf.org/html/rfc6265">https://tools.ietf.org/html/rfc6265</a>
* @author JSON.org
* @version 2015-12-09
*/
public class Cookie {
/**
* Constructs a new Cookie object.
*/
public Cookie() {
}
/**
* Produce a copy of a string in which the characters '+', '%', '=', ';'
* and control characters are replaced with "%hh". This is a gentle form
* of URL encoding, attempting to cause as little distortion to the
* string as possible. The characters '=' and ';' are meta characters in
* cookies. By convention, they are escaped using the URL-encoding. This is
* only a convention, not a standard. Often, cookies are expected to have
* encoded values. We encode '=' and ';' because we must. We encode '%' and
* '+' because they are meta characters in URL encoding.
* @param string The source string.
* @return The escaped result.
*/
public static String escape(String string) {
char c;
String s = string.trim();
int length = s.length();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i += 1) {
c = s.charAt(i);
if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
sb.append('%');
sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
sb.append(Character.forDigit((char)(c & 0x0f), 16));
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* Convert a cookie specification string into a JSONObject. The string
* must contain a name value pair separated by '='. The name and the value
* will be unescaped, possibly converting '+' and '%' sequences. The
* cookie properties may follow, separated by ';', also represented as
* name=value (except the Attribute properties like "Secure" or "HttpOnly",
* which do not have a value. The value {@link Boolean#TRUE} will be used for these).
* The name will be stored under the key "name", and the value will be
* stored under the key "value". This method does not do checking or
* validation of the parameters. It only converts the cookie string into
* a JSONObject. All attribute names are converted to lower case keys in the
* JSONObject (HttpOnly =&gt; httponly). If an attribute is specified more than
* once, only the value found closer to the end of the cookie-string is kept.
* @param string The cookie specification string.
* @return A JSONObject containing "name", "value", and possibly other
* members.
* @throws JSONException If there is an error parsing the Cookie String.
* Cookie strings must have at least one '=' character and the 'name'
* portion of the cookie must not be blank.
*/
public static JSONObject toJSONObject(String string) {
final JSONObject jo = new JSONObject();
String name;
Object value;
JSONTokener x = new JSONTokener(string);
name = unescape(x.nextTo('=').trim());
//per RFC6265, if the name is blank, the cookie should be ignored.
if("".equals(name)) {
throw new JSONException("Cookies must have a 'name'");
}
jo.put("name", name);
// per RFC6265, if there is no '=', the cookie should be ignored.
// the 'next' call here throws an exception if the '=' is not found.
x.next('=');
jo.put("value", unescape(x.nextTo(';')).trim());
// discard the ';'
x.next();
// parse the remaining cookie attributes
while (x.more()) {
name = unescape(x.nextTo("=;")).trim().toLowerCase(Locale.ROOT);
// don't allow a cookies attributes to overwrite its name or value.
if("name".equalsIgnoreCase(name)) {
throw new JSONException("Illegal attribute name: 'name'");
}
if("value".equalsIgnoreCase(name)) {
throw new JSONException("Illegal attribute name: 'value'");
}
// check to see if it's a flag property
if (x.next() != '=') {
value = Boolean.TRUE;
} else {
value = unescape(x.nextTo(';')).trim();
x.next();
}
// only store non-blank attributes
if(!"".equals(name) && !"".equals(value)) {
jo.put(name, value);
}
}
return jo;
}
/**
* Convert a JSONObject into a cookie specification string. The JSONObject
* must contain "name" and "value" members (case insensitive).
* If the JSONObject contains other members, they will be appended to the cookie
* specification string. User-Agents are instructed to ignore unknown attributes,
* so ensure your JSONObject is using only known attributes.
* See also: <a href="https://tools.ietf.org/html/rfc6265">https://tools.ietf.org/html/rfc6265</a>
* @param jo A JSONObject
* @return A cookie specification string
* @throws JSONException thrown if the cookie has no name.
*/
public static String toString(JSONObject jo) throws JSONException {
StringBuilder sb = new StringBuilder();
String name = null;
Object value = null;
for(String key : jo.keySet()){
if("name".equalsIgnoreCase(key)) {
name = jo.getString(key).trim();
}
if("value".equalsIgnoreCase(key)) {
value=jo.getString(key).trim();
}
if(name != null && value != null) {
break;
}
}
if(name == null || "".equals(name.trim())) {
throw new JSONException("Cookie does not have a name");
}
if(value == null) {
value = "";
}
sb.append(escape(name));
sb.append("=");
sb.append(escape((String)value));
for(String key : jo.keySet()){
if("name".equalsIgnoreCase(key)
|| "value".equalsIgnoreCase(key)) {
// already processed above
continue;
}
value = jo.opt(key);
if(value instanceof Boolean) {
if(Boolean.TRUE.equals(value)) {
sb.append(';').append(escape(key));
}
// don't emit false values
} else {
sb.append(';')
.append(escape(key))
.append('=')
.append(escape(value.toString()));
}
}
return sb.toString();
}
/**
* Convert <code>%</code><i>hh</i> sequences to single characters, and
* convert plus to space.
* @param string A string that may contain
* <code>+</code>&nbsp;<small>(plus)</small> and
* <code>%</code><i>hh</i> sequences.
* @return The unescaped string.
*/
public static String unescape(String string) {
int length = string.length();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; ++i) {
char c = string.charAt(i);
if (c == '+') {
c = ' ';
} else if (c == '%' && i + 2 < length) {
int d = JSONTokener.dehexchar(string.charAt(i + 1));
int e = JSONTokener.dehexchar(string.charAt(i + 2));
if (d >= 0 && e >= 0) {
c = (char)(d * 16 + e);
i += 2;
}
}
sb.append(c);
}
return sb.toString();
}
}

View File

@ -0,0 +1,72 @@
package org.json;
/*
Public Domain.
*/
/**
* Convert a web browser cookie list string to a JSONObject and back.
* @author JSON.org
* @version 2015-12-09
*/
public class CookieList {
/**
* Constructs a new CookieList object.
*/
public CookieList() {
}
/**
* Convert a cookie list into a JSONObject. A cookie list is a sequence
* of name/value pairs. The names are separated from the values by '='.
* The pairs are separated by ';'. The names and the values
* will be unescaped, possibly converting '+' and '%' sequences.
*
* To add a cookie to a cookie list,
* cookielistJSONObject.put(cookieJSONObject.getString("name"),
* cookieJSONObject.getString("value"));
* @param string A cookie list string
* @return A JSONObject
* @throws JSONException if a called function fails
*/
public static JSONObject toJSONObject(String string) throws JSONException {
JSONObject jo = new JSONObject();
JSONTokener x = new JSONTokener(string);
while (x.more()) {
String name = Cookie.unescape(x.nextTo('='));
x.next('=');
jo.put(name, Cookie.unescape(x.nextTo(';')));
x.next();
}
return jo;
}
/**
* Convert a JSONObject into a cookie list. A cookie list is a sequence
* of name/value pairs. The names are separated from the values by '='.
* The pairs are separated by ';'. The characters '%', '+', '=', and ';'
* in the names and values are replaced by "%hh".
* @param jo A JSONObject
* @return A cookie list string
* @throws JSONException if a called function fails
*/
public static String toString(JSONObject jo) throws JSONException {
boolean isEndOfPair = false;
final StringBuilder sb = new StringBuilder();
// Don't use the new entrySet API to maintain Android support
for (final String key : jo.keySet()) {
final Object value = jo.opt(key);
if (!JSONObject.NULL.equals(value)) {
if (isEndOfPair) {
sb.append(';');
}
sb.append(Cookie.escape(key));
sb.append("=");
sb.append(Cookie.escape(value.toString()));
isEndOfPair = true;
}
}
return sb.toString();
}
}

View File

@ -1,163 +1,148 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import java.util.Iterator;
/**
* Convert an HTTP header to a JSONObject and back.
* @author JSON.org
* @version 2015-12-09
*/
public class HTTP {
/** Carriage return/line feed. */
public static final String CRLF = "\r\n";
/**
* Convert an HTTP header string into a JSONObject. It can be a request
* header or a response header. A request header will contain
* <pre>{
* Method: "POST" (for example),
* "Request-URI": "/" (for example),
* "HTTP-Version": "HTTP/1.1" (for example)
* }</pre>
* A response header will contain
* <pre>{
* "HTTP-Version": "HTTP/1.1" (for example),
* "Status-Code": "200" (for example),
* "Reason-Phrase": "OK" (for example)
* }</pre>
* In addition, the other parameters in the header will be captured, using
* the HTTP field names as JSON names, so that <pre>
* Date: Sun, 26 May 2002 18:06:04 GMT
* Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
* Cache-Control: no-cache</pre>
* become
* <pre>{...
* Date: "Sun, 26 May 2002 18:06:04 GMT",
* Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
* "Cache-Control": "no-cache",
* ...}</pre>
* It does no further checking or conversion. It does not parse dates.
* It does not do '%' transforms on URLs.
* @param string An HTTP header string.
* @return A JSONObject containing the elements and attributes
* of the XML string.
* @throws JSONException
*/
public static JSONObject toJSONObject(String string) throws JSONException {
JSONObject jo = new JSONObject();
HTTPTokener x = new HTTPTokener(string);
String token;
token = x.nextToken();
if (token.toUpperCase().startsWith("HTTP")) {
// Response
jo.put("HTTP-Version", token);
jo.put("Status-Code", x.nextToken());
jo.put("Reason-Phrase", x.nextTo('\0'));
x.next();
} else {
// Request
jo.put("Method", token);
jo.put("Request-URI", x.nextToken());
jo.put("HTTP-Version", x.nextToken());
}
// Fields
while (x.more()) {
String name = x.nextTo(':');
x.next(':');
jo.put(name, x.nextTo('\0'));
x.next();
}
return jo;
}
/**
* Convert a JSONObject into an HTTP header. A request header must contain
* <pre>{
* Method: "POST" (for example),
* "Request-URI": "/" (for example),
* "HTTP-Version": "HTTP/1.1" (for example)
* }</pre>
* A response header must contain
* <pre>{
* "HTTP-Version": "HTTP/1.1" (for example),
* "Status-Code": "200" (for example),
* "Reason-Phrase": "OK" (for example)
* }</pre>
* Any other members of the JSONObject will be output as HTTP fields.
* The result will end with two CRLF pairs.
* @param jo A JSONObject
* @return An HTTP header string.
* @throws JSONException if the object does not contain enough
* information.
*/
public static String toString(JSONObject jo) throws JSONException {
Iterator<String> keys = jo.keys();
String string;
StringBuilder sb = new StringBuilder();
if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
sb.append(jo.getString("HTTP-Version"));
sb.append(' ');
sb.append(jo.getString("Status-Code"));
sb.append(' ');
sb.append(jo.getString("Reason-Phrase"));
} else if (jo.has("Method") && jo.has("Request-URI")) {
sb.append(jo.getString("Method"));
sb.append(' ');
sb.append('"');
sb.append(jo.getString("Request-URI"));
sb.append('"');
sb.append(' ');
sb.append(jo.getString("HTTP-Version"));
} else {
throw new JSONException("Not enough material for an HTTP header.");
}
sb.append(CRLF);
while (keys.hasNext()) {
string = keys.next();
if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) &&
!"Reason-Phrase".equals(string) && !"Method".equals(string) &&
!"Request-URI".equals(string) && !jo.isNull(string)) {
sb.append(string);
sb.append(": ");
sb.append(jo.getString(string));
sb.append(CRLF);
}
}
sb.append(CRLF);
return sb.toString();
}
}
package org.json;
/*
Public Domain.
*/
import java.util.Locale;
/**
* Convert an HTTP header to a JSONObject and back.
* @author JSON.org
* @version 2015-12-09
*/
public class HTTP {
/**
* Constructs a new HTTP object.
*/
public HTTP() {
}
/** Carriage return/line feed. */
public static final String CRLF = "\r\n";
/**
* Convert an HTTP header string into a JSONObject. It can be a request
* header or a response header. A request header will contain
* <pre>{
* Method: "POST" (for example),
* "Request-URI": "/" (for example),
* "HTTP-Version": "HTTP/1.1" (for example)
* }</pre>
* A response header will contain
* <pre>{
* "HTTP-Version": "HTTP/1.1" (for example),
* "Status-Code": "200" (for example),
* "Reason-Phrase": "OK" (for example)
* }</pre>
* In addition, the other parameters in the header will be captured, using
* the HTTP field names as JSON names, so that <pre>{@code
* Date: Sun, 26 May 2002 18:06:04 GMT
* Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
* Cache-Control: no-cache}</pre>
* become
* <pre>{@code
* Date: "Sun, 26 May 2002 18:06:04 GMT",
* Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
* "Cache-Control": "no-cache",
* ...}</pre>
* It does no further checking or conversion. It does not parse dates.
* It does not do '%' transforms on URLs.
* @param string An HTTP header string.
* @return A JSONObject containing the elements and attributes
* of the XML string.
* @throws JSONException if a called function fails
*/
public static JSONObject toJSONObject(String string) throws JSONException {
JSONObject jo = new JSONObject();
HTTPTokener x = new HTTPTokener(string);
String token;
token = x.nextToken();
if (token.toUpperCase(Locale.ROOT).startsWith("HTTP")) {
// Response
jo.put("HTTP-Version", token);
jo.put("Status-Code", x.nextToken());
jo.put("Reason-Phrase", x.nextTo('\0'));
x.next();
} else {
// Request
jo.put("Method", token);
jo.put("Request-URI", x.nextToken());
jo.put("HTTP-Version", x.nextToken());
}
// Fields
while (x.more()) {
String name = x.nextTo(':');
x.next(':');
jo.put(name, x.nextTo('\0'));
x.next();
}
return jo;
}
/**
* Convert a JSONObject into an HTTP header. A request header must contain
* <pre>{
* Method: "POST" (for example),
* "Request-URI": "/" (for example),
* "HTTP-Version": "HTTP/1.1" (for example)
* }</pre>
* A response header must contain
* <pre>{
* "HTTP-Version": "HTTP/1.1" (for example),
* "Status-Code": "200" (for example),
* "Reason-Phrase": "OK" (for example)
* }</pre>
* Any other members of the JSONObject will be output as HTTP fields.
* The result will end with two CRLF pairs.
* @param jo A JSONObject
* @return An HTTP header string.
* @throws JSONException if the object does not contain enough
* information.
*/
public static String toString(JSONObject jo) throws JSONException {
StringBuilder sb = new StringBuilder();
if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
sb.append(jo.getString("HTTP-Version"));
sb.append(' ');
sb.append(jo.getString("Status-Code"));
sb.append(' ');
sb.append(jo.getString("Reason-Phrase"));
} else if (jo.has("Method") && jo.has("Request-URI")) {
sb.append(jo.getString("Method"));
sb.append(' ');
sb.append('"');
sb.append(jo.getString("Request-URI"));
sb.append('"');
sb.append(' ');
sb.append(jo.getString("HTTP-Version"));
} else {
throw new JSONException("Not enough material for an HTTP header.");
}
sb.append(CRLF);
// Don't use the new entrySet API to maintain Android support
for (final String key : jo.keySet()) {
String value = jo.optString(key);
if (!"HTTP-Version".equals(key) && !"Status-Code".equals(key) &&
!"Reason-Phrase".equals(key) && !"Method".equals(key) &&
!"Request-URI".equals(key) && !JSONObject.NULL.equals(value)) {
sb.append(key);
sb.append(": ");
sb.append(jo.optString(key));
sb.append(CRLF);
}
}
sb.append(CRLF);
return sb.toString();
}
}

View File

@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**
@ -43,8 +23,8 @@ public class HTTPTokener extends JSONTokener {
/**
* Get the next token or string. This is used in parsing HTTP headers.
* @throws JSONException
* @return A String.
* @throws JSONException if a syntax error occurs
*/
public String nextToken() throws JSONException {
char c;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,9 @@
package org.json;
/*
Public Domain.
*/
/**
* The JSONException is thrown by the JSON.org classes when things are amiss.
*

View File

@ -1,32 +1,9 @@
package org.json;
/*
Copyright (c) 2008 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.util.Iterator;
/**
* This provides static methods to convert an XML text into a JSONArray or
* JSONObject, and to covert a JSONArray or JSONObject into an XML text using
@ -36,21 +13,53 @@ import java.util.Iterator;
* @version 2016-01-30
*/
public class JSONML {
/**
* Constructs a new JSONML object.
*/
public JSONML() {
}
/**
* Parse XML values and store them in a JSONArray.
* @param x The XMLTokener containing the source string.
* @param arrayForm true if array form, false if object form.
* @param ja The JSONArray that is containing the current tag or null
* if we are at the outermost level.
* @param keepStrings Don't type-convert text nodes and attibute values
* @param keepStrings Don't type-convert text nodes and attribute values
* @return A JSONArray if the value is the outermost tag, otherwise null.
* @throws JSONException
* @throws JSONException if a parsing error occurs
*/
private static Object parse(
XMLTokener x,
boolean arrayForm,
JSONArray ja,
boolean keepStrings
boolean keepStrings,
int currentNestingDepth
) throws JSONException {
return parse(x,arrayForm, ja,
keepStrings ? JSONMLParserConfiguration.KEEP_STRINGS : JSONMLParserConfiguration.ORIGINAL,
currentNestingDepth);
}
/**
* Parse XML values and store them in a JSONArray.
* @param x The XMLTokener containing the source string.
* @param arrayForm true if array form, false if object form.
* @param ja The JSONArray that is containing the current tag or null
* if we are at the outermost level.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means Don't type-convert text nodes and attribute values.
* @return A JSONArray if the value is the outermost tag, otherwise null.
* @throws JSONException if a parsing error occurs
*/
private static Object parse(
XMLTokener x,
boolean arrayForm,
JSONArray ja,
JSONMLParserConfiguration config,
int currentNestingDepth
) throws JSONException {
String attribute;
char c;
@ -102,7 +111,7 @@ public class JSONML {
}
} else if (c == '[') {
token = x.nextToken();
if (token.equals("CDATA") && x.next() == '[') {
if ("CDATA".equals(token) && x.next() == '[') {
if (ja != null) {
ja.put(x.nextCDATA());
}
@ -175,7 +184,7 @@ public class JSONML {
if (!(token instanceof String)) {
throw x.syntaxError("Missing value");
}
newjo.accumulate(attribute, keepStrings ? token :JSONObject.stringToValue((String)token));
newjo.accumulate(attribute, config.isKeepStrings() ? ((String)token) :XML.stringToValue((String)token));
token = null;
} else {
newjo.accumulate(attribute, "");
@ -204,7 +213,12 @@ public class JSONML {
if (token != XML.GT) {
throw x.syntaxError("Misshaped tag");
}
closeTag = (String)parse(x, arrayForm, newja, keepStrings);
if (currentNestingDepth == config.getMaxNestingDepth()) {
throw x.syntaxError("Maximum nesting depth of " + config.getMaxNestingDepth() + " reached");
}
closeTag = (String)parse(x, arrayForm, newja, config, currentNestingDepth + 1);
if (closeTag != null) {
if (!closeTag.equals(tagName)) {
throw x.syntaxError("Mismatched '" + tagName +
@ -226,7 +240,7 @@ public class JSONML {
} else {
if (ja != null) {
ja.put(token instanceof String
? keepStrings ? token :JSONObject.stringToValue((String)token)
? (config.isKeepStrings() ? XML.unescape((String)token) : XML.stringToValue((String)token))
: token);
}
}
@ -241,13 +255,13 @@ public class JSONML {
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child tags.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The source string.
* @return A JSONArray containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(String string) throws JSONException {
return (JSONArray)parse(new XMLTokener(string), true, null, false);
return (JSONArray)parse(new XMLTokener(string), true, null, JSONMLParserConfiguration.ORIGINAL, 0);
}
@ -258,10 +272,10 @@ public class JSONML {
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The source string.
* @param keepStrings If true, then values will not be coerced into boolean
* or numeric values and will instead be left as strings
@ -269,7 +283,32 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException {
return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings);
return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONArray using the JsonML transform. Each XML tag is represented as
* a JSONArray in which the first element is the tag name. If the tag has
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The source string.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONArray containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(String string, JSONMLParserConfiguration config) throws JSONException {
return (JSONArray)parse(new XMLTokener(string), true, null, config, 0);
}
@ -280,10 +319,34 @@ public class JSONML {
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child content and tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONArray containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
return (JSONArray)parse(x, true, null, config, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONArray using the JsonML transform. Each XML tag is represented as
* a JSONArray in which the first element is the tag name. If the tag has
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child content and tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener.
* @param keepStrings If true, then values will not be coerced into boolean
* or numeric values and will instead be left as strings
@ -291,7 +354,7 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException {
return (JSONArray)parse(x, true, null, keepStrings);
return (JSONArray)parse(x, true, null, keepStrings, 0);
}
@ -302,13 +365,13 @@ public class JSONML {
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child content and tags.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener.
* @return A JSONArray containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
return (JSONArray)parse(x, true, null, false);
return (JSONArray)parse(x, true, null, false, 0);
}
@ -320,16 +383,16 @@ public class JSONML {
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The XML source text.
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(String string) throws JSONException {
return (JSONObject)parse(new XMLTokener(string), false, null, false);
return (JSONObject)parse(new XMLTokener(string), false, null, false, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
@ -338,7 +401,7 @@ public class JSONML {
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The XML source text.
* @param keepStrings If true, then values will not be coerced into boolean
* or numeric values and will instead be left as strings
@ -346,10 +409,10 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings);
return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
@ -358,13 +421,35 @@ public class JSONML {
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The XML source text.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(String string, JSONMLParserConfiguration config) throws JSONException {
return (JSONObject)parse(new XMLTokener(string), false, null, config, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
* a JSONObject with a "tagName" property. If the tag has attributes, then
* the attributes will be in the JSONObject as properties. If the tag
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener of the XML source text.
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
return (JSONObject)parse(x, false, null, false);
return (JSONObject)parse(x, false, null, false, 0);
}
@ -376,7 +461,7 @@ public class JSONML {
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener of the XML source text.
* @param keepStrings If true, then values will not be coerced into boolean
* or numeric values and will instead be left as strings
@ -384,7 +469,29 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException {
return (JSONObject)parse(x, false, null, keepStrings);
return (JSONObject)parse(x, false, null, keepStrings, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
* a JSONObject with a "tagName" property. If the tag has attributes, then
* the attributes will be in the JSONObject as properties. If the tag
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener of the XML source text.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
return (JSONObject)parse(x, false, null, config, 0);
}
@ -397,13 +504,10 @@ public class JSONML {
public static String toString(JSONArray ja) throws JSONException {
int i;
JSONObject jo;
String key;
Iterator<String> keys;
int length;
Object object;
StringBuilder sb = new StringBuilder();
String tagName;
String value;
// Emit <tagName
@ -420,17 +524,16 @@ public class JSONML {
// Emit the attributes
keys = jo.keys();
while (keys.hasNext()) {
key = keys.next();
// Don't use the new entrySet API to maintain Android support
for (final String key : jo.keySet()) {
final Object value = jo.opt(key);
XML.noSpace(key);
value = jo.optString(key);
if (value != null) {
sb.append(' ');
sb.append(XML.escape(key));
sb.append('=');
sb.append('"');
sb.append(XML.escape(value));
sb.append(XML.escape(value.toString()));
sb.append('"');
}
}
@ -469,6 +572,7 @@ public class JSONML {
return sb.toString();
}
/**
* Reverse the JSONML transformation, making an XML text from a JSONObject.
* The JSONObject must contain a "tagName" property. If it has children,
@ -482,12 +586,10 @@ public class JSONML {
StringBuilder sb = new StringBuilder();
int i;
JSONArray ja;
String key;
Iterator<String> keys;
int length;
Object object;
String tagName;
String value;
Object value;
//Emit <tagName
@ -502,18 +604,17 @@ public class JSONML {
//Emit the attributes
keys = jo.keys();
while (keys.hasNext()) {
key = keys.next();
// Don't use the new entrySet API to maintain Android support
for (final String key : jo.keySet()) {
if (!"tagName".equals(key) && !"childNodes".equals(key)) {
XML.noSpace(key);
value = jo.optString(key);
value = jo.opt(key);
if (value != null) {
sb.append(' ');
sb.append(XML.escape(key));
sb.append('=');
sb.append('"');
sb.append(XML.escape(value));
sb.append(XML.escape(value.toString()));
sb.append('"');
}
}

View File

@ -0,0 +1,69 @@
package org.json;
/*
Public Domain.
*/
/**
* Configuration object for the XML to JSONML parser. The configuration is immutable.
*/
@SuppressWarnings({""})
public class JSONMLParserConfiguration extends ParserConfiguration {
/**
* We can override the default maximum nesting depth if needed.
*/
public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = ParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH;
/** Original Configuration of the XML to JSONML Parser. */
public static final JSONMLParserConfiguration ORIGINAL
= new JSONMLParserConfiguration();
/** Original configuration of the XML to JSONML Parser except that values are kept as strings. */
public static final JSONMLParserConfiguration KEEP_STRINGS
= new JSONMLParserConfiguration().withKeepStrings(true);
/**
* Default parser configuration. Does not keep strings (tries to implicitly convert values).
*/
public JSONMLParserConfiguration() {
super();
this.maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
}
/**
* Configure the parser string processing and use the default CDATA Tag Name as "content".
* @param keepStrings <code>true</code> to parse all values as string.
* <code>false</code> to try and convert XML string values into a JSON value.
* @param maxNestingDepth <code>int</code> to limit the nesting depth
*/
protected JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) {
super(keepStrings, maxNestingDepth);
}
/**
* Provides a new instance of the same configuration.
*/
@Override
protected JSONMLParserConfiguration clone() {
// future modifications to this method should always ensure a "deep"
// clone in the case of collections. i.e. if a Map is added as a configuration
// item, a new map instance should be created and if possible each value in the
// map should be cloned as well. If the values of the map are known to also
// be immutable, then a shallow clone of the map is acceptable.
return new JSONMLParserConfiguration(
this.keepStrings,
this.maxNestingDepth
);
}
@SuppressWarnings("unchecked")
@Override
public JSONMLParserConfiguration withKeepStrings(final boolean newVal) {
return super.withKeepStrings(newVal);
}
@SuppressWarnings("unchecked")
@Override
public JSONMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) {
return super.withMaxNestingDepth(maxNestingDepth);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,152 @@
package org.json;
/**
* Configuration object for the JSON parser. The configuration is immutable.
*/
public class JSONParserConfiguration extends ParserConfiguration {
/**
* Used to indicate whether to overwrite duplicate key or not.
*/
private boolean overwriteDuplicateKey;
/**
* Used to indicate whether to convert java null values to JSONObject.NULL or ignoring the entry when converting java maps.
*/
private boolean useNativeNulls;
/**
* Configuration with the default values.
*/
public JSONParserConfiguration() {
super();
this.overwriteDuplicateKey = false;
// DO NOT DELETE THE FOLLOWING LINE -- it is used for strictMode testing
// this.strictMode = true;
}
/**
* This flag, when set to true, instructs the parser to enforce strict mode when parsing JSON text.
* Garbage chars at the end of the doc, unquoted string, and single-quoted strings are all disallowed.
*/
private boolean strictMode;
@Override
protected JSONParserConfiguration clone() {
JSONParserConfiguration clone = new JSONParserConfiguration();
clone.overwriteDuplicateKey = overwriteDuplicateKey;
clone.strictMode = strictMode;
clone.maxNestingDepth = maxNestingDepth;
clone.keepStrings = keepStrings;
clone.useNativeNulls = useNativeNulls;
return clone;
}
/**
* Defines the maximum nesting depth that the parser will descend before throwing an exception
* when parsing a map into JSONObject or parsing a {@link java.util.Collection} instance into
* JSONArray. The default max nesting depth is 512, which means the parser will throw a JsonException
* if the maximum depth is reached.
*
* @param maxNestingDepth the maximum nesting depth allowed to the JSON parser
* @return The existing configuration will not be modified. A new configuration is returned.
*/
@SuppressWarnings("unchecked")
@Override
public JSONParserConfiguration withMaxNestingDepth(final int maxNestingDepth) {
JSONParserConfiguration clone = this.clone();
clone.maxNestingDepth = maxNestingDepth;
return clone;
}
/**
* Controls the parser's behavior when meeting duplicate keys.
* If set to false, the parser will throw a JSONException when meeting a duplicate key.
* Or the duplicate key's value will be overwritten.
*
* @param overwriteDuplicateKey defines should the parser overwrite duplicate keys.
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public JSONParserConfiguration withOverwriteDuplicateKey(final boolean overwriteDuplicateKey) {
JSONParserConfiguration clone = this.clone();
clone.overwriteDuplicateKey = overwriteDuplicateKey;
return clone;
}
/**
* Controls the parser's behavior when meeting Java null values while converting maps.
* If set to true, the parser will put a JSONObject.NULL into the resulting JSONObject.
* Or the map entry will be ignored.
*
* @param useNativeNulls defines if the parser should convert null values in Java maps
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public JSONParserConfiguration withUseNativeNulls(final boolean useNativeNulls) {
JSONParserConfiguration clone = this.clone();
clone.useNativeNulls = useNativeNulls;
return clone;
}
/**
* Sets the strict mode configuration for the JSON parser with default true value
* <p>
* When strict mode is enabled, the parser will throw a JSONException if it encounters an invalid character
* immediately following the final ']' character in the input. This is useful for ensuring strict adherence to the
* JSON syntax, as any characters after the final closing bracket of a JSON array are considered invalid.
* @return a new JSONParserConfiguration instance with the updated strict mode setting
*/
public JSONParserConfiguration withStrictMode() {
return withStrictMode(true);
}
/**
* Sets the strict mode configuration for the JSON parser.
* <p>
* When strict mode is enabled, the parser will throw a JSONException if it encounters an invalid character
* immediately following the final ']' character in the input. This is useful for ensuring strict adherence to the
* JSON syntax, as any characters after the final closing bracket of a JSON array are considered invalid.
*
* @param mode a boolean value indicating whether strict mode should be enabled or not
* @return a new JSONParserConfiguration instance with the updated strict mode setting
*/
public JSONParserConfiguration withStrictMode(final boolean mode) {
JSONParserConfiguration clone = this.clone();
clone.strictMode = mode;
return clone;
}
/**
* The parser's behavior when meeting duplicate keys, controls whether the parser should
* overwrite duplicate keys or not.
*
* @return The <code>overwriteDuplicateKey</code> configuration value.
*/
public boolean isOverwriteDuplicateKey() {
return this.overwriteDuplicateKey;
}
/**
* The parser's behavior when meeting a null value in a java map, controls whether the parser should
* write a JSON entry with a null value (<code>isUseNativeNulls() == true</code>)
* or ignore that map entry (<code>isUseNativeNulls() == false</code>).
*
* @return The <code>useNativeNulls</code> configuration value.
*/
public boolean isUseNativeNulls() {
return this.useNativeNulls;
}
/**
* The parser throws an Exception when strict mode is true and tries to parse invalid JSON characters.
* Otherwise, the parser is more relaxed and might tolerate some invalid characters.
*
* @return the current strict mode setting.
*/
public boolean isStrictMode() {
return this.strictMode;
}
}

View File

@ -5,30 +5,12 @@ import static java.lang.String.format;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**
@ -60,19 +42,26 @@ public class JSONPointer {
*/
public static class Builder {
/**
* Constructs a new Builder object.
*/
public Builder() {
}
// Segments for the eventual JSONPointer string
private final List<String> refTokens = new ArrayList<String>();
/**
* Creates a {@code JSONPointer} instance using the tokens previously set using the
* {@link #append(String)} method calls.
* @return a JSONPointer object
*/
public JSONPointer build() {
return new JSONPointer(refTokens);
return new JSONPointer(this.refTokens);
}
/**
* Adds an arbitary token to the list of reference tokens. It can be any non-null value.
* Adds an arbitrary token to the list of reference tokens. It can be any non-null value.
*
* Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
* argument of this method MUST NOT be escaped. If you want to query the property called
@ -87,7 +76,7 @@ public class JSONPointer {
if (token == null) {
throw new NullPointerException("token cannot be null");
}
refTokens.add(token);
this.refTokens.add(token);
return this;
}
@ -99,7 +88,7 @@ public class JSONPointer {
* @return {@code this}
*/
public Builder append(int arrayIndex) {
refTokens.add(String.valueOf(arrayIndex));
this.refTokens.add(String.valueOf(arrayIndex));
return this;
}
}
@ -134,40 +123,67 @@ public class JSONPointer {
* @param pointer the JSON String or URI Fragment representation of the JSON pointer.
* @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer
*/
public JSONPointer(String pointer) {
public JSONPointer(final String pointer) {
if (pointer == null) {
throw new NullPointerException("pointer cannot be null");
}
if (pointer.isEmpty()) {
refTokens = Collections.emptyList();
if (pointer.isEmpty() || "#".equals(pointer)) {
this.refTokens = Collections.emptyList();
return;
}
String refs;
if (pointer.startsWith("#/")) {
pointer = pointer.substring(2);
refs = pointer.substring(2);
try {
pointer = URLDecoder.decode(pointer, ENCODING);
refs = URLDecoder.decode(refs, ENCODING);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
} else if (pointer.startsWith("/")) {
pointer = pointer.substring(1);
refs = pointer.substring(1);
} else {
throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'");
}
refTokens = new ArrayList<String>();
for (String token : pointer.split("/")) {
refTokens.add(unescape(token));
}
this.refTokens = new ArrayList<String>();
int slashIdx = -1;
int prevSlashIdx = 0;
do {
prevSlashIdx = slashIdx + 1;
slashIdx = refs.indexOf('/', prevSlashIdx);
if(prevSlashIdx == slashIdx || prevSlashIdx == refs.length()) {
// found 2 slashes in a row ( obj//next )
// or single slash at the end of a string ( obj/test/ )
this.refTokens.add("");
} else if (slashIdx >= 0) {
final String token = refs.substring(prevSlashIdx, slashIdx);
this.refTokens.add(unescape(token));
} else {
// last item after separator, or no separator at all.
final String token = refs.substring(prevSlashIdx);
this.refTokens.add(unescape(token));
}
} while (slashIdx >= 0);
// using split does not take into account consecutive separators or "ending nulls"
//for (String token : refs.split("/")) {
// this.refTokens.add(unescape(token));
//}
}
/**
* Constructs a new JSONPointer instance with the provided list of reference tokens.
*
* @param refTokens A list of strings representing the reference tokens for the JSON Pointer.
* Each token identifies a step in the path to the targeted value.
*/
public JSONPointer(List<String> refTokens) {
this.refTokens = new ArrayList<String>(refTokens);
}
private String unescape(String token) {
return token.replace("~1", "/").replace("~0", "~")
.replace("\\\"", "\"")
.replace("\\\\", "\\");
/**
* @see <a href="https://tools.ietf.org/html/rfc6901#section-3">rfc6901 section 3</a>
*/
private static String unescape(String token) {
return token.replace("~1", "/").replace("~0", "~");
}
/**
@ -180,12 +196,12 @@ public class JSONPointer {
* @return the result of the evaluation
* @throws JSONPointerException if an error occurs during evaluation
*/
public Object queryFrom(Object document) {
if (refTokens.isEmpty()) {
public Object queryFrom(Object document) throws JSONPointerException {
if (this.refTokens.isEmpty()) {
return document;
}
Object current = document;
for (String token : refTokens) {
for (String token : this.refTokens) {
if (current instanceof JSONObject) {
current = ((JSONObject) current).opt(unescape(token));
} else if (current instanceof JSONArray) {
@ -204,17 +220,21 @@ public class JSONPointer {
* @param current the JSONArray to be evaluated
* @param indexToken the array index in string form
* @return the matched object. If no matching item is found a
* JSONPointerException is thrown
* @throws JSONPointerException is thrown if the index is out of bounds
*/
private Object readByIndexToken(Object current, String indexToken) {
private static Object readByIndexToken(Object current, String indexToken) throws JSONPointerException {
try {
int index = Integer.parseInt(indexToken);
JSONArray currentArr = (JSONArray) current;
if (index >= currentArr.length()) {
throw new JSONPointerException(format("index %d is out of bounds - the array has %d elements", index,
currentArr.length()));
throw new JSONPointerException(format("index %s is out of bounds - the array has %d elements", indexToken,
Integer.valueOf(currentArr.length())));
}
return currentArr.get(index);
try {
return currentArr.get(index);
} catch (JSONException e) {
throw new JSONPointerException("Error reading value at index position " + index, e);
}
} catch (NumberFormatException e) {
throw new JSONPointerException(format("%s is not an array index", indexToken), e);
}
@ -226,8 +246,8 @@ public class JSONPointer {
*/
@Override
public String toString() {
StringBuilder rval = new StringBuilder("");
for (String token: refTokens) {
StringBuilder rval = new StringBuilder();
for (String token: this.refTokens) {
rval.append('/').append(escape(token));
}
return rval.toString();
@ -236,26 +256,26 @@ public class JSONPointer {
/**
* Escapes path segment values to an unambiguous form.
* The escape char to be inserted is '~'. The chars to be escaped
* are ~, which maps to ~0, and /, which maps to ~1. Backslashes
* and double quote chars are also escaped.
* are ~, which maps to ~0, and /, which maps to ~1.
* @param token the JSONPointer segment value to be escaped
* @return the escaped value for the token
*
* @see <a href="https://tools.ietf.org/html/rfc6901#section-3">rfc6901 section 3</a>
*/
private String escape(String token) {
private static String escape(String token) {
return token.replace("~", "~0")
.replace("/", "~1")
.replace("\\", "\\\\")
.replace("\"", "\\\"");
.replace("/", "~1");
}
/**
* Returns a string representing the JSONPointer path value using URI
* fragment identifier representation
* @return a uri fragment string
*/
public String toURIFragment() {
try {
StringBuilder rval = new StringBuilder("#");
for (String token : refTokens) {
for (String token : this.refTokens) {
rval.append('/').append(URLEncoder.encode(token, ENCODING));
}
return rval.toString();

View File

@ -0,0 +1,36 @@
package org.json;
/*
Public Domain.
*/
/**
* The JSONPointerException is thrown by {@link JSONPointer} if an error occurs
* during evaluating a pointer.
*
* @author JSON.org
* @version 2016-05-13
*/
public class JSONPointerException extends JSONException {
private static final long serialVersionUID = 8872944667561856751L;
/**
* Constructs a new JSONPointerException with the specified error message.
*
* @param message The detail message describing the reason for the exception.
*/
public JSONPointerException(String message) {
super(message);
}
/**
* Constructs a new JSONPointerException with the specified error message and cause.
*
* @param message The detail message describing the reason for the exception.
* @param cause The cause of the exception.
*/
public JSONPointerException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,23 @@
package org.json;
/*
Public Domain.
*/
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Use this annotation on a getter method to override the Bean name
* parser for Bean -&gt; JSONObject mapping. If this annotation is
* present at any level in the class hierarchy, then the method will
* not be serialized from the bean into the JSONObject.
*/
@Documented
@Retention(RUNTIME)
@Target({METHOD})
public @interface JSONPropertyIgnore { }

View File

@ -0,0 +1,28 @@
package org.json;
/*
Public Domain.
*/
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Use this annotation on a getter method to override the Bean name
* parser for Bean -&gt; JSONObject mapping. A value set to empty string <code>""</code>
* will have the Bean parser fall back to the default field name processing.
*/
@Documented
@Retention(RUNTIME)
@Target({METHOD})
public @interface JSONPropertyName {
/**
* The value of the JSON property.
* @return The name of the property as to be used in the JSON Object.
*/
String value();
}

View File

@ -1,4 +1,9 @@
package org.json;
/*
Public Domain.
*/
/**
* The <code>JSONString</code> interface allows a <code>toJSONString()</code>
* method so that a class can change the behavior of

View File

@ -1,78 +1,59 @@
package org.json;
/*
Copyright (c) 2006 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import java.io.StringWriter;
/**
* JSONStringer provides a quick and convenient way of producing JSON text.
* The texts produced strictly conform to JSON syntax rules. No whitespace is
* added, so the results are ready for transmission or storage. Each instance of
* JSONStringer can produce one JSON text.
* <p>
* A JSONStringer instance provides a <code>value</code> method for appending
* values to the
* text, and a <code>key</code>
* method for adding keys before values in objects. There are <code>array</code>
* and <code>endArray</code> methods that make and bound array values, and
* <code>object</code> and <code>endObject</code> methods which make and bound
* object values. All of these methods return the JSONWriter instance,
* permitting cascade style. For example, <pre>
* myString = new JSONStringer()
* .object()
* .key("JSON")
* .value("Hello, World!")
* .endObject()
* .toString();</pre> which produces the string <pre>
* {"JSON":"Hello, World!"}</pre>
* <p>
* The first method called must be <code>array</code> or <code>object</code>.
* There are no methods for adding commas or colons. JSONStringer adds them for
* you. Objects and arrays can be nested up to 20 levels deep.
* <p>
* This can sometimes be easier than using a JSONObject to build a string.
* @author JSON.org
* @version 2015-12-09
*/
public class JSONStringer extends JSONWriter {
/**
* Make a fresh JSONStringer. It can be used to build one JSON text.
*/
public JSONStringer() {
super(new StringWriter());
}
/**
* Return the JSON text. This method is used to obtain the product of the
* JSONStringer instance. It will return <code>null</code> if there was a
* problem in the construction of the JSON text (such as the calls to
* <code>array</code> were not properly balanced with calls to
* <code>endArray</code>).
* @return The JSON text.
*/
public String toString() {
return this.mode == 'd' ? this.writer.toString() : null;
}
}
package org.json;
/*
Public Domain.
*/
import java.io.StringWriter;
/**
* JSONStringer provides a quick and convenient way of producing JSON text.
* The texts produced strictly conform to JSON syntax rules. No whitespace is
* added, so the results are ready for transmission or storage. Each instance of
* JSONStringer can produce one JSON text.
* <p>
* A JSONStringer instance provides a <code>value</code> method for appending
* values to the
* text, and a <code>key</code>
* method for adding keys before values in objects. There are <code>array</code>
* and <code>endArray</code> methods that make and bound array values, and
* <code>object</code> and <code>endObject</code> methods which make and bound
* object values. All of these methods return the JSONWriter instance,
* permitting cascade style. For example, <pre>
* myString = new JSONStringer()
* .object()
* .key("JSON")
* .value("Hello, World!")
* .endObject()
* .toString();</pre> which produces the string <pre>
* {"JSON":"Hello, World!"}</pre>
* <p>
* The first method called must be <code>array</code> or <code>object</code>.
* There are no methods for adding commas or colons. JSONStringer adds them for
* you. Objects and arrays can be nested up to 200 levels deep.
* <p>
* This can sometimes be easier than using a JSONObject to build a string.
* @author JSON.org
* @version 2015-12-09
*/
public class JSONStringer extends JSONWriter {
/**
* Make a fresh JSONStringer. It can be used to build one JSON text.
*/
public JSONStringer() {
super(new StringWriter());
}
/**
* Return the JSON text. This method is used to obtain the product of the
* JSONStringer instance. It will return <code>null</code> if there was a
* problem in the construction of the JSON text (such as the calls to
* <code>array</code> were not properly balanced with calls to
* <code>endArray</code>).
* @return The JSON text.
*/
@Override
public String toString() {
return this.mode == 'd' ? this.writer.toString() : null;
}
}

View File

@ -1,35 +1,11 @@
package org.json;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.*;
import java.nio.charset.Charset;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
Public Domain.
*/
/**
* A JSONTokener takes a source string and extracts characters and tokens from
@ -39,52 +15,110 @@ SOFTWARE.
* @version 2014-05-03
*/
public class JSONTokener {
private long character;
/** current read character position on the current line. */
private long character;
/** flag to indicate if the end of the input has been found. */
private boolean eof;
private long index;
private long line;
private char previous;
private Reader reader;
/** current read index of the input. */
private long index;
/** current line of the input. */
private long line;
/** previous character read from the input. */
private char previous;
/** Reader for the input. */
private final Reader reader;
/** flag to indicate that a previous character was requested. */
private boolean usePrevious;
/** the number of characters read in the previous line. */
private long characterPreviousLine;
// access to this object is required for strict mode checking
private JSONParserConfiguration jsonParserConfiguration;
/**
* Construct a JSONTokener from a Reader.
* Construct a JSONTokener from a Reader. The caller must close the Reader.
*
* @param reader A reader.
* @param reader the source.
*/
public JSONTokener(Reader reader) {
this(reader, new JSONParserConfiguration());
}
/**
* Construct a JSONTokener from a Reader with a given JSONParserConfiguration. The caller must close the Reader.
*
* @param reader the source.
* @param jsonParserConfiguration A JSONParserConfiguration instance that controls the behavior of the parser.
*
*/
public JSONTokener(Reader reader, JSONParserConfiguration jsonParserConfiguration) {
this.jsonParserConfiguration = jsonParserConfiguration;
this.reader = reader.markSupported()
? reader
: new BufferedReader(reader);
? reader
: new BufferedReader(reader);
this.eof = false;
this.usePrevious = false;
this.previous = 0;
this.index = 0;
this.character = 1;
this.characterPreviousLine = 0;
this.line = 1;
}
/**
* Construct a JSONTokener from an InputStream.
* Construct a JSONTokener from an InputStream. The caller must close the input stream.
* @param inputStream The source.
*/
public JSONTokener(InputStream inputStream) {
this(new InputStreamReader(inputStream));
this(inputStream, new JSONParserConfiguration());
}
/**
* Construct a JSONTokener from an InputStream. The caller must close the input stream.
* @param inputStream The source.
* @param jsonParserConfiguration A JSONParserConfiguration instance that controls the behavior of the parser.
*/
public JSONTokener(InputStream inputStream, JSONParserConfiguration jsonParserConfiguration) {
this(new InputStreamReader(inputStream, Charset.forName("UTF-8")), jsonParserConfiguration);
}
/**
* Construct a JSONTokener from a string.
*
* @param s A source string.
* @param source A source string.
*/
public JSONTokener(String s) {
this(new StringReader(s));
public JSONTokener(String source) {
this(new StringReader(source));
}
/**
* Construct a JSONTokener from an InputStream. The caller must close the input stream.
* @param source The source.
* @param jsonParserConfiguration A JSONParserConfiguration instance that controls the behavior of the parser.
*/
public JSONTokener(String source, JSONParserConfiguration jsonParserConfiguration) {
this(new StringReader(source), jsonParserConfiguration);
}
/**
* Getter
* @return jsonParserConfiguration
*/
public JSONParserConfiguration getJsonParserConfiguration() {
return jsonParserConfiguration;
}
/**
* Setter
* @param jsonParserConfiguration new value for jsonParserConfiguration
*
* @deprecated method should not be used
*/
@Deprecated
public void setJsonParserConfiguration(JSONParserConfiguration jsonParserConfiguration) {
this.jsonParserConfiguration = jsonParserConfiguration;
}
/**
* Back up one character. This provides a sort of lookahead capability,
@ -97,12 +131,23 @@ public class JSONTokener {
if (this.usePrevious || this.index <= 0) {
throw new JSONException("Stepping back two steps is not supported");
}
this.index -= 1;
this.character -= 1;
this.decrementIndexes();
this.usePrevious = true;
this.eof = false;
}
/**
* Decrements the indexes for the {@link #back()} method based on the previous character read.
*/
private void decrementIndexes() {
this.index--;
if(this.previous=='\r' || this.previous == '\n') {
this.line--;
this.character=this.characterPreviousLine ;
} else if(this.character > 0){
this.character--;
}
}
/**
* Get the hex value of a character (base16).
@ -124,6 +169,8 @@ public class JSONTokener {
}
/**
* Checks if the end of the input has been reached.
*
* @return true if at the end of the file and we didn't step back
*/
public boolean end() {
@ -139,11 +186,24 @@ public class JSONTokener {
* or backward while checking for more data.
*/
public boolean more() throws JSONException {
this.next();
if (this.end()) {
return false;
if(this.usePrevious) {
return true;
}
try {
this.reader.mark(1);
} catch (IOException e) {
throw new JSONException("Unable to preserve stream position", e);
}
try {
// -1 is EOF, but next() can not consume the null character '\0'
if(this.reader.read() <= 0) {
this.eof = true;
return false;
}
this.reader.reset();
} catch (IOException e) {
throw new JSONException("Unable to read the next character from the stream", e);
}
this.back();
return true;
}
@ -165,26 +225,45 @@ public class JSONTokener {
} catch (IOException exception) {
throw new JSONException(exception);
}
if (c <= 0) { // End of stream
this.eof = true;
c = 0;
}
}
this.index += 1;
if (this.previous == '\r') {
this.line += 1;
this.character = c == '\n' ? 0 : 1;
} else if (c == '\n') {
this.line += 1;
this.character = 0;
} else {
this.character += 1;
if (c <= 0) { // End of stream
this.eof = true;
return 0;
}
this.incrementIndexes(c);
this.previous = (char) c;
return this.previous;
}
/**
* Get the last character read from the input or '\0' if nothing has been read yet.
* @return the last character read from the input.
*/
protected char getPrevious() { return this.previous;}
/**
* Increments the internal indexes according to the previous character
* read and the character passed as the current character.
* @param c the current character read.
*/
private void incrementIndexes(int c) {
if(c > 0) {
this.index++;
if(c=='\r') {
this.line++;
this.characterPreviousLine = this.character;
this.character=0;
}else if (c=='\n') {
if(this.previous != '\r') {
this.line++;
this.characterPreviousLine = this.character;
}
this.character=0;
} else {
this.character++;
}
}
}
/**
* Consume the next character, and check that it matches a specified
@ -196,8 +275,11 @@ public class JSONTokener {
public char next(char c) throws JSONException {
char n = this.next();
if (n != c) {
throw this.syntaxError("Expected '" + c + "' and instead saw '" +
n + "'");
if(n > 0) {
throw this.syntaxError("Expected '" + c + "' and instead saw '" +
n + "'");
}
throw this.syntaxError("Expected '" + c + "' and instead saw ''");
}
return n;
}
@ -212,23 +294,23 @@ public class JSONTokener {
* Substring bounds error if there are not
* n characters remaining in the source string.
*/
public String next(int n) throws JSONException {
if (n == 0) {
return "";
}
public String next(int n) throws JSONException {
if (n == 0) {
return "";
}
char[] chars = new char[n];
int pos = 0;
char[] chars = new char[n];
int pos = 0;
while (pos < n) {
chars[pos] = this.next();
if (this.end()) {
throw this.syntaxError("Substring bounds error");
}
pos += 1;
}
return new String(chars);
}
while (pos < n) {
chars[pos] = this.next();
if (this.end()) {
throw this.syntaxError("Substring bounds error");
}
pos += 1;
}
return new String(chars);
}
/**
@ -266,7 +348,8 @@ public class JSONTokener {
case 0:
case '\n':
case '\r':
throw this.syntaxError("Unterminated string");
throw this.syntaxError("Unterminated string. " +
"Character with int code " + (int) c + " is not allowed within a quoted string.");
case '\\':
c = this.next();
switch (c) {
@ -286,10 +369,12 @@ public class JSONTokener {
sb.append('\r');
break;
case 'u':
String next = this.next(4);
try {
sb.append((char)Integer.parseInt(this.next(4), 16));
sb.append((char)Integer.parseInt(next, 16));
} catch (NumberFormatException e) {
throw this.syntaxError("Illegal escape.", e);
throw this.syntaxError("Illegal escape. " +
"\\u must be followed by a 4 digit hexadecimal number. \\" + next + " is not valid.", e);
}
break;
case '"':
@ -299,7 +384,7 @@ public class JSONTokener {
sb.append(c);
break;
default:
throw this.syntaxError("Illegal escape.");
throw this.syntaxError("Illegal escape. Escape sequence \\" + c + " is not valid.");
}
break;
default:
@ -369,18 +454,38 @@ public class JSONTokener {
*/
public Object nextValue() throws JSONException {
char c = this.nextClean();
switch (c) {
case '{':
this.back();
try {
return new JSONObject(this, jsonParserConfiguration);
} catch (StackOverflowError e) {
throw new JSONException("JSON Array or Object depth too large to process.", e);
}
case '[':
this.back();
try {
return new JSONArray(this, jsonParserConfiguration);
} catch (StackOverflowError e) {
throw new JSONException("JSON Array or Object depth too large to process.", e);
}
}
return nextSimpleValue(c);
}
Object nextSimpleValue(char c) {
String string;
// Strict mode only allows strings with explicit double quotes
if (jsonParserConfiguration != null &&
jsonParserConfiguration.isStrictMode() &&
c == '\'') {
throw this.syntaxError("Strict mode error: Single quoted strings are not allowed");
}
switch (c) {
case '"':
case '\'':
return this.nextString(c);
case '{':
this.back();
return new JSONObject(this);
case '[':
this.back();
return new JSONArray(this);
case '"':
case '\'':
return this.nextString(c);
}
/*
@ -397,13 +502,32 @@ public class JSONTokener {
sb.append(c);
c = this.next();
}
this.back();
if (!this.eof) {
this.back();
}
string = sb.toString().trim();
if ("".equals(string)) {
throw this.syntaxError("Missing value");
}
return JSONObject.stringToValue(string);
Object obj = JSONObject.stringToValue(string);
// if obj is a boolean, look at string
if (jsonParserConfiguration != null &&
jsonParserConfiguration.isStrictMode()) {
if (obj instanceof Boolean && !"true".equals(string) && !"false".equals(string)) {
// Strict mode only allows lowercase true or false
throw this.syntaxError(String.format("Strict mode error: Value '%s' is not lowercase boolean", obj));
}
else if (obj == JSONObject.NULL && !"null".equals(string)) {
// Strint mode only allows lowercase null
throw this.syntaxError(String.format("Strict mode error: Value '%s' is not lowercase null", obj));
}
else if (obj instanceof String) {
// Strict mode only allows strings with explicit double quotes
throw this.syntaxError(String.format("Strict mode error: Value '%s' is not surrounded by quotes", obj));
}
}
return obj;
}
@ -426,13 +550,17 @@ public class JSONTokener {
do {
c = this.next();
if (c == 0) {
// in some readers, reset() may throw an exception if
// the remaining portion of the input is greater than
// the mark size (1,000,000 above).
this.reader.reset();
this.index = startIndex;
this.character = startCharacter;
this.line = startLine;
return c;
return 0;
}
} while (c != to);
this.reader.mark(1);
} catch (IOException exception) {
throw new JSONException(exception);
}
@ -440,7 +568,6 @@ public class JSONTokener {
return c;
}
/**
* Make a JSONException to signal a syntax error.
*
@ -470,6 +597,17 @@ public class JSONTokener {
@Override
public String toString() {
return " at " + this.index + " [character " + this.character + " line " +
this.line + "]";
this.line + "]";
}
/**
* Closes the underlying reader, releasing any resources associated with it.
*
* @throws IOException If an I/O error occurs while closing the reader.
*/
public void close() throws IOException {
if(reader!=null){
reader.close();
}
}
}

View File

@ -1,327 +1,394 @@
package org.json;
import java.io.IOException;
import java.io.Writer;
/*
Copyright (c) 2006 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/**
* JSONWriter provides a quick and convenient way of producing JSON text.
* The texts produced strictly conform to JSON syntax rules. No whitespace is
* added, so the results are ready for transmission or storage. Each instance of
* JSONWriter can produce one JSON text.
* <p>
* A JSONWriter instance provides a <code>value</code> method for appending
* values to the
* text, and a <code>key</code>
* method for adding keys before values in objects. There are <code>array</code>
* and <code>endArray</code> methods that make and bound array values, and
* <code>object</code> and <code>endObject</code> methods which make and bound
* object values. All of these methods return the JSONWriter instance,
* permitting a cascade style. For example, <pre>
* new JSONWriter(myWriter)
* .object()
* .key("JSON")
* .value("Hello, World!")
* .endObject();</pre> which writes <pre>
* {"JSON":"Hello, World!"}</pre>
* <p>
* The first method called must be <code>array</code> or <code>object</code>.
* There are no methods for adding commas or colons. JSONWriter adds them for
* you. Objects and arrays can be nested up to 20 levels deep.
* <p>
* This can sometimes be easier than using a JSONObject to build a string.
* @author JSON.org
* @version 2015-12-09
*/
public class JSONWriter {
private static final int maxdepth = 200;
/**
* The comma flag determines if a comma should be output before the next
* value.
*/
private boolean comma;
/**
* The current mode. Values:
* 'a' (array),
* 'd' (done),
* 'i' (initial),
* 'k' (key),
* 'o' (object).
*/
protected char mode;
/**
* The object/array stack.
*/
private final JSONObject stack[];
/**
* The stack top index. A value of 0 indicates that the stack is empty.
*/
private int top;
/**
* The writer that will receive the output.
*/
protected Writer writer;
/**
* Make a fresh JSONWriter. It can be used to build one JSON text.
*/
public JSONWriter(Writer w) {
this.comma = false;
this.mode = 'i';
this.stack = new JSONObject[maxdepth];
this.top = 0;
this.writer = w;
}
/**
* Append a value.
* @param string A string value.
* @return this
* @throws JSONException If the value is out of sequence.
*/
private JSONWriter append(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null pointer");
}
if (this.mode == 'o' || this.mode == 'a') {
try {
if (this.comma && this.mode == 'a') {
this.writer.write(',');
}
this.writer.write(string);
} catch (IOException e) {
throw new JSONException(e);
}
if (this.mode == 'o') {
this.mode = 'k';
}
this.comma = true;
return this;
}
throw new JSONException("Value out of sequence.");
}
/**
* Begin appending a new array. All values until the balancing
* <code>endArray</code> will be appended to this array. The
* <code>endArray</code> method must be called to mark the array's end.
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter array() throws JSONException {
if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
this.push(null);
this.append("[");
this.comma = false;
return this;
}
throw new JSONException("Misplaced array.");
}
/**
* End something.
* @param mode Mode
* @param c Closing character
* @return this
* @throws JSONException If unbalanced.
*/
private JSONWriter end(char mode, char c) throws JSONException {
if (this.mode != mode) {
throw new JSONException(mode == 'a'
? "Misplaced endArray."
: "Misplaced endObject.");
}
this.pop(mode);
try {
this.writer.write(c);
} catch (IOException e) {
throw new JSONException(e);
}
this.comma = true;
return this;
}
/**
* End an array. This method most be called to balance calls to
* <code>array</code>.
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endArray() throws JSONException {
return this.end('a', ']');
}
/**
* End an object. This method most be called to balance calls to
* <code>object</code>.
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endObject() throws JSONException {
return this.end('k', '}');
}
/**
* Append a key. The key will be associated with the next value. In an
* object, every value must be preceded by a key.
* @param string A key string.
* @return this
* @throws JSONException If the key is out of place. For example, keys
* do not belong in arrays or if the key is null.
*/
public JSONWriter key(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null key.");
}
if (this.mode == 'k') {
try {
this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
if (this.comma) {
this.writer.write(',');
}
this.writer.write(JSONObject.quote(string));
this.writer.write(':');
this.comma = false;
this.mode = 'o';
return this;
} catch (IOException e) {
throw new JSONException(e);
}
}
throw new JSONException("Misplaced key.");
}
/**
* Begin appending a new object. All keys and values until the balancing
* <code>endObject</code> will be appended to this object. The
* <code>endObject</code> method must be called to mark the object's end.
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter object() throws JSONException {
if (this.mode == 'i') {
this.mode = 'o';
}
if (this.mode == 'o' || this.mode == 'a') {
this.append("{");
this.push(new JSONObject());
this.comma = false;
return this;
}
throw new JSONException("Misplaced object.");
}
/**
* Pop an array or object scope.
* @param c The scope to close.
* @throws JSONException If nesting is wrong.
*/
private void pop(char c) throws JSONException {
if (this.top <= 0) {
throw new JSONException("Nesting error.");
}
char m = this.stack[this.top - 1] == null ? 'a' : 'k';
if (m != c) {
throw new JSONException("Nesting error.");
}
this.top -= 1;
this.mode = this.top == 0
? 'd'
: this.stack[this.top - 1] == null
? 'a'
: 'k';
}
/**
* Push an array or object scope.
* @param jo The scope to open.
* @throws JSONException If nesting is too deep.
*/
private void push(JSONObject jo) throws JSONException {
if (this.top >= maxdepth) {
throw new JSONException("Nesting too deep.");
}
this.stack[this.top] = jo;
this.mode = jo == null ? 'a' : 'k';
this.top += 1;
}
/**
* Append either the value <code>true</code> or the value
* <code>false</code>.
* @param b A boolean.
* @return this
* @throws JSONException
*/
public JSONWriter value(boolean b) throws JSONException {
return this.append(b ? "true" : "false");
}
/**
* Append a double value.
* @param d A double.
* @return this
* @throws JSONException If the number is not finite.
*/
public JSONWriter value(double d) throws JSONException {
return this.value(new Double(d));
}
/**
* Append a long value.
* @param l A long.
* @return this
* @throws JSONException
*/
public JSONWriter value(long l) throws JSONException {
return this.append(Long.toString(l));
}
/**
* Append an object value.
* @param object The object to append. It can be null, or a Boolean, Number,
* String, JSONObject, or JSONArray, or an object that implements JSONString.
* @return this
* @throws JSONException If the value is out of sequence.
*/
public JSONWriter value(Object object) throws JSONException {
return this.append(JSONObject.valueToString(object));
}
}
package org.json;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
/*
Public Domain.
*/
/**
* JSONWriter provides a quick and convenient way of producing JSON text.
* The texts produced strictly conform to JSON syntax rules. No whitespace is
* added, so the results are ready for transmission or storage. Each instance of
* JSONWriter can produce one JSON text.
* <p>
* A JSONWriter instance provides a <code>value</code> method for appending
* values to the
* text, and a <code>key</code>
* method for adding keys before values in objects. There are <code>array</code>
* and <code>endArray</code> methods that make and bound array values, and
* <code>object</code> and <code>endObject</code> methods which make and bound
* object values. All of these methods return the JSONWriter instance,
* permitting a cascade style. For example, <pre>
* new JSONWriter(myWriter)
* .object()
* .key("JSON")
* .value("Hello, World!")
* .endObject();</pre> which writes <pre>
* {"JSON":"Hello, World!"}</pre>
* <p>
* The first method called must be <code>array</code> or <code>object</code>.
* There are no methods for adding commas or colons. JSONWriter adds them for
* you. Objects and arrays can be nested up to 200 levels deep.
* <p>
* This can sometimes be easier than using a JSONObject to build a string.
* @author JSON.org
* @version 2016-08-08
*/
public class JSONWriter {
private static final int maxdepth = 200;
/**
* The comma flag determines if a comma should be output before the next
* value.
*/
private boolean comma;
/**
* The current mode. Values:
* 'a' (array),
* 'd' (done),
* 'i' (initial),
* 'k' (key),
* 'o' (object).
*/
protected char mode;
/**
* The object/array stack.
*/
private final JSONObject stack[];
/**
* The stack top index. A value of 0 indicates that the stack is empty.
*/
private int top;
/**
* The writer that will receive the output.
*/
protected Appendable writer;
/**
* Make a fresh JSONWriter. It can be used to build one JSON text.
* @param w an appendable object
*/
public JSONWriter(Appendable w) {
this.comma = false;
this.mode = 'i';
this.stack = new JSONObject[maxdepth];
this.top = 0;
this.writer = w;
}
/**
* Append a value.
* @param string A string value.
* @return this
* @throws JSONException If the value is out of sequence.
*/
private JSONWriter append(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null pointer");
}
if (this.mode == 'o' || this.mode == 'a') {
try {
if (this.comma && this.mode == 'a') {
this.writer.append(',');
}
this.writer.append(string);
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
if (this.mode == 'o') {
this.mode = 'k';
}
this.comma = true;
return this;
}
throw new JSONException("Value out of sequence.");
}
/**
* Begin appending a new array. All values until the balancing
* <code>endArray</code> will be appended to this array. The
* <code>endArray</code> method must be called to mark the array's end.
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter array() throws JSONException {
if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
this.push(null);
this.append("[");
this.comma = false;
return this;
}
throw new JSONException("Misplaced array.");
}
/**
* End something.
* @param m Mode
* @param c Closing character
* @return this
* @throws JSONException If unbalanced.
*/
private JSONWriter end(char m, char c) throws JSONException {
if (this.mode != m) {
throw new JSONException(m == 'a'
? "Misplaced endArray."
: "Misplaced endObject.");
}
this.pop(m);
try {
this.writer.append(c);
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
this.comma = true;
return this;
}
/**
* End an array. This method most be called to balance calls to
* <code>array</code>.
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endArray() throws JSONException {
return this.end('a', ']');
}
/**
* End an object. This method most be called to balance calls to
* <code>object</code>.
* @return this
* @throws JSONException If incorrectly nested.
*/
public JSONWriter endObject() throws JSONException {
return this.end('k', '}');
}
/**
* Append a key. The key will be associated with the next value. In an
* object, every value must be preceded by a key.
* @param string A key string.
* @return this
* @throws JSONException If the key is out of place. For example, keys
* do not belong in arrays or if the key is null.
*/
public JSONWriter key(String string) throws JSONException {
if (string == null) {
throw new JSONException("Null key.");
}
if (this.mode == 'k') {
try {
JSONObject topObject = this.stack[this.top - 1];
// don't use the built in putOnce method to maintain Android support
if(topObject.has(string)) {
throw new JSONException("Duplicate key \"" + string + "\"");
}
topObject.put(string, true);
if (this.comma) {
this.writer.append(',');
}
this.writer.append(JSONObject.quote(string));
this.writer.append(':');
this.comma = false;
this.mode = 'o';
return this;
} catch (IOException e) {
// Android as of API 25 does not support this exception constructor
// however we won't worry about it. If an exception is happening here
// it will just throw a "Method not found" exception instead.
throw new JSONException(e);
}
}
throw new JSONException("Misplaced key.");
}
/**
* Begin appending a new object. All keys and values until the balancing
* <code>endObject</code> will be appended to this object. The
* <code>endObject</code> method must be called to mark the object's end.
* @return this
* @throws JSONException If the nesting is too deep, or if the object is
* started in the wrong place (for example as a key or after the end of the
* outermost array or object).
*/
public JSONWriter object() throws JSONException {
if (this.mode == 'i') {
this.mode = 'o';
}
if (this.mode == 'o' || this.mode == 'a') {
this.append("{");
this.push(new JSONObject());
this.comma = false;
return this;
}
throw new JSONException("Misplaced object.");
}
/**
* Pop an array or object scope.
* @param c The scope to close.
* @throws JSONException If nesting is wrong.
*/
private void pop(char c) throws JSONException {
if (this.top <= 0) {
throw new JSONException("Nesting error.");
}
char m = this.stack[this.top - 1] == null ? 'a' : 'k';
if (m != c) {
throw new JSONException("Nesting error.");
}
this.top -= 1;
this.mode = this.top == 0
? 'd'
: this.stack[this.top - 1] == null
? 'a'
: 'k';
}
/**
* Push an array or object scope.
* @param jo The scope to open.
* @throws JSONException If nesting is too deep.
*/
private void push(JSONObject jo) throws JSONException {
if (this.top >= maxdepth) {
throw new JSONException("Nesting too deep.");
}
this.stack[this.top] = jo;
this.mode = jo == null ? 'a' : 'k';
this.top += 1;
}
/**
* Make a JSON text of an Object value. If the object has an
* value.toJSONString() method, then that method will be used to produce the
* JSON text. The method is required to produce a strictly conforming text.
* If the object does not contain a toJSONString method (which is the most
* common case), then a text will be produced by other means. If the value
* is an array or Collection, then a JSONArray will be made from it and its
* toJSONString method will be called. If the value is a MAP, then a
* JSONObject will be made from it and its toJSONString method will be
* called. Otherwise, the value's toString method will be called, and the
* result will be quoted.
*
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @param value
* The value to be serialized.
* @return a printable, displayable, transmittable representation of the
* object, beginning with <code>{</code>&nbsp;<small>(left
* brace)</small> and ending with <code>}</code>&nbsp;<small>(right
* brace)</small>.
* @throws JSONException
* If the value is or contains an invalid number.
*/
public static String valueToString(Object value) throws JSONException {
if (value == null || value.equals(null)) {
return "null";
}
if (value instanceof JSONString) {
String object;
try {
object = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
if (object != null) {
return object;
}
throw new JSONException("Bad value from toJSONString: " + object);
}
if (value instanceof Number) {
// not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex
final String numberAsString = JSONObject.numberToString((Number) value);
if(JSONObject.NUMBER_PATTERN.matcher(numberAsString).matches()) {
// Close enough to a JSON number that we will return it unquoted
return numberAsString;
}
// The Number value is not a valid JSON number.
// Instead we will quote it as a string
return JSONObject.quote(numberAsString);
}
if (value instanceof Boolean || value instanceof JSONObject
|| value instanceof JSONArray) {
return value.toString();
}
if (value instanceof Map) {
Map<?, ?> map = (Map<?, ?>) value;
return new JSONObject(map).toString();
}
if (value instanceof Collection) {
Collection<?> coll = (Collection<?>) value;
return new JSONArray(coll).toString();
}
if (value.getClass().isArray()) {
return new JSONArray(value).toString();
}
if(value instanceof Enum<?>){
return JSONObject.quote(((Enum<?>)value).name());
}
return JSONObject.quote(value.toString());
}
/**
* Append either the value <code>true</code> or the value
* <code>false</code>.
* @param b A boolean.
* @return this
* @throws JSONException if a called function has an error
*/
public JSONWriter value(boolean b) throws JSONException {
return this.append(b ? "true" : "false");
}
/**
* Append a double value.
* @param d A double.
* @return this
* @throws JSONException If the number is not finite.
*/
public JSONWriter value(double d) throws JSONException {
return this.value(Double.valueOf(d));
}
/**
* Append a long value.
* @param l A long.
* @return this
* @throws JSONException if a called function has an error
*/
public JSONWriter value(long l) throws JSONException {
return this.append(Long.toString(l));
}
/**
* Append an object value.
* @param object The object to append. It can be null, or a Boolean, Number,
* String, JSONObject, or JSONArray, or an object that implements JSONString.
* @return this
* @throws JSONException If the value is out of sequence.
*/
public JSONWriter value(Object object) throws JSONException {
return this.append(valueToString(object));
}
}

View File

@ -0,0 +1,126 @@
package org.json;
/*
Public Domain.
*/
/**
* Configuration base object for parsers. The configuration is immutable.
*/
@SuppressWarnings({""})
public class ParserConfiguration {
/**
* Used to indicate there's no defined limit to the maximum nesting depth when parsing a document.
*/
public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1;
/**
* The default maximum nesting depth when parsing a document.
*/
public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512;
/**
* Specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string).
*/
protected boolean keepStrings;
/**
* The maximum nesting depth when parsing an object.
*/
protected int maxNestingDepth;
/**
* Constructs a new ParserConfiguration with default settings.
*/
public ParserConfiguration() {
this.keepStrings = false;
this.maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
}
/**
* Constructs a new ParserConfiguration with the specified settings.
*
* @param keepStrings A boolean indicating whether to preserve strings during parsing.
* @param maxNestingDepth An integer representing the maximum allowed nesting depth.
*/
protected ParserConfiguration(final boolean keepStrings, final int maxNestingDepth) {
this.keepStrings = keepStrings;
this.maxNestingDepth = maxNestingDepth;
}
/**
* Provides a new instance of the same configuration.
*/
@Override
protected ParserConfiguration clone() {
// future modifications to this method should always ensure a "deep"
// clone in the case of collections. i.e. if a Map is added as a configuration
// item, a new map instance should be created and if possible each value in the
// map should be cloned as well. If the values of the map are known to also
// be immutable, then a shallow clone of the map is acceptable.
return new ParserConfiguration(
this.keepStrings,
this.maxNestingDepth
);
}
/**
* When parsing the XML into JSONML, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string).
*
* @return The <code>keepStrings</code> configuration value.
*/
public boolean isKeepStrings() {
return this.keepStrings;
}
/**
* When parsing the XML into JSONML, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
* @param newVal new value to use for the <code>keepStrings</code> configuration option.
* @param <T> the type of the configuration object
* @return The existing configuration will not be modified. A new configuration is returned.
*/
@SuppressWarnings("unchecked")
public <T extends ParserConfiguration> T withKeepStrings(final boolean newVal) {
T newConfig = (T) this.clone();
newConfig.keepStrings = newVal;
return newConfig;
}
/**
* The maximum nesting depth that the parser will descend before throwing an exception
* when parsing an object (e.g. Map, Collection) into JSON-related objects.
*
* @return the maximum nesting depth set for this configuration
*/
public int getMaxNestingDepth() {
return maxNestingDepth;
}
/**
* Defines the maximum nesting depth that the parser will descend before throwing an exception
* when parsing an object (e.g. Map, Collection) into JSON-related objects.
* The default max nesting depth is 512, which means the parser will throw a JsonException if
* the maximum depth is reached.
* Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
* which means the parses will go as deep as the maximum call stack size allows.
*
* @param maxNestingDepth the maximum nesting depth allowed to the XML parser
* @param <T> the type of the configuration object
* @return The existing configuration will not be modified. A new configuration is returned.
*/
@SuppressWarnings("unchecked")
public <T extends ParserConfiguration> T withMaxNestingDepth(int maxNestingDepth) {
T newConfig = (T) this.clone();
if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
newConfig.maxNestingDepth = maxNestingDepth;
} else {
newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
}
return newConfig;
}
}

View File

@ -0,0 +1,62 @@
package org.json;
/*
Public Domain.
*/
import java.util.Enumeration;
import java.util.Properties;
/**
* Converts a Property file data into JSONObject and back.
* @author JSON.org
* @version 2015-05-05
*/
public class Property {
/**
* Constructs a new Property object.
*/
public Property() {
}
/**
* Converts a property file object into a JSONObject. The property file object is a table of name value pairs.
* @param properties java.util.Properties
* @return JSONObject
* @throws JSONException if a called function has an error
*/
public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException {
// can't use the new constructor for Android support
// JSONObject jo = new JSONObject(properties == null ? 0 : properties.size());
JSONObject jo = new JSONObject();
if (properties != null && !properties.isEmpty()) {
Enumeration<?> enumProperties = properties.propertyNames();
while(enumProperties.hasMoreElements()) {
String name = (String)enumProperties.nextElement();
jo.put(name, properties.getProperty(name));
}
}
return jo;
}
/**
* Converts the JSONObject into a property file object.
* @param jo JSONObject
* @return java.util.Properties
* @throws JSONException if a called function has an error
*/
public static Properties toProperties(JSONObject jo) throws JSONException {
Properties properties = new Properties();
if (jo != null) {
// Don't use the new entrySet API to maintain Android support
for (final String key : jo.keySet()) {
Object value = jo.opt(key);
if (!JSONObject.NULL.equals(value)) {
properties.put(key, value.toString());
}
}
}
return properties;
}
}

View File

@ -0,0 +1,92 @@
package org.json;
import java.io.IOException;
import java.io.Writer;
/**
* Performance optimised alternative for {@link java.io.StringWriter}
* using internally a {@link StringBuilder} instead of a {@link StringBuffer}.
*/
public class StringBuilderWriter extends Writer {
private final StringBuilder builder;
/**
* Create a new string builder writer using the default initial string-builder buffer size.
*/
public StringBuilderWriter() {
builder = new StringBuilder();
lock = builder;
}
/**
* Create a new string builder writer using the specified initial string-builder buffer size.
*
* @param initialSize The number of {@code char} values that will fit into this buffer
* before it is automatically expanded
*
* @throws IllegalArgumentException If {@code initialSize} is negative
*/
public StringBuilderWriter(int initialSize) {
builder = new StringBuilder(initialSize);
lock = builder;
}
@Override
public void write(int c) {
builder.append((char) c);
}
@Override
public void write(char[] cbuf, int offset, int length) {
if ((offset < 0) || (offset > cbuf.length) || (length < 0) ||
((offset + length) > cbuf.length) || ((offset + length) < 0)) {
throw new IndexOutOfBoundsException();
} else if (length == 0) {
return;
}
builder.append(cbuf, offset, length);
}
@Override
public void write(String str) {
builder.append(str);
}
@Override
public void write(String str, int offset, int length) {
builder.append(str, offset, offset + length);
}
@Override
public StringBuilderWriter append(CharSequence csq) {
write(String.valueOf(csq));
return this;
}
@Override
public StringBuilderWriter append(CharSequence csq, int start, int end) {
if (csq == null) {
csq = "null";
}
return append(csq.subSequence(start, end));
}
@Override
public StringBuilderWriter append(char c) {
write(c);
return this;
}
@Override
public String toString() {
return builder.toString();
}
@Override
public void flush() {
}
@Override
public void close() throws IOException {
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,444 @@
package org.json;
/*
Public Domain.
*/
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Configuration object for the XML parser. The configuration is immutable.
* @author AylwardJ
*/
@SuppressWarnings({""})
public class XMLParserConfiguration extends ParserConfiguration {
/**
* The default maximum nesting depth when parsing a XML document to JSON.
*/
// public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; // We could override
/**
* Allow user to control how numbers are parsed
*/
private boolean keepNumberAsString;
/**
* Allow user to control how booleans are parsed
*/
private boolean keepBooleanAsString;
/** Original Configuration of the XML Parser. */
public static final XMLParserConfiguration ORIGINAL
= new XMLParserConfiguration();
/** Original configuration of the XML Parser except that values are kept as strings. */
public static final XMLParserConfiguration KEEP_STRINGS
= new XMLParserConfiguration().withKeepStrings(true);
/**
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
* processing.
*/
private String cDataTagName;
/**
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(<code>false</code>), or they should be converted to
* <code>null</code>(<code>true</code>)
*/
private boolean convertNilAttributeToNull;
/**
* When creating an XML from JSON Object, an empty tag by default will self-close.
* If it has to be closed explicitly, with empty content between start and end tag,
* this flag is to be turned on.
*/
private boolean closeEmptyTag;
/**
* This will allow type conversion for values in XML if xsi:type attribute is defined
*/
private Map<String, XMLXsiTypeConverter<?>> xsiTypeMap;
/**
* When parsing the XML into JSON, specifies the tags whose values should be converted
* to arrays
*/
private Set<String> forceList;
/**
* Flag to indicate whether white space should be trimmed when parsing XML.
* The default behaviour is to trim white space. When this is set to false, inputting XML
* with tags that are the same as the value of cDataTagName is unsupported. It is recommended to set cDataTagName
* to a distinct value in this case.
*/
private boolean shouldTrimWhiteSpace;
/**
* Default parser configuration. Does not keep strings (tries to implicitly convert
* values), and the CDATA Tag Name is "content". Trims whitespace.
*/
public XMLParserConfiguration () {
super();
this.cDataTagName = "content";
this.convertNilAttributeToNull = false;
this.xsiTypeMap = Collections.emptyMap();
this.forceList = Collections.emptySet();
this.shouldTrimWhiteSpace = true;
}
/**
* Configure the parser string processing and use the default CDATA Tag Name as "content".
* @param keepStrings <code>true</code> to parse all values as string.
* <code>false</code> to try and convert XML string values into a JSON value.
* @deprecated This constructor has been deprecated in favor of using the new builder
* pattern for the configuration.
* This constructor may be removed in a future release.
*/
@Deprecated
public XMLParserConfiguration (final boolean keepStrings) {
this(keepStrings, "content", false);
}
/**
* Configure the parser string processing to try and convert XML values to JSON values and
* use the passed CDATA Tag Name the processing value. Pass <code>null</code> to
* disable CDATA processing
* @param cDataTagName <code>null</code> to disable CDATA processing. Any other value
* to use that value as the JSONObject key name to process as CDATA.
* @deprecated This constructor has been deprecated in favor of using the new builder
* pattern for the configuration.
* This constructor may be removed in a future release.
*/
@Deprecated
public XMLParserConfiguration (final String cDataTagName) {
this(false, cDataTagName, false);
}
/**
* Configure the parser to use custom settings.
* @param keepStrings <code>true</code> to parse all values as string.
* <code>false</code> to try and convert XML string values into a JSON value.
* @param cDataTagName <code>null</code> to disable CDATA processing. Any other value
* to use that value as the JSONObject key name to process as CDATA.
* @deprecated This constructor has been deprecated in favor of using the new builder
* pattern for the configuration.
* This constructor may be removed in a future release.
*/
@Deprecated
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName) {
super(keepStrings, DEFAULT_MAXIMUM_NESTING_DEPTH);
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = false;
}
/**
* Configure the parser to use custom settings.
* @param keepStrings <code>true</code> to parse all values as string.
* <code>false</code> to try and convert XML string values into a JSON value.
* @param cDataTagName <code>null</code> to disable CDATA processing. Any other value
* to use that value as the JSONObject key name to process as CDATA.
* @param convertNilAttributeToNull <code>true</code> to parse values with attribute xsi:nil="true" as null.
* <code>false</code> to parse values with attribute xsi:nil="true" as {"xsi:nil":true}.
* @deprecated This constructor has been deprecated in favor of using the new builder
* pattern for the configuration.
* This constructor may be removed or marked private in a future release.
*/
@Deprecated
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull) {
super(false, DEFAULT_MAXIMUM_NESTING_DEPTH);
this.keepNumberAsString = keepStrings;
this.keepBooleanAsString = keepStrings;
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = convertNilAttributeToNull;
}
/**
* Configure the parser to use custom settings.
* @param keepStrings <code>true</code> to parse all values as string.
* <code>false</code> to try and convert XML string values into a JSON value.
* @param cDataTagName <code>null</code> to disable CDATA processing. Any other value
* to use that value as the JSONObject key name to process as CDATA.
* @param convertNilAttributeToNull <code>true</code> to parse values with attribute xsi:nil="true" as null.
* <code>false</code> to parse values with attribute xsi:nil="true" as {"xsi:nil":true}.
* @param xsiTypeMap <code>new HashMap<String, XMLXsiTypeConverter<?>>()</code> to parse values with attribute
* xsi:type="integer" as integer, xsi:type="string" as string
* @param forceList <code>new HashSet<String>()</code> to parse the provided tags' values as arrays
* @param maxNestingDepth <code>int</code> to limit the nesting depth
* @param closeEmptyTag <code>boolean</code> to turn on explicit end tag for tag with empty value
*/
private XMLParserConfiguration (final boolean keepStrings, final String cDataTagName,
final boolean convertNilAttributeToNull, final Map<String, XMLXsiTypeConverter<?>> xsiTypeMap, final Set<String> forceList,
final int maxNestingDepth, final boolean closeEmptyTag, final boolean keepNumberAsString, final boolean keepBooleanAsString) {
super(false, maxNestingDepth);
this.keepNumberAsString = keepNumberAsString;
this.keepBooleanAsString = keepBooleanAsString;
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = convertNilAttributeToNull;
this.xsiTypeMap = Collections.unmodifiableMap(xsiTypeMap);
this.forceList = Collections.unmodifiableSet(forceList);
this.closeEmptyTag = closeEmptyTag;
}
/**
* Provides a new instance of the same configuration.
*/
@Override
protected XMLParserConfiguration clone() {
// future modifications to this method should always ensure a "deep"
// clone in the case of collections. i.e. if a Map is added as a configuration
// item, a new map instance should be created and if possible each value in the
// map should be cloned as well. If the values of the map are known to also
// be immutable, then a shallow clone of the map is acceptable.
final XMLParserConfiguration config = new XMLParserConfiguration(
this.keepStrings,
this.cDataTagName,
this.convertNilAttributeToNull,
this.xsiTypeMap,
this.forceList,
this.maxNestingDepth,
this.closeEmptyTag,
this.keepNumberAsString,
this.keepBooleanAsString
);
config.shouldTrimWhiteSpace = this.shouldTrimWhiteSpace;
return config;
}
/**
* When parsing the XML into JSON, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
* @param newVal
* new value to use for the <code>keepStrings</code> configuration option.
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
@SuppressWarnings("unchecked")
@Override
public XMLParserConfiguration withKeepStrings(final boolean newVal) {
XMLParserConfiguration newConfig = this.clone();
newConfig.keepStrings = newVal;
newConfig.keepNumberAsString = newVal;
newConfig.keepBooleanAsString = newVal;
return newConfig;
}
/**
* When parsing the XML into JSON, specifies if numbers should be kept as strings (<code>1</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
* @param newVal
* new value to use for the <code>keepNumberAsString</code> configuration option.
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withKeepNumberAsString(final boolean newVal) {
XMLParserConfiguration newConfig = this.clone();
newConfig.keepNumberAsString = newVal;
newConfig.keepStrings = newConfig.keepBooleanAsString && newConfig.keepNumberAsString;
return newConfig;
}
/**
* When parsing the XML into JSON, specifies if booleans should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
* @param newVal
* new value to use for the <code>withKeepBooleanAsString</code> configuration option.
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withKeepBooleanAsString(final boolean newVal) {
XMLParserConfiguration newConfig = this.clone();
newConfig.keepBooleanAsString = newVal;
newConfig.keepStrings = newConfig.keepBooleanAsString && newConfig.keepNumberAsString;
return newConfig;
}
/**
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
* processing.
*
* @return The <code>cDataTagName</code> configuration value.
*/
public String getcDataTagName() {
return this.cDataTagName;
}
/**
* When parsing the XML into JSONML, specifies if numbers should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string).
*
* @return The <code>keepStrings</code> configuration value.
*/
public boolean isKeepNumberAsString() {
return this.keepNumberAsString;
}
/**
* When parsing the XML into JSONML, specifies if booleans should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string).
*
* @return The <code>keepStrings</code> configuration value.
*/
public boolean isKeepBooleanAsString() {
return this.keepBooleanAsString;
}
/**
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
* processing.
*
* @param newVal
* new value to use for the <code>cDataTagName</code> configuration option.
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withcDataTagName(final String newVal) {
XMLParserConfiguration newConfig = this.clone();
newConfig.cDataTagName = newVal;
return newConfig;
}
/**
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(<code>false</code>), or they should be converted to
* <code>null</code>(<code>true</code>)
*
* @return The <code>convertNilAttributeToNull</code> configuration value.
*/
public boolean isConvertNilAttributeToNull() {
return this.convertNilAttributeToNull;
}
/**
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(<code>false</code>), or they should be converted to
* <code>null</code>(<code>true</code>)
*
* @param newVal
* new value to use for the <code>convertNilAttributeToNull</code> configuration option.
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withConvertNilAttributeToNull(final boolean newVal) {
XMLParserConfiguration newConfig = this.clone();
newConfig.convertNilAttributeToNull = newVal;
return newConfig;
}
/**
* When parsing the XML into JSON, specifies that the values with attribute xsi:type
* will be converted to target type defined to client in this configuration
* {@code Map<String, XMLXsiTypeConverter<?>>} to parse values with attribute
* xsi:type="integer" as integer, xsi:type="string" as string
* @return <code>xsiTypeMap</code> unmodifiable configuration map.
*/
public Map<String, XMLXsiTypeConverter<?>> getXsiTypeMap() {
return this.xsiTypeMap;
}
/**
* When parsing the XML into JSON, specifies that the values with attribute xsi:type
* will be converted to target type defined to client in this configuration
* {@code Map<String, XMLXsiTypeConverter<?>>} to parse values with attribute
* xsi:type="integer" as integer, xsi:type="string" as string
* @param xsiTypeMap {@code new HashMap<String, XMLXsiTypeConverter<?>>()} to parse values with attribute
* xsi:type="integer" as integer, xsi:type="string" as string
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withXsiTypeMap(final Map<String, XMLXsiTypeConverter<?>> xsiTypeMap) {
XMLParserConfiguration newConfig = this.clone();
Map<String, XMLXsiTypeConverter<?>> cloneXsiTypeMap = new HashMap<String, XMLXsiTypeConverter<?>>(xsiTypeMap);
newConfig.xsiTypeMap = Collections.unmodifiableMap(cloneXsiTypeMap);
return newConfig;
}
/**
* When parsing the XML into JSON, specifies that tags that will be converted to arrays
* in this configuration {@code Set<String>} to parse the provided tags' values as arrays
* @return <code>forceList</code> unmodifiable configuration set.
*/
public Set<String> getForceList() {
return this.forceList;
}
/**
* When parsing the XML into JSON, specifies that tags that will be converted to arrays
* in this configuration {@code Set<String>} to parse the provided tags' values as arrays
* @param forceList {@code new HashSet<String>()} to parse the provided tags' values as arrays
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withForceList(final Set<String> forceList) {
XMLParserConfiguration newConfig = this.clone();
Set<String> cloneForceList = new HashSet<String>(forceList);
newConfig.forceList = Collections.unmodifiableSet(cloneForceList);
return newConfig;
}
/**
* Defines the maximum nesting depth that the parser will descend before throwing an exception
* when parsing the XML into JSON. The default max nesting depth is 512, which means the parser
* will throw a JsonException if the maximum depth is reached.
* Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
* which means the parses will go as deep as the maximum call stack size allows.
* @param maxNestingDepth the maximum nesting depth allowed to the XML parser
* @return The existing configuration will not be modified. A new configuration is returned.
*/
@SuppressWarnings("unchecked")
@Override
public XMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) {
return super.withMaxNestingDepth(maxNestingDepth);
}
/**
* To enable explicit end tag with empty value.
* @param closeEmptyTag new value for the closeEmptyTag property
* @return same instance of configuration with empty tag config updated
*/
public XMLParserConfiguration withCloseEmptyTag(boolean closeEmptyTag){
XMLParserConfiguration clonedConfiguration = this.clone();
clonedConfiguration.closeEmptyTag = closeEmptyTag;
return clonedConfiguration;
}
/**
* Sets whether whitespace should be trimmed inside of tags. *NOTE* Do not use this if
* you expect your XML tags to have names that are the same as cDataTagName as this is unsupported.
* cDataTagName should be set to a distinct value in these cases.
* @param shouldTrimWhiteSpace boolean to set trimming on or off. Off is default.
* @return same instance of configuration with empty tag config updated
*/
public XMLParserConfiguration withShouldTrimWhitespace(boolean shouldTrimWhiteSpace){
XMLParserConfiguration clonedConfiguration = this.clone();
clonedConfiguration.shouldTrimWhiteSpace = shouldTrimWhiteSpace;
return clonedConfiguration;
}
/**
* Checks if the parser should automatically close empty XML tags.
*
* @return {@code true} if empty XML tags should be automatically closed, {@code false} otherwise.
*/
public boolean isCloseEmptyTag() {
return this.closeEmptyTag;
}
/**
* Checks if the parser should trim white spaces from XML content.
*
* @return {@code true} if white spaces should be trimmed, {@code false} otherwise.
*/
public boolean shouldTrimWhiteSpace() {
return this.shouldTrimWhiteSpace;
}
}

View File

@ -1,29 +1,11 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.io.Reader;
/**
* The XMLTokener extends the JSONTokener to provide additional methods
* for the parsing of XML texts.
@ -38,6 +20,8 @@ public class XMLTokener extends JSONTokener {
*/
public static final java.util.HashMap<String, Character> entity;
private XMLParserConfiguration configuration = XMLParserConfiguration.ORIGINAL;
static {
entity = new java.util.HashMap<String, Character>(8);
entity.put("amp", XML.AMP);
@ -47,6 +31,14 @@ public class XMLTokener extends JSONTokener {
entity.put("quot", XML.QUOT);
}
/**
* Construct an XMLTokener from a Reader.
* @param r A source reader.
*/
public XMLTokener(Reader r) {
super(r);
}
/**
* Construct an XMLTokener from a string.
* @param s A source string.
@ -55,6 +47,16 @@ public class XMLTokener extends JSONTokener {
super(s);
}
/**
* Construct an XMLTokener from a Reader and an XMLParserConfiguration.
* @param r A source reader.
* @param configuration the configuration that can be used to set certain flags
*/
public XMLTokener(Reader r, XMLParserConfiguration configuration) {
super(r);
this.configuration = configuration;
}
/**
* Get the text in the CDATA block.
* @return The string up to the <code>]]&gt;</code>.
@ -64,11 +66,8 @@ public class XMLTokener extends JSONTokener {
char c;
int i;
StringBuilder sb = new StringBuilder();
for (;;) {
while (more()) {
c = next();
if (end()) {
throw syntaxError("Unclosed CDATA");
}
sb.append(c);
i = sb.length() - 3;
if (i >= 0 && sb.charAt(i) == ']' &&
@ -77,24 +76,26 @@ public class XMLTokener extends JSONTokener {
return sb.toString();
}
}
throw syntaxError("Unclosed CDATA");
}
/**
* Get the next XML outer token, trimming whitespace. There are two kinds
* of tokens: the '<' character which begins a markup tag, and the content
* of tokens: the <pre>{@code '<' }</pre> character which begins a markup
* tag, and the content
* text between markup tags.
*
* @return A string, or a '<' Character, or null if there is no more
* source text.
* @throws JSONException
* @return A string, or a <pre>{@code '<' }</pre> Character, or null if
* there is no more source text.
* @throws JSONException if a called function has an error
*/
public Object nextContent() throws JSONException {
char c;
StringBuilder sb;
do {
c = next();
} while (Character.isWhitespace(c));
} while (Character.isWhitespace(c) && configuration.shouldTrimWhiteSpace());
if (c == 0) {
return null;
}
@ -103,10 +104,15 @@ public class XMLTokener extends JSONTokener {
}
sb = new StringBuilder();
for (;;) {
if (c == '<' || c == 0) {
back();
if (c == 0) {
return sb.toString().trim();
}
if (c == '<') {
back();
if (configuration.shouldTrimWhiteSpace()) {
return sb.toString().trim();
} else return sb.toString();
}
if (c == '&') {
sb.append(nextEntity(c));
} else {
@ -118,13 +124,15 @@ public class XMLTokener extends JSONTokener {
/**
* <pre>{@code
* Return the next entity. These entities are translated to Characters:
* <code>&amp; &apos; &gt; &lt; &quot;</code>.
* &amp; &apos; &gt; &lt; &quot;.
* }</pre>
* @param ampersand An ampersand character.
* @return A Character or an entity String if the entity is not recognized.
* @throws JSONException If missing ';' in XML entity.
*/
public Object nextEntity(char ampersand) throws JSONException {
public Object nextEntity(@SuppressWarnings("unused") char ampersand) throws JSONException {
StringBuilder sb = new StringBuilder();
for (;;) {
char c = next();
@ -137,17 +145,49 @@ public class XMLTokener extends JSONTokener {
}
}
String string = sb.toString();
Object object = entity.get(string);
return object != null ? object : ampersand + string + ";";
return unescapeEntity(string);
}
/**
* Unescape an XML entity encoding;
* @param e entity (only the actual entity value, not the preceding & or ending ;
* @return
*/
static String unescapeEntity(String e) {
// validate
if (e == null || e.isEmpty()) {
return "";
}
// if our entity is an encoded unicode point, parse it.
if (e.charAt(0) == '#') {
int cp;
if (e.charAt(1) == 'x' || e.charAt(1) == 'X') {
// hex encoded unicode
cp = Integer.parseInt(e.substring(2), 16);
} else {
// decimal encoded unicode
cp = Integer.parseInt(e.substring(1));
}
return new String(new int[] {cp},0,1);
}
Character knownEntity = entity.get(e);
if(knownEntity==null) {
// we don't know the entity so keep it encoded
return '&' + e + ';';
}
return knownEntity.toString();
}
/**
* <pre>{@code
* Returns the next XML meta token. This is used for skipping over <!...>
* and <?...?> structures.
* @return Syntax characters (<code>< > / = ! ?</code>) are returned as
* }</pre>
* @return <pre>{@code Syntax characters (< > / = ! ?) are returned as
* Character, and strings and names are returned as Boolean. We don't care
* what the values actually are.
* }</pre>
* @throws JSONException If a string is not properly closed or if the XML
* is badly structured.
*/
@ -192,6 +232,7 @@ public class XMLTokener extends JSONTokener {
}
switch (c) {
case 0:
throw syntaxError("Unterminated string");
case '<':
case '>':
case '/':
@ -209,10 +250,12 @@ public class XMLTokener extends JSONTokener {
/**
* <pre>{@code
* Get the next XML Token. These tokens are found inside of angle
* brackets. It may be one of these characters: <code>/ > = ! ?</code> or it
* brackets. It may be one of these characters: / > = ! ? or it
* may be a string wrapped in single quotes or double quotes, or it may be a
* name.
* }</pre>
* @return a String or a Character.
* @throws JSONException If the XML is not well formed.
*/
@ -296,9 +339,11 @@ public class XMLTokener extends JSONTokener {
* Skip characters until past the requested string.
* If it is not found, we are left at the end of the source with a result of false.
* @param to A string to skip past.
* @throws JSONException
*/
public boolean skipPast(String to) throws JSONException {
// The Android implementation of JSONTokener has a public method of public void skipPast(String to)
// even though ours does not have that method, to have API compatibility, our method in the subclass
// should match.
public void skipPast(String to) {
boolean b;
char c;
int i;
@ -315,7 +360,7 @@ public class XMLTokener extends JSONTokener {
for (i = 0; i < length; i += 1) {
c = next();
if (c == 0) {
return false;
return;
}
circle[i] = c;
}
@ -342,14 +387,14 @@ public class XMLTokener extends JSONTokener {
/* If we exit the loop with b intact, then victory is ours. */
if (b) {
return true;
return;
}
/* Get the next character. If there isn't one, then defeat is ours. */
c = next();
if (c == 0) {
return false;
return;
}
/*
* Shove the character in the circle buffer and advance the

View File

@ -0,0 +1,53 @@
package org.json;
/*
Public Domain.
*/
/**
* Type conversion configuration interface to be used with xsi:type attributes.
* <pre>
* <b>XML Sample</b>
* {@code
* <root>
* <asString xsi:type="string">12345</asString>
* <asInt xsi:type="integer">54321</asInt>
* </root>
* }
* <b>JSON Output</b>
* {@code
* {
* "root" : {
* "asString" : "12345",
* "asInt": 54321
* }
* }
* }
*
* <b>Usage</b>
* {@code
* Map<String, XMLXsiTypeConverter<?>> xsiTypeMap = new HashMap<String, XMLXsiTypeConverter<?>>();
* xsiTypeMap.put("string", new XMLXsiTypeConverter<String>() {
* &#64;Override public String convert(final String value) {
* return value;
* }
* });
* xsiTypeMap.put("integer", new XMLXsiTypeConverter<Integer>() {
* &#64;Override public Integer convert(final String value) {
* return Integer.valueOf(value);
* }
* });
* }
* </pre>
* @author kumar529
* @param <T> return type of convert method
*/
public interface XMLXsiTypeConverter<T> {
/**
* Converts an XML xsi:type attribute value to the specified type {@code T}.
*
* @param value The string representation of the XML xsi:type attribute value to be converted.
* @return An object of type {@code T} representing the converted value.
*/
T convert(String value);
}

View File

@ -0,0 +1,392 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import org.junit.Test;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.CDL;
/**
* Tests for CDL.java.
* CDL provides an application level API, but it is not used by the
* reference app. To test it, strings will be converted to JSON-Java classes
* and then converted back.
*/
public class CDLTest {
/**
* String of lines where the column names are in the first row,
* and all subsequent rows are values. All keys and values should be legal.
*/
private static final String LINES = "Col 1, Col 2, \tCol 3, Col 4, Col 5, Col 6, Col 7\n" +
"val1, val2, val3, val4, val5, val6, val7\n" +
"1, 2, 3, 4\t, 5, 6, 7\n" +
"true, false, true, true, false, false, false\n" +
"0.23, 57.42, 5e27, -234.879, 2.34e5, 0.0, 9e-3\n" +
"\"va\tl1\", \"v\bal2\", \"val3\", \"val\f4\", \"val5\", \"va'l6\", val7\n";
/**
* CDL.toJSONArray() adds all values as strings, with no filtering or
* conversions. For testing, this means that the expected JSONObject
* values all must be quoted in the cases where the JSONObject parsing
* might normally convert the value into a non-string.
*/
private static final String EXPECTED_LINES =
"[ " +
"{" +
"\"Col 1\":\"val1\", " +
"\"Col 2\":\"val2\", " +
"\"Col 3\":\"val3\", " +
"\"Col 4\":\"val4\", " +
"\"Col 5\":\"val5\", " +
"\"Col 6\":\"val6\", " +
"\"Col 7\":\"val7\"" +
"}, " +
" {" +
"\"Col 1\":\"1\", " +
"\"Col 2\":\"2\", " +
"\"Col 3\":\"3\", " +
"\"Col 4\":\"4\", " +
"\"Col 5\":\"5\", " +
"\"Col 6\":\"6\", " +
"\"Col 7\":\"7\"" +
"}, " +
" {" +
"\"Col 1\":\"true\", " +
"\"Col 2\":\"false\", " +
"\"Col 3\":\"true\", " +
"\"Col 4\":\"true\", " +
"\"Col 5\":\"false\", " +
"\"Col 6\":\"false\", " +
"\"Col 7\":\"false\"" +
"}, " +
"{" +
"\"Col 1\":\"0.23\", " +
"\"Col 2\":\"57.42\", " +
"\"Col 3\":\"5e27\", " +
"\"Col 4\":\"-234.879\", " +
"\"Col 5\":\"2.34e5\", " +
"\"Col 6\":\"0.0\", " +
"\"Col 7\":\"9e-3\"" +
"}, " +
"{" +
"\"Col 1\":\"va\tl1\", " +
"\"Col 2\":\"v\bal2\", " +
"\"Col 3\":\"val3\", " +
"\"Col 4\":\"val\f4\", " +
"\"Col 5\":\"val5\", " +
"\"Col 6\":\"va'l6\", " +
"\"Col 7\":\"val7\"" +
"}" +
"]";
/**
* Attempts to create a JSONArray from a null string.
* Expect a NullPointerException.
*/
@Test(expected=NullPointerException.class)
public void exceptionOnNullString() {
String nullStr = null;
CDL.toJSONArray(nullStr);
}
/**
* Attempts to create a JSONArray from a string with unbalanced quotes
* in column title line. Expects a JSONException.
*/
@Test
public void unbalancedQuoteInName() {
String badLine = "Col1, \"Col2\nVal1, Val2";
try {
CDL.toJSONArray(badLine);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Missing close quote '\"'. at 12 [character 0 line 2]",
e.getMessage());
}
}
/**
* Attempts to create a JSONArray from a string with unbalanced quotes
* in value line. Expects a JSONException.
*/
@Test
public void unbalancedQuoteInValue() {
String badLine = "Col1, Col2\n\"Val1, Val2";
try {
CDL.toJSONArray(badLine);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Missing close quote '\"'. at 22 [character 11 line 2]",
e.getMessage());
}
}
/**
* Attempts to create a JSONArray from a string with null char
* in column title line. Expects a JSONException.
*/
@Test
public void nullInName() {
String badLine = "C\0ol1, Col2\nVal1, Val2";
try {
CDL.toJSONArray(badLine);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Bad character 'o' (111). at 2 [character 3 line 1]",
e.getMessage());
}
}
/**
* Attempt to create a JSONArray with unbalanced quotes and a properly escaped doubled quote.
* Expects a JSONException.
*/
@Test
public void unbalancedEscapedQuote(){
String badLine = "Col1, Col2\n\"Val1, \"\"Val2\"\"";
try {
CDL.toJSONArray(badLine);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Missing close quote '\"'. at 26 [character 15 line 2]",
e.getMessage());
}
}
/**
* Csv parsing skip last row if last field of this row is empty #943
*/
@Test
public void csvParsingCatchesLastRow(){
String data = "Field 1,Field 2,Field 3\n" +
"value11,value12,\n" +
"value21,value22,";
JSONArray jsonArray = CDL.toJSONArray(data);
JSONArray expectedJsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonObject.put("Field 1", "value11");
jsonObject.put("Field 2", "value12");
jsonObject.put("Field 3", "");
expectedJsonArray.put(jsonObject);
jsonObject = new JSONObject();
jsonObject.put("Field 1", "value21");
jsonObject.put("Field 2", "value22");
jsonObject.put("Field 3", "");
expectedJsonArray.put(jsonObject);
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
}
/**
* Assert that there is no error for a single escaped quote within a properly embedded quote.
*/
@Test
public void singleEscapedQuote(){
String singleEscape = "Col1, Col2\nVal1, \"\"\"Val2\"";
JSONArray jsonArray = CDL.toJSONArray(singleEscape);
String cdlStr = CDL.toString(jsonArray);
assertTrue(cdlStr.contains("Col1"));
assertTrue(cdlStr.contains("Col2"));
assertTrue(cdlStr.contains("Val1"));
assertTrue(cdlStr.contains("\"Val2"));
}
/**
* Assert that there is no error for a single escaped quote within a properly
* embedded quote when not the last value.
*/
@Test
public void singleEscapedQuoteMiddleString(){
String singleEscape = "Col1, Col2\nVal1, \"\"\"Val2\"\nVal 3,Val 4";
JSONArray jsonArray = CDL.toJSONArray(singleEscape);
String cdlStr = CDL.toString(jsonArray);
assertTrue(cdlStr.contains("Col1"));
assertTrue(cdlStr.contains("Col2"));
assertTrue(cdlStr.contains("Val1"));
assertTrue(cdlStr.contains("\"Val2"));
}
/**
* Attempt to create a JSONArray with an escape quote and no enclosing quotes.
* Expects a JSONException.
*/
@Test
public void badEscapedQuote(){
String badLine = "Col1, Col2\nVal1, \"\"Val2";
try {
CDL.toJSONArray(badLine);
fail("Expecting an exception");
} catch (JSONException e) {
//System.out.println("Message" + e.getMessage());
assertEquals("Expecting an exception message",
"Bad character 'V' (86). at 20 [character 9 line 2]",
e.getMessage());
}
}
/**
* call toString with a null array
*/
@Test(expected=NullPointerException.class)
public void nullJSONArrayToString() {
CDL.toString((JSONArray)null);
}
/**
* Create a JSONArray from an empty string
*/
@Test
public void emptyString() {
String emptyStr = "";
JSONArray jsonArray = CDL.toJSONArray(emptyStr);
assertNull("CDL should return null when the input string is empty", jsonArray);
}
/**
* Create a JSONArray with only 1 row
*/
@Test
public void onlyColumnNames() {
String columnNameStr = "col1, col2, col3";
JSONArray jsonArray = CDL.toJSONArray(columnNameStr);
assertNull("CDL should return null when only 1 row is given",
jsonArray);
}
/**
* Create a JSONArray from string containing only whitespace and commas
*/
@Test
public void emptyLinesToJSONArray() {
String str = " , , , \n , , , ";
JSONArray jsonArray = CDL.toJSONArray(str);
assertNull("JSONArray should be null for no content",
jsonArray);
}
/**
* call toString with a null array
*/
@Test
public void emptyJSONArrayToString() {
JSONArray jsonArray = new JSONArray();
String str = CDL.toString(jsonArray);
assertNull("CDL should return null for toString(null)",
str);
}
/**
* call toString with a null arrays for names and values
*/
@Test
public void nullJSONArraysToString() {
String str = CDL.toString(null, null);
assertNull("CDL should return null for toString(null)",
str);
}
/**
* Given a JSONArray that was not built by CDL, some chars may be
* found that would otherwise be filtered out by CDL.
*/
@Test
public void checkSpecialChars() {
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonArray.put(jsonObject);
// \r will be filtered from name
jsonObject.put("Col \r1", "V1");
// \r will be filtered from value
jsonObject.put("Col 2", "V2\r");
assertEquals("expected length should be 1", 1, jsonArray.length());
String cdlStr = CDL.toString(jsonArray);
jsonObject = jsonArray.getJSONObject(0);
assertTrue(cdlStr.contains("\"Col 1\""));
assertTrue(cdlStr.contains("Col 2"));
assertTrue(cdlStr.contains("V1"));
assertTrue(cdlStr.contains("\"V2\""));
}
/**
* Create a JSONArray from a string of lines
*/
@Test
public void textToJSONArray() {
JSONArray jsonArray = CDL.toJSONArray(LINES);
JSONArray expectedJsonArray = new JSONArray(EXPECTED_LINES);
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
}
@Test
public void textToJSONArrayPipeDelimited() {
char delimiter = '|';
JSONArray jsonArray = CDL.toJSONArray(LINES.replaceAll(",", String.valueOf(delimiter)), delimiter);
JSONArray expectedJsonArray = new JSONArray(EXPECTED_LINES);
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
}
/**
* Create a JSONArray from a JSONArray of titles and a
* string of value lines
*/
@Test
public void jsonArrayToJSONArray() {
String nameArrayStr = "[\"Col1\", \"Col2\"]";
String values = "V1, V2";
JSONArray nameJSONArray = new JSONArray(nameArrayStr);
JSONArray jsonArray = CDL.toJSONArray(nameJSONArray, values);
JSONArray expectedJsonArray = new JSONArray("[{\"Col1\":\"V1\",\"Col2\":\"V2\"}]");
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
}
/**
* Create a JSONArray from a string of lines,
* then convert to string and then back to JSONArray
*/
@Test
public void textToJSONArrayAndBackToString() {
JSONArray jsonArray = CDL.toJSONArray(LINES);
String jsonStr = CDL.toString(jsonArray);
JSONArray finalJsonArray = CDL.toJSONArray(jsonStr);
JSONArray expectedJsonArray = new JSONArray(EXPECTED_LINES);
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
}
/**
* Create a JSONArray from a string of lines,
* then convert to string and then back to JSONArray
* with a custom delimiter
*/
@Test
public void textToJSONArrayAndBackToStringCustomDelimiter() {
JSONArray jsonArray = CDL.toJSONArray(LINES, ',');
String jsonStr = CDL.toString(jsonArray, ';');
JSONArray finalJsonArray = CDL.toJSONArray(jsonStr, ';');
JSONArray expectedJsonArray = new JSONArray(EXPECTED_LINES);
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
}
}

View File

@ -0,0 +1,190 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import java.util.*;
import org.json.*;
import org.junit.Test;
import com.jayway.jsonpath.*;
/**
* HTTP cookie specification RFC6265: http://tools.ietf.org/html/rfc6265
* <p>
* A cookie list is a JSONObject whose members are presumed to be cookie
* name/value pairs. Entries are unescaped while being added, and escaped in
* the toString() output.
* Unescaping means to convert %hh hex strings to the ascii equivalent
* and converting '+' to ' '.
* Escaping converts '+', '%', '=', ';' and ascii control chars to %hh hex strings.
* <p>
* CookieList should not be considered as just a list of Cookie objects:<br>
* - CookieList stores a cookie name/value pair as a single entry; Cookie stores
* it as 2 entries (key="name" and key="value").<br>
* - CookieList requires multiple name/value pairs as input; Cookie allows the
* 'secure' name with no associated value<br>
* - CookieList has no special handling for attribute name/value pairs.<br>
*/
public class CookieListTest {
/**
* Attempts to create a CookieList from a null string.
* Expects a NullPointerException.
*/
@Test(expected=NullPointerException.class)
public void nullCookieListException() {
String cookieStr = null;
CookieList.toJSONObject(cookieStr);
}
/**
* Attempts to create a CookieList from a malformed string.
* Expects a JSONException.
*/
@Test
public void malFormedCookieListException() {
String cookieStr = "thisCookieHasNoEqualsChar";
try {
CookieList.toJSONObject(cookieStr);
fail("should throw an exception");
} catch (JSONException e) {
/**
* Not sure of the missing char, but full string compare fails
*/
assertEquals("Expecting an exception message",
"Expected '=' and instead saw '' at 25 [character 26 line 1]",
e.getMessage());
}
}
/**
* Creates a CookieList from an empty string.
*/
@Test
public void emptyStringCookieList() {
String cookieStr = "";
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
assertTrue(jsonObject.isEmpty());
}
/**
* CookieList with the simplest cookie - a name/value pair with no delimiter.
*/
@Test
public void simpleCookieList() {
String cookieStr = "SID=31d4d96e407aad42";
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("Expected 1 top level item", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
assertTrue("expected 31d4d96e407aad42", "31d4d96e407aad42".equals(jsonObject.query("/SID")));
}
/**
* CookieList with a single a cookie which has a name/value pair and delimiter.
*/
@Test
public void simpleCookieListWithDelimiter() {
String cookieStr = "SID=31d4d96e407aad42;";
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("Expected 1 top level item", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
assertTrue("expected 31d4d96e407aad42", "31d4d96e407aad42".equals(jsonObject.query("/SID")));
}
/**
* CookieList with multiple cookies consisting of name/value pairs
* with delimiters.
*/
@Test
public void multiPartCookieList() {
String cookieStr =
"name1=myCookieValue1; "+
" name2=myCookieValue2;"+
"name3=myCookieValue3;"+
" name4=myCookieValue4; "+
"name5=myCookieValue5;"+
" name6=myCookieValue6;";
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("Expected 6 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 6);
assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
assertTrue("expected myCookieValue2", "myCookieValue2".equals(jsonObject.query("/name2")));
assertTrue("expected myCookieValue3", "myCookieValue3".equals(jsonObject.query("/name3")));
assertTrue("expected myCookieValue4", "myCookieValue4".equals(jsonObject.query("/name4")));
assertTrue("expected myCookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
}
/**
* CookieList from a JSONObject with valid key and null value
*/
@Test
public void convertCookieListWithNullValueToString() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", JSONObject.NULL);
String cookieToStr = CookieList.toString(jsonObject);
assertTrue("toString() should be empty", "".equals(cookieToStr));
}
/**
* CookieList with multiple entries converted to a JSON document.
*/
@Test
public void convertCookieListToString() {
String cookieStr =
"name1=myCookieValue1; "+
" name2=myCookieValue2;"+
"name3=myCookieValue3;"+
" name4=myCookieValue4; "+
"name5=myCookieValue5;"+
" name6=myCookieValue6;";
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
// exercise CookieList.toString()
String cookieListString = CookieList.toString(jsonObject);
// have to convert it back for validation
jsonObject = CookieList.toJSONObject(cookieListString);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("Expected 6 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 6);
assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
assertTrue("expected myCookieValue2", "myCookieValue2".equals(jsonObject.query("/name2")));
assertTrue("expected myCookieValue3", "myCookieValue3".equals(jsonObject.query("/name3")));
assertTrue("expected myCookieValue4", "myCookieValue4".equals(jsonObject.query("/name4")));
assertTrue("expected myCookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
}
/**
* CookieList with multiple entries and some '+' chars and URL-encoded
* values converted to a JSON document.
*/
@Test
public void convertEncodedCookieListToString() {
String cookieStr =
"name1=myCookieValue1; "+
" name2=my+Cookie+Value+2;"+
"name3=my%2BCookie%26Value%3B3%3D;"+
" name4=my%25CookieValue4; "+
"name5=myCookieValue5;"+
" name6=myCookieValue6;";
JSONObject jsonObject = CookieList.toJSONObject(cookieStr);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("Expected 6 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 6);
assertTrue("expected myCookieValue1", "myCookieValue1".equals(jsonObject.query("/name1")));
assertTrue("expected my Cookie Value 2", "my Cookie Value 2".equals(jsonObject.query("/name2")));
assertTrue("expected my+Cookie&Value;3=", "my+Cookie&Value;3=".equals(jsonObject.query("/name3")));
assertTrue("expected my%CookieValue4", "my%CookieValue4".equals(jsonObject.query("/name4")));
assertTrue("expected my%CookieValue5", "myCookieValue5".equals(jsonObject.query("/name5")));
assertTrue("expected myCookieValue6", "myCookieValue6".equals(jsonObject.query("/name6")));
}
}

View File

@ -0,0 +1,242 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import org.json.*;
import org.junit.Test;
/**
* HTTP cookie specification: RFC6265
* <p>
* At its most basic, a cookie is a name=value pair. The value may be subdivided
* into other cookies, but that is not tested here. The cookie may also include
* certain named attributes, delimited by semicolons.
* <p>
* The Cookie.toString() method emits certain attributes if present: expires,
* domain, path, secure. All but secure are name-value pairs. Other attributes
* are not included in the toString() output.
* <p>
* A JSON-Java encoded cookie escapes '+', '%', '=', ';' with %hh values.
*/
public class CookieTest {
/**
* Attempts to create a JSONObject from a null string.
* Expects a NullPointerException.
*/
@Test(expected=NullPointerException.class)
public void nullCookieException() {
String cookieStr = null;
Cookie.toJSONObject(cookieStr);
}
/**
* Attempts to create a JSONObject from a cookie string with
* no '=' char.
* Expects a JSONException.
*/
@Test
public void malFormedNameValueException() {
String cookieStr = "thisCookieHasNoEqualsChar";
try {
Cookie.toJSONObject(cookieStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Expected '=' and instead saw '' at 25 [character 26 line 1]",
e.getMessage());
}
}
/**
* Attempts to create a JSONObject from a cookie string
* with embedded ';' char.
* Expects a JSONException.
*/
@Test
public void booleanAttribute() {
String cookieStr = "this=Cookie;myAttribute";
JSONObject jo = Cookie.toJSONObject(cookieStr);
assertTrue("has key 'name'", jo.has("name"));
assertTrue("has key 'value'", jo.has("value"));
assertTrue("has key 'myAttribute'", jo.has("myattribute"));
}
/**
* Attempts to create a JSONObject from an empty cookie string.<br>
* Note: Cookie throws an exception, but CookieList does not.<br>
* Expects a JSONException
*/
@Test
public void emptyStringCookieException() {
String cookieStr = "";
try {
Cookie.toJSONObject(cookieStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Cookies must have a 'name'",
e.getMessage());
}
}
/**
*
* Attempts to create a JSONObject from an cookie string where the name is blank.<br>
* Note: Cookie throws an exception, but CookieList does not.<br>
* Expects a JSONException
*/
@Test
public void emptyNameCookieException() {
String cookieStr = " = value ";
try {
Cookie.toJSONObject(cookieStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Cookies must have a 'name'",
e.getMessage());
}
}
/**
* Cookie from a simple name/value pair with no delimiter
*/
@Test
public void simpleCookie() {
String cookieStr = "SID=31d4d96e407aad42";
String expectedCookieStr = "{\"name\":\"SID\",\"value\":\"31d4d96e407aad42\"}";
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
}
/**
* Store a cookie with all of the supported attributes in a
* JSONObject. The secure attribute, which has no value, is treated
* as a boolean.
*/
@Test
public void multiPartCookie() {
String cookieStr =
"PH=deleted; "+
" expires=Wed, 19-Mar-2014 17:53:53 GMT;"+
"path=/; "+
" domain=.yahoo.com;"+
"secure";
String expectedCookieStr =
"{"+
"\"name\":\"PH\","+
"\"value\":\"deleted\","+
"\"path\":\"/\","+
"\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
"\"domain\":\".yahoo.com\","+
"\"secure\":true"+
"}";
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
}
/**
* Cookie.toString() will emit the non-standard "thiswont=beIncluded"
* attribute, and the attribute is still stored in the JSONObject.
* This test confirms both behaviors.
*/
@Test
public void convertCookieToString() {
String cookieStr =
"PH=deleted; "+
" expires=Wed, 19-Mar-2014 17:53:53 GMT;"+
"path=/; "+
" domain=.yahoo.com;"+
"thisWont=beIncluded;"+
"secure";
String expectedCookieStr =
"{\"thiswont\":\"beIncluded\","+
"\"path\":\"/\","+
"\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
"\"domain\":\".yahoo.com\","+
"\"name\":\"PH\","+
"\"secure\":true,"+
"\"value\":\"deleted\"}";
// Add the nonstandard attribute to the expected cookie string
String expectedDirectCompareCookieStr = expectedCookieStr;
// convert all strings into JSONObjects
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
JSONObject expectedDirectCompareJsonObject =
new JSONObject(expectedDirectCompareCookieStr);
// emit the string
String cookieToStr = Cookie.toString(jsonObject);
// create a final JSONObject from the string
JSONObject finalJsonObject = Cookie.toJSONObject(cookieToStr);
// JSONObject should contain the nonstandard string
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedDirectCompareJsonObject);
// JSONObject -> string -> JSONObject should not contain the nonstandard string
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
}
/**
* A string may be URL-encoded when converting to JSONObject.
* If found, '+' is converted to ' ', and %hh hex strings are converted
* to their ascii char equivalents. This test confirms the decoding
* behavior.
*/
@Test
public void convertEncodedCookieToString() {
String cookieStr =
"PH=deleted; "+
" expires=Wed,+19-Mar-2014+17:53:53+GMT;"+
"path=/%2Bthis/is%26/a/spec%3Bsegment%3D; "+
" domain=.yahoo.com;"+
"secure";
String expectedCookieStr =
"{\"path\":\"/+this/is&/a/spec;segment=\","+
"\"expires\":\"Wed, 19-Mar-2014 17:53:53 GMT\","+
"\"domain\":\".yahoo.com\","+
"\"name\":\"PH\","+
"\"secure\":true,"+
"\"value\":\"deleted\"}";
JSONObject jsonObject = Cookie.toJSONObject(cookieStr);
JSONObject expectedJsonObject = new JSONObject(expectedCookieStr);
String cookieToStr = Cookie.toString(jsonObject);
JSONObject finalJsonObject = Cookie.toJSONObject(cookieToStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
}
/**
* A public API method performs a URL encoding for selected chars
* in a string. Control chars, '+', '%', '=', ';' are all encoded
* as %hh hex strings. The string is also trimmed.
* This test confirms that behavior.
*/
@Test
public void escapeString() {
String str = " +%\r\n\t\b%=;;; ";
String expectedStr = "%2b%25%0d%0a%09%08%25%3d%3b%3b%3b";
String actualStr = Cookie.escape(str);
assertTrue("expect escape() to encode correctly. Actual: " +actualStr+
" expected: " +expectedStr, expectedStr.equals(actualStr));
}
/**
* A public API method performs URL decoding for strings.
* '+' is converted to space and %hh hex strings are converted to
* their ascii equivalent values. The string is not trimmed.
* This test confirms that behavior.
*/
@Test
public void unescapeString() {
String str = " +%2b%25%0d%0a%09%08%25%3d%3b%3b%3b+ ";
String expectedStr = " +%\r\n\t\b%=;;; ";
String actualStr = Cookie.unescape(str);
assertTrue("expect unescape() to decode correctly. Actual: " +actualStr+
" expected: " +expectedStr, expectedStr.equals(actualStr));
}
}

View File

@ -0,0 +1,433 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.junit.data.MyEnum;
import org.json.junit.data.MyEnumClass;
import org.json.junit.data.MyEnumField;
import org.junit.Test;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
/**
* Enums are not explicitly supported in JSON-Java. But because enums act like
* classes, all required behavior is already be present in some form.
* These tests explore how enum serialization works with JSON-Java.
*/
public class EnumTest {
/**
* To serialize an enum by its getters, use the JSONObject Object constructor.
* The JSONObject ctor handles enum like any other bean. A JSONobject
* is created whose entries are the getter name/value pairs.
*/
@Test
public void jsonObjectFromEnum() {
// If there are no getters then the object is empty.
MyEnum myEnum = MyEnum.VAL2;
JSONObject jsonObject = new JSONObject(myEnum);
assertTrue("simple enum has no getters", jsonObject.isEmpty());
// enum with a getters should create a non-empty object
MyEnumField myEnumField = MyEnumField.VAL2;
jsonObject = new JSONObject(myEnumField);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider()
.parse(jsonObject.toString());
assertTrue("expecting 2 items in top level object", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expecting val 2", "val 2".equals(jsonObject.query("/value")));
assertTrue("expecting 2", Integer.valueOf(2).equals(jsonObject.query("/intVal")));
/**
* class which contains enum instances. Each enum should be stored
* in its own JSONObject
*/
MyEnumClass myEnumClass = new MyEnumClass();
myEnumClass.setMyEnum(MyEnum.VAL1);
myEnumClass.setMyEnumField(MyEnumField.VAL3);
jsonObject = new JSONObject(myEnumClass);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected 2 myEnumField items", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
assertTrue("expected 0 myEnum items", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
assertTrue("expecting MyEnumField.VAL3", MyEnumField.VAL3.equals(jsonObject.query("/myEnumField")));
assertTrue("expecting MyEnum.VAL1", MyEnum.VAL1.equals(jsonObject.query("/myEnum")));
}
/**
* To serialize an enum by its set of allowed values, use getNames()
* and the JSONObject Object with names constructor.
*/
@Test
public void jsonObjectFromEnumWithNames() {
String [] names;
JSONObject jsonObject;
MyEnum myEnum = MyEnum.VAL1;
names = JSONObject.getNames(myEnum);
// The values will be MyEnum fields
jsonObject = new JSONObject(myEnum, names);
// validate JSON object
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
assertTrue("expected VAL1", MyEnum.VAL1.equals(jsonObject.query("/VAL1")));
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/VAL2")));
assertTrue("expected VAL3", MyEnum.VAL3.equals(jsonObject.query("/VAL3")));
MyEnumField myEnumField = MyEnumField.VAL3;
names = JSONObject.getNames(myEnumField);
// The values will be MyEnmField fields
jsonObject = new JSONObject(myEnumField, names);
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/VAL1")));
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/VAL2")));
assertTrue("expected VAL3", MyEnumField.VAL3.equals(jsonObject.query("/VAL3")));
}
/**
* Verify that enums are handled consistently between JSONArray and JSONObject
*/
@Test
public void verifyEnumConsistency(){
JSONObject jo = new JSONObject();
jo.put("value", MyEnumField.VAL2);
String expected="{\"value\":\"VAL2\"}";
String actual = jo.toString();
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
jo.accumulate("value", MyEnumField.VAL1);
expected="{\"value\":[\"VAL2\",\"VAL1\"]}";
actual = jo.toString();
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
jo.remove("value");
jo.append("value", MyEnumField.VAL1);
expected="{\"value\":[\"VAL1\"]}";
actual = jo.toString();
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
jo.put("value", EnumSet.of(MyEnumField.VAL2));
expected="{\"value\":[\"VAL2\"]}";
actual = jo.toString();
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
JSONArray ja = new JSONArray();
ja.put(MyEnumField.VAL2);
jo.put("value", ja);
actual = jo.toString();
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
jo.put("value", new MyEnumField[]{MyEnumField.VAL2});
actual = jo.toString();
assertTrue("Expected "+expected+" but actual was "+actual, expected.equals(actual));
}
/**
* To serialize by assigned value, use the put() methods. The value
* will be stored as a enum type.
*/
@Test
public void enumPut() {
JSONObject jsonObject = new JSONObject();
MyEnum myEnum = MyEnum.VAL2;
jsonObject.put("myEnum", myEnum);
MyEnumField myEnumField = MyEnumField.VAL1;
jsonObject.putOnce("myEnumField", myEnumField);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 2 top level objects", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/myEnum")));
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/myEnumField")));
JSONArray jsonArray = new JSONArray();
jsonArray.put(myEnum);
jsonArray.put(1, myEnumField);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
assertTrue("expected 2 top level objects", ((List<?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonArray.query("/0")));
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonArray.query("/1")));
/**
* Leaving these tests because they exercise get, opt, and remove
*/
assertTrue("expecting myEnum value", MyEnum.VAL2.equals(jsonArray.get(0)));
assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.opt(1)));
assertTrue("expecting myEnumField value", MyEnumField.VAL1.equals(jsonArray.remove(1)));
}
/**
* The default action of valueToString() is to call object.toString().
* For enums, this means the assigned value will be returned as a string.
*/
@Test
public void enumValueToString() {
String expectedStr1 = "\"VAL1\"";
String expectedStr2 = "\"VAL1\"";
MyEnum myEnum = MyEnum.VAL1;
MyEnumField myEnumField = MyEnumField.VAL1;
MyEnumClass myEnumClass = new MyEnumClass();
String str1 = JSONObject.valueToString(myEnum);
assertTrue("actual myEnum: "+str1+" expected: "+expectedStr1,
str1.equals(expectedStr1));
String str2 = JSONObject.valueToString(myEnumField);
assertTrue("actual myEnumField: "+str2+" expected: "+expectedStr2,
str2.equals(expectedStr2));
/**
* However, an enum within another class will not be rendered
* unless that class overrides default toString()
*/
String expectedStr3 = "\"org.json.junit.data.MyEnumClass@";
myEnumClass.setMyEnum(MyEnum.VAL1);
myEnumClass.setMyEnumField(MyEnumField.VAL1);
String str3 = JSONObject.valueToString(myEnumClass);
assertTrue("actual myEnumClass: "+str3+" expected: "+expectedStr3,
str3.startsWith(expectedStr3));
}
/**
* In whatever form the enum was added to the JSONObject or JSONArray,
* json[Object|Array].toString should serialize it in a reasonable way.
*/
@Test
public void enumToString() {
MyEnum myEnum = MyEnum.VAL2;
JSONObject jsonObject = new JSONObject(myEnum);
String expectedStr = "{}";
assertTrue("myEnum toString() should be empty", expectedStr.equals(jsonObject.toString()));
MyEnumField myEnumField = MyEnumField.VAL2;
jsonObject = new JSONObject(myEnumField);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected val 2", "val 2".equals(jsonObject.query("/value")));
assertTrue("expected 2", Integer.valueOf(2).equals(jsonObject.query("/intVal")));
MyEnumClass myEnumClass = new MyEnumClass();
myEnumClass.setMyEnum(MyEnum.VAL1);
myEnumClass.setMyEnumField(MyEnumField.VAL3);
jsonObject = new JSONObject(myEnumClass);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected VAL3", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
assertTrue("expected VAL1", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
String [] names = JSONObject.getNames(myEnum);
jsonObject = new JSONObject(myEnum, names);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
assertTrue("expected VAL1", MyEnum.VAL1.equals(jsonObject.query("/VAL1")));
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/VAL2")));
assertTrue("expected VAL3", MyEnum.VAL3.equals(jsonObject.query("/VAL3")));
names = JSONObject.getNames(myEnumField);
jsonObject = new JSONObject(myEnumField, names);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 3 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 3);
assertTrue("expected VAL1", MyEnumField.VAL1.equals(jsonObject.query("/VAL1")));
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/VAL2")));
assertTrue("expected VAL3", MyEnumField.VAL3.equals(jsonObject.query("/VAL3")));
expectedStr = "{\"myEnum\":\"VAL2\", \"myEnumField\":\"VAL2\"}";
jsonObject = new JSONObject();
jsonObject.putOpt("myEnum", myEnum);
jsonObject.putOnce("myEnumField", myEnumField);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonObject.query("/myEnum")));
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/myEnumField")));
JSONArray jsonArray = new JSONArray();
jsonArray.put(myEnum);
jsonArray.put(1, myEnumField);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
assertTrue("expected 2 top level items", ((List<?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected VAL2", MyEnum.VAL2.equals(jsonArray.query("/0")));
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonArray.query("/1")));
}
/**
* Wrap should handle enums exactly as a value type like Integer, Boolean, or String.
*/
@Test
public void wrap() {
assertTrue("simple enum has no getters", JSONObject.wrap(MyEnum.VAL2) instanceof MyEnum);
MyEnumField myEnumField = MyEnumField.VAL2;
JSONObject jsonObject = new JSONObject();
jsonObject.put("enum",myEnumField);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 1 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
assertTrue("expected VAL2", MyEnumField.VAL2.equals(jsonObject.query("/enum")));
MyEnumClass myEnumClass = new MyEnumClass();
myEnumClass.setMyEnum(MyEnum.VAL1);
myEnumClass.setMyEnumField(MyEnumField.VAL3);
jsonObject = (JSONObject)JSONObject.wrap(myEnumClass);
// validate JSON content
doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected VAL3", "VAL3".equals((JsonPath.read(doc, "$.myEnumField"))));
assertTrue("expected VAL1", "VAL1".equals((JsonPath.read(doc, "$.myEnum"))));
assertTrue("expecting MyEnumField.VAL3", MyEnumField.VAL3.equals(jsonObject.query("/myEnumField")));
assertTrue("expecting MyEnum.VAL1", MyEnum.VAL1.equals(jsonObject.query("/myEnum")));
}
/**
* It was determined that some API methods should be added to
* support enums:<br>
* JSONObject.getEnum(class, key)<br>
* JSONObject.optEnum(class, key)<br>
* JSONObject.optEnum(class, key, default)<br>
* JSONArray.getEnum(class, index)<br>
* JSONArray.optEnum(class, index)<br>
* JSONArray.optEnum(class, index, default)<br>
* <p>
* Exercise these enum API methods on JSONObject and JSONArray
*/
@Test
public void enumAPI() {
MyEnumClass myEnumClass = new MyEnumClass();
myEnumClass.setMyEnum(MyEnum.VAL1);
MyEnumField myEnumField = MyEnumField.VAL2;
JSONObject jsonObject = new JSONObject();
jsonObject.put("strKey", "value");
jsonObject.put("strKey2", "VAL1");
jsonObject.put("enumKey", myEnumField);
jsonObject.put("enumClassKey", myEnumClass);
// get a plain old enum
MyEnumField actualEnum = jsonObject.getEnum(MyEnumField.class, "enumKey");
assertTrue("get myEnumField", actualEnum == MyEnumField.VAL2);
// try to get the wrong value
try {
actualEnum = jsonObject.getEnum(MyEnumField.class, "strKey");
assertTrue("should throw an exception for wrong key", false);
} catch (Exception ignored) {}
// get a class that contains an enum
MyEnumClass actualEnumClass = (MyEnumClass)jsonObject.get("enumClassKey");
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
// opt a plain old enum
actualEnum = jsonObject.optEnum(MyEnumField.class, "enumKey");
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
// opt the wrong value
actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey");
assertTrue("opt null", actualEnum == null);
// opt a class that contains an enum
actualEnumClass = (MyEnumClass)jsonObject.opt("enumClassKey");
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
// opt with default a plain old enum
actualEnum = jsonObject.optEnum(MyEnumField.class, "enumKey", null);
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
// opt with default the wrong value
actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey", null);
assertNull("opt null", actualEnum);
// opt with default the string value
actualEnum = jsonObject.optEnum(MyEnumField.class, "strKey2", null);
assertEquals(MyEnumField.VAL1, actualEnum);
// opt with default an index that does not exist
actualEnum = jsonObject.optEnum(MyEnumField.class, "noKey", null);
assertNull("opt null", actualEnum);
assertNull("Expected Null when the enum class is null",
jsonObject.optEnum(null, "enumKey"));
/**
* Exercise the proposed enum API methods on JSONArray
*/
JSONArray jsonArray = new JSONArray();
jsonArray.put("value");
jsonArray.put(myEnumField);
jsonArray.put(myEnumClass);
// get a plain old enum
actualEnum = jsonArray.getEnum(MyEnumField.class, 1);
assertTrue("get myEnumField", actualEnum == MyEnumField.VAL2);
// try to get the wrong value
try {
actualEnum = jsonArray.getEnum(MyEnumField.class, 0);
assertTrue("should throw an exception for wrong index", false);
} catch (Exception ignored) {}
// get a class that contains an enum
actualEnumClass = (MyEnumClass)jsonArray.get(2);
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
// opt a plain old enum
actualEnum = jsonArray.optEnum(MyEnumField.class, 1);
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
// opt the wrong value
actualEnum = jsonArray.optEnum(MyEnumField.class, 0);
assertTrue("opt null", actualEnum == null);
// opt a class that contains an enum
actualEnumClass = (MyEnumClass)jsonArray.opt(2);
assertTrue("get enum", actualEnumClass.getMyEnum() == MyEnum.VAL1);
// opt with default a plain old enum
actualEnum = jsonArray.optEnum(MyEnumField.class, 1, null);
assertTrue("opt myEnumField", actualEnum == MyEnumField.VAL2);
// opt with default the wrong value
actualEnum = jsonArray.optEnum(MyEnumField.class, 0, null);
assertTrue("opt null", actualEnum == null);
// opt with default an index that does not exist
actualEnum = jsonArray.optEnum(MyEnumField.class, 3, null);
assertTrue("opt null", actualEnum == null);
}
}

View File

@ -0,0 +1,200 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import org.json.*;
import org.junit.Test;
/**
* Unit tests for JSON-Java HTTP.java. See RFC7230.
*/
public class HTTPTest {
/**
* Attempt to call HTTP.toJSONObject() with a null string
* Expects a NUllPointerException.
*/
@Test(expected=NullPointerException.class)
public void nullHTTPException() {
String httpStr = null;
HTTP.toJSONObject(httpStr);
}
/**
* Attempt to call HTTP.toJSONObject() with a string containing
* an empty object. Expects a JSONException.
*/
@Test
public void notEnoughHTTPException() {
String httpStr = "{}";
JSONObject jsonObject = new JSONObject(httpStr);
try {
HTTP.toString(jsonObject);
assertTrue("Expected to throw exception", false);
} catch (JSONException e) {
assertTrue("Expecting an exception message",
"Not enough material for an HTTP header.".equals(e.getMessage()));
}
}
/**
* Calling HTTP.toJSONObject() with an empty string will result in a
* populated JSONObject with keys but no values for Request-URI, Method,
* and HTTP-Version.
*/
@Test
public void emptyStringHTTPRequest() {
String httpStr = "";
String expectedHTTPStr = "{\"Request-URI\":\"\",\"Method\":\"\",\"HTTP-Version\":\"\"}";
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
}
/**
* Call HTTP.toJSONObject() with a Request-URI, Method,
* and HTTP-Version.
*/
@Test
public void simpleHTTPRequest() {
String httpStr = "GET /hello.txt HTTP/1.1";
String expectedHTTPStr =
"{\"Request-URI\":\"/hello.txt\",\"Method\":\"GET\",\"HTTP-Version\":\"HTTP/1.1\"}";
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
}
/**
* Call HTTP.toJSONObject() with a response string containing a
* HTTP-Version, Status-Code, and Reason.
*/
@Test
public void simpleHTTPResponse() {
String httpStr = "HTTP/1.1 200 OK";
String expectedHTTPStr =
"{\"HTTP-Version\":\"HTTP/1.1\",\"Status-Code\":\"200\",\"Reason-Phrase\":\"OK\"}";
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
}
/**
* Call HTTP.toJSONObject() with a full request string including
* request headers.
*/
@Test
public void extendedHTTPRequest() {
String httpStr =
"POST /enlighten/calais.asmx HTTP/1.1\n"+
"Host: api.opencalais.com\n"+
"Content-Type: text/xml; charset=utf-8\n"+
"Content-Length: 100\n"+
"SOAPAction: \"http://clearforest.com/Enlighten\"";
String expectedHTTPStr =
"{"+
"\"Request-URI\":\"/enlighten/calais.asmx\","+
"\"Host\":\"api.opencalais.com\","+
"\"Method\":\"POST\","+
"\"HTTP-Version\":\"HTTP/1.1\","+
"\"Content-Length\":\"100\","+
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
/**
* Not too easy for JSONObject to parse a string with embedded quotes.
* For the sake of the test, add it here.
*/
expectedJsonObject.put("SOAPAction","\"http://clearforest.com/Enlighten\"");
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
}
/**
* Call HTTP.toJSONObject() with a full response string including
* response headers.
*/
@Test
public void extendedHTTPResponse() {
String httpStr =
"HTTP/1.1 200 OK\n"+
"Content-Type: text/xml; charset=utf-8\n"+
"Content-Length: 100\n";
String expectedHTTPStr =
"{\"HTTP-Version\":\"HTTP/1.1\","+
"\"Status-Code\":\"200\","+
"\"Content-Length\":\"100\","+
"\"Reason-Phrase\":\"OK\","+
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
}
/**
* Call HTTP.toJSONObject() with a full POST request string including
* response headers, then convert it back into an HTTP string.
*/
@Test
public void convertHTTPRequestToString() {
String httpStr =
"POST /enlighten/calais.asmx HTTP/1.1\n"+
"Host: api.opencalais.com\n"+
"Content-Type: text/xml; charset=utf-8\n"+
"Content-Length: 100";
String expectedHTTPStr =
"{"+
"\"Request-URI\":\"/enlighten/calais.asmx\","+
"\"Host\":\"api.opencalais.com\","+
"\"Method\":\"POST\","+
"\"HTTP-Version\":\"HTTP/1.1\","+
"\"Content-Length\":\"100\","+
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
String httpToStr = HTTP.toString(jsonObject);
/**
* JSONObject objects to crlfs and any trailing chars.
* For the sake of the test, simplify the resulting string
*/
httpToStr = httpToStr.replaceAll("("+HTTP.CRLF+HTTP.CRLF+")", "");
httpToStr = httpToStr.replaceAll(HTTP.CRLF, "\n");
JSONObject finalJsonObject = HTTP.toJSONObject(httpToStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
}
/**
* Call HTTP.toJSONObject() with a full response string including
* response headers, then convert it back into an HTTP string.
*/
@Test
public void convertHTTPResponseToString() {
String httpStr =
"HTTP/1.1 200 OK\n"+
"Content-Type: text/xml; charset=utf-8\n"+
"Content-Length: 100\n";
String expectedHTTPStr =
"{\"HTTP-Version\":\"HTTP/1.1\","+
"\"Status-Code\":\"200\","+
"\"Content-Length\":\"100\","+
"\"Reason-Phrase\":\"OK\","+
"\"Content-Type\":\"text/xml; charset=utf-8\"}";
JSONObject jsonObject = HTTP.toJSONObject(httpStr);
JSONObject expectedJsonObject = new JSONObject(expectedHTTPStr);
String httpToStr = HTTP.toString(jsonObject);
/**
* JSONObject objects to crlfs and any trailing chars.
* For the sake of the test, simplify the resulting string
*/
httpToStr = httpToStr.replaceAll("("+HTTP.CRLF+HTTP.CRLF+")", "");
httpToStr = httpToStr.replaceAll(HTTP.CRLF, "\n");
JSONObject finalJsonObject = HTTP.toJSONObject(httpToStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
Util.compareActualVsExpectedJsonObjects(finalJsonObject,expectedJsonObject);
}
}

View File

@ -0,0 +1,107 @@
package org.json.junit;
import org.json.HTTPTokener;
import org.json.JSONException;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Tests for JSON-Java HTTPTokener.java
*/
public class HTTPTokenerTest {
/**
* Test parsing a simple unquoted token.
*/
@Test
public void parseSimpleToken() {
HTTPTokener tokener = new HTTPTokener("Content-Type");
String token = tokener.nextToken();
assertEquals("Content-Type", token);
}
/**
* Test parsing multiple tokens separated by whitespace.
*/
@Test
public void parseMultipleTokens() {
HTTPTokener tokener = new HTTPTokener("Content-Type application/json");
String token1 = tokener.nextToken();
String token2 = tokener.nextToken();
assertEquals("Content-Type", token1);
assertEquals("application/json", token2);
}
/**
* Test parsing a double-quoted token.
*/
@Test
public void parseDoubleQuotedToken() {
HTTPTokener tokener = new HTTPTokener("\"application/json\"");
String token = tokener.nextToken();
assertEquals("application/json", token);
}
/**
* Test parsing a single-quoted token.
*/
@Test
public void parseSingleQuotedToken() {
HTTPTokener tokener = new HTTPTokener("'application/json'");
String token = tokener.nextToken();
assertEquals("application/json", token);
}
/**
* Test parsing a quoted token that includes spaces and semicolons.
*/
@Test
public void parseQuotedTokenWithSpaces() {
HTTPTokener tokener = new HTTPTokener("\"text/html; charset=UTF-8\"");
String token = tokener.nextToken();
assertEquals("text/html; charset=UTF-8", token);
}
/**
* Test that unterminated quoted strings throw a JSONException.
*/
@Test
public void throwExceptionOnUnterminatedString() {
HTTPTokener tokener = new HTTPTokener("\"incomplete");
JSONException exception = assertThrows(JSONException.class, tokener::nextToken);
assertTrue(exception.getMessage().contains("Unterminated string"));
}
/**
* Test behavior with empty input string.
*/
@Test
public void parseEmptyInput() {
HTTPTokener tokener = new HTTPTokener("");
String token = tokener.nextToken();
assertEquals("", token);
}
/**
* Test behavior with input consisting only of whitespace.
*/
@Test
public void parseWhitespaceOnly() {
HTTPTokener tokener = new HTTPTokener(" \t \n ");
String token = tokener.nextToken();
assertEquals("", token);
}
/**
* Test parsing tokens separated by multiple whitespace characters.
*/
@Test
public void parseTokensWithMultipleWhitespace() {
HTTPTokener tokener = new HTTPTokener("GET /index.html");
String method = tokener.nextToken();
String path = tokener.nextToken();
assertEquals("GET", method);
assertEquals("/index.html", path);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,989 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import org.json.*;
import org.junit.Test;
/**
* Tests for org.json.JSONML.java
*
* Certain inputs are expected to result in exceptions. These tests are
* executed first. JSONML provides an API to:
* Convert an XML string into a JSONArray or a JSONObject.
* Convert a JSONArray or JSONObject into an XML string.
* Both fromstring and tostring operations operations should be symmetrical
* within the limits of JSONML.
* It should be possible to perform the following operations, which should
* result in the original string being recovered, within the limits of the
* underlying classes:
* Convert a string -> JSONArray -> string -> JSONObject -> string
* Convert a string -> JSONObject -> string -> JSONArray -> string
*
*/
public class JSONMLTest {
/**
* Attempts to transform a null XML string to JSON.
* Expects a NullPointerException
*/
@Test(expected=NullPointerException.class)
public void nullXMLException() {
String xmlStr = null;
JSONML.toJSONArray(xmlStr);
}
/**
* Attempts to transform an empty string to JSON.
* Expects a JSONException
*/
@Test
public void emptyXMLException() {
String xmlStr = "";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Bad XML at 0 [character 1 line 1]",
e.getMessage());
}
}
/**
* Attempts to call JSONML.toString() with a null JSONArray.
* Expects a NullPointerException.
*/
@Test(expected=NullPointerException.class)
public void nullJSONXMLException() {
/**
* Tries to convert a null JSONArray to XML.
*/
JSONArray jsonArray= null;
JSONML.toString(jsonArray);
}
/**
* Attempts to call JSONML.toString() with a null JSONArray.
* Expects a JSONException.
*/
@Test
public void emptyJSONXMLException() {
/**
* Tries to convert an empty JSONArray to XML.
*/
JSONArray jsonArray = new JSONArray();
try {
JSONML.toString(jsonArray);
assertTrue("Expecting an exception", false);
} catch (JSONException e) {
assertTrue("Expecting an exception message",
"JSONArray[0] not found.".
equals(e.getMessage()));
}
}
/**
* Attempts to transform an non-XML string to JSON.
* Expects a JSONException
*/
@Test
public void nonXMLException() {
/**
* Attempts to transform a nonXML string to JSON
*/
String xmlStr = "{ \"this is\": \"not xml\"}";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Bad XML at 23 [character 24 line 1]",
e.getMessage());
}
}
/**
* Attempts to transform a JSON document with XML content that
* does not follow JSONML conventions (element name is not first value
* in a nested JSONArray) to a JSONArray then back to string.
* Expects a JSONException
*/
@Test
public void emptyTagException() {
/**
* jsonArrayStr is used to build a JSONArray which is then
* turned into XML. For this transformation, all arrays represent
* elements and the first array entry is the name of the element.
* In this case, one of the arrays does not have a name
*/
String jsonArrayStr =
"[\"addresses\","+
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
// this array has no name
"["+
"[\"name\"],"+
"[\"nocontent\"],"+
"\">\""+
"]"+
"]";
JSONArray jsonArray = new JSONArray(jsonArrayStr);
try {
JSONML.toString(jsonArray);
assertTrue("Expecting an exception", false);
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"JSONArray[0] is not a String (class org.json.JSONArray).",
e.getMessage());
}
}
/**
* Attempts to transform a JSON document with XML content that
* does not follow JSONML conventions (element tag has an embedded space)
* to a JSONArray then back to string. Expects a JSONException
*/
@Test
public void spaceInTagException() {
/**
* jsonArrayStr is used to build a JSONArray which is then
* turned into XML. For this transformation, all arrays represent
* elements and the first array entry is the name of the element.
* In this case, one of the element names has an embedded space,
* which is not allowed.
*/
String jsonArrayStr =
"[\"addresses\","+
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
// this array has an invalid name
"[\"addr esses\","+
"[\"name\"],"+
"[\"nocontent\"],"+
"\">\""+
"]"+
"]";
JSONArray jsonArray = new JSONArray(jsonArrayStr);
try {
JSONML.toString(jsonArray);
assertTrue("Expecting an exception", false);
} catch (JSONException e) {
assertTrue("Expecting an exception message",
"'addr esses' contains a space character.".
equals(e.getMessage()));
}
}
/**
* Attempts to transform a malformed XML document
* (element tag has a frontslash) to a JSONArray.\
* Expects a JSONException
*/
@Test
public void invalidSlashInTagException() {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because the 'name' element
* contains an invalid frontslash.
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
" <address>\n"+
" <name/x>\n"+
" <street>abc street</street>\n"+
" </address>\n"+
"</addresses>";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Misshaped tag at 176 [character 14 line 4]",
e.getMessage());
}
}
/**
* Malformed XML text (invalid tagname) is transformed into a JSONArray.
* Expects a JSONException.
*/
@Test
public void invalidBangInTagException() {
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
" <address>\n"+
" <name/>\n"+
" <!>\n"+
" </address>\n"+
"</addresses>";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Misshaped meta tag at 215 [character 12 line 7]",
e.getMessage());
}
}
/**
* Malformed XML text (invalid tagname, no close bracket) is transformed\
* into a JSONArray. Expects a JSONException.
*/
@Test
public void invalidBangNoCloseInTagException() {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because an element
* starts with '!' and has no closing tag
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
" <address>\n"+
" <name/>\n"+
" <!\n"+
" </address>\n"+
"</addresses>";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Misshaped meta tag at 214 [character 12 line 7]",
e.getMessage());
}
}
/**
* Malformed XML text (tagname with no close bracket) is transformed\
* into a JSONArray. Expects a JSONException.
*/
@Test
public void noCloseStartTagException() {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because an element
* has no closing '>'.
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
" <address>\n"+
" <name/>\n"+
" <abc\n"+
" </address>\n"+
"</addresses>";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Misplaced '<' at 194 [character 5 line 6]",
e.getMessage());
}
}
/**
* Malformed XML text (endtag with no name) is transformed\
* into a JSONArray. Expects a JSONException.
*/
@Test
public void noCloseEndTagException() {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because an element
* has no name after the closing tag '</'.
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
" <address>\n"+
" <name/>\n"+
" <abc/>\n"+
" </>\n"+
"</addresses>";
try {
JSONML.toJSONArray(xmlStr);
assertTrue("Expecting an exception", false);
} catch (JSONException e) {
assertTrue("Expecting an exception message",
"Expected a closing name instead of '>'.".
equals(e.getMessage()));
}
}
/**
* Malformed XML text (endtag with no close bracket) is transformed\
* into a JSONArray. Expects a JSONException.
*/
@Test
public void noCloseEndBraceException() {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because an element
* has '>' after the closing tag '</' and name.
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation=\"test.xsd\">\n"+
" <address>\n"+
" <name/>\n"+
" <abc/>\n"+
" </address\n"+
"</addresses>";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Misplaced '<' at 206 [character 1 line 7]",
e.getMessage());
}
}
/**
* Malformed XML text (incomplete CDATA string) is transformed\
* into a JSONArray. Expects a JSONException.
*/
@Test
public void invalidCDATABangInTagException() {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because an element
* does not have a complete CDATA string.
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
" <address>\n"+
" <name>Joe Tester</name>\n"+
" <![[]>\n"+
" </address>\n"+
"</addresses>";
try {
JSONML.toJSONArray(xmlStr);
fail("Expecting an exception");
} catch (JSONException e) {
assertEquals("Expecting an exception message",
"Expected 'CDATA[' at 204 [character 11 line 5]",
e.getMessage());
}
}
/**
* Convert an XML document into a JSONArray, then use JSONML.toString()
* to convert it into a string. This string is then converted back into
* a JSONArray. Both JSONArrays are compared against a control to
* confirm the contents.
*/
@Test
public void toJSONArray() {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* Each element becomes a JSONArray:
* 1st entry = elementname
* 2nd entry = attributes object (if present)
* 3rd entry = content (if present)
* 4th entry = child element JSONArrays (if present)
* The result is compared against an expected JSONArray.
* The transformed JSONArray is then transformed back into a string
* which is used to create a final JSONArray, which is also compared
* against the expected JSONArray.
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
"xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
"<address attr1=\"attrValue1\" attr2=\"attrValue2\" attr3=\"attrValue3\">\n"+
"<name nameType=\"mine\">myName</name>\n"+
"<nocontent/>>\n"+
"</address>\n"+
"</addresses>";
String expectedStr =
"[\"addresses\","+
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
"[\"address\","+
"{\"attr1\":\"attrValue1\",\"attr2\":\"attrValue2\",\"attr3\":\"attrValue3\"},"+
"[\"name\", {\"nameType\":\"mine\"},\"myName\"],"+
"[\"nocontent\"],"+
"\">\""+
"]"+
"]";
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
JSONArray expectedJsonArray = new JSONArray(expectedStr);
String xmlToStr = JSONML.toString(jsonArray);
JSONArray finalJsonArray = JSONML.toJSONArray(xmlToStr);
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
}
/**
* Convert an XML document into a JSONObject. Use JSONML.toString() to
* convert it back into a string, and then re-convert it into a JSONObject.
* Both JSONObjects are compared against a control JSONObject to confirm
* the contents.
* <p>
* Next convert the XML document into a JSONArray. Use JSONML.toString() to
* convert it back into a string, and then re-convert it into a JSONArray.
* Both JSONArrays are compared against a control JSONArray to confirm
* the contents.
* <p>
* This test gives a comprehensive example of how the JSONML
* transformations work.
*/
@Test
public void toJSONObjectToJSONArray() {
/**
* xmlStr contains XML text which is transformed into a JSONObject,
* restored to XML, transformed into a JSONArray, and then restored
* to XML again. Both JSONObject and JSONArray should contain the same
* information and should produce the same XML, allowing for non-ordered
* attributes.
*
* Transformation to JSONObject:
* The elementName is stored as a string where key="tagName"
* Attributes are simply stored as key/value pairs
* If the element has either content or child elements, they are stored
* in a jsonArray with key="childNodes".
*
* Transformation to JSONArray:
* 1st entry = elementname
* 2nd entry = attributes object (if present)
* 3rd entry = content (if present)
* 4th entry = child element JSONArrays (if present)
*/
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
"xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
"<address addrType=\"my address\">\n"+
"<name nameType=\"my name\">Joe Tester</name>\n"+
"<street><![CDATA[Baker street 5]]></street>\n"+
"<NothingHere except=\"an attribute\"/>\n"+
"<TrueValue>true</TrueValue>\n"+
"<FalseValue>false</FalseValue>\n"+
"<NullValue>null</NullValue>\n"+
"<PositiveValue>42</PositiveValue>\n"+
"<NegativeValue>-23</NegativeValue>\n"+
"<DoubleValue>-23.45</DoubleValue>\n"+
"<Nan>-23x.45</Nan>\n"+
"<ArrayOfNum>\n"+
"<value>1</value>\n"+
"<value>2</value>\n"+
"<value><subValue svAttr=\"svValue\">abc</subValue></value>\n"+
"<value>3</value>\n"+
"<value>4.1</value>\n"+
"<value>5.2</value>\n"+
"</ArrayOfNum>\n"+
"</address>\n"+
"</addresses>";
String expectedJSONObjectStr =
"{"+
"\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"childNodes\":["+
"{"+
"\"childNodes\":["+
"{"+
"\"childNodes\":[\"Joe Tester\"],"+
"\"nameType\":\"my name\","+
"\"tagName\":\"name\""+
"},"+
"{"+
"\"childNodes\":[\"Baker street 5\"],"+
"\"tagName\":\"street\""+
"},"+
"{"+
"\"tagName\":\"NothingHere\","+
"\"except\":\"an attribute\""+
"},"+
"{"+
"\"childNodes\":[true],"+
"\"tagName\":\"TrueValue\""+
"},"+
"{"+
"\"childNodes\":[false],"+
"\"tagName\":\"FalseValue\""+
"},"+
"{"+
"\"childNodes\":[null],"+
"\"tagName\":\"NullValue\""+
"},"+
"{"+
"\"childNodes\":[42],"+
"\"tagName\":\"PositiveValue\""+
"},"+
"{"+
"\"childNodes\":[-23],"+
"\"tagName\":\"NegativeValue\""+
"},"+
"{"+
"\"childNodes\":[-23.45],"+
"\"tagName\":\"DoubleValue\""+
"},"+
"{"+
"\"childNodes\":[\"-23x.45\"],"+
"\"tagName\":\"Nan\""+
"},"+
"{"+
"\"childNodes\":["+
"{"+
"\"childNodes\":[1],"+
"\"tagName\":\"value\""+
"},"+
"{"+
"\"childNodes\":[2],"+
"\"tagName\":\"value\""+
"},"+
"{"+
"\"childNodes\":["+
"{"+
"\"childNodes\":[\"abc\"],"+
"\"svAttr\":\"svValue\","+
"\"tagName\":\"subValue\""+
"}"+
"],"+
"\"tagName\":\"value\""+
"},"+
"{"+
"\"childNodes\":[3],"+
"\"tagName\":\"value\""+
"},"+
"{"+
"\"childNodes\":[4.1],"+
"\"tagName\":\"value\""+
"},"+
"{"+
"\"childNodes\":[5.2],"+
"\"tagName\":\"value\""+
"}"+
"],"+
"\"tagName\":\"ArrayOfNum\""+
"}"+
"],"+
"\"addrType\":\"my address\","+
"\"tagName\":\"address\""+
"}"+
"],"+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\","+
"\"tagName\":\"addresses\""+
"}";
String expectedJSONArrayStr =
"["+
"\"addresses\","+
"{"+
"\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\""+
"},"+
"["+
"\"address\","+
"{"+
"\"addrType\":\"my address\""+
"},"+
"["+
"\"name\","+
"{"+
"\"nameType\":\"my name\""+
"},"+
"\"Joe Tester\""+
"],"+
"[\"street\",\"Baker street 5\"],"+
"["+
"\"NothingHere\","+
"{\"except\":\"an attribute\"}"+
"],"+
"[\"TrueValue\",true],"+
"[\"FalseValue\",false],"+
"[\"NullValue\",null],"+
"[\"PositiveValue\",42],"+
"[\"NegativeValue\",-23],"+
"[\"DoubleValue\",-23.45],"+
"[\"Nan\",\"-23x.45\"],"+
"["+
"\"ArrayOfNum\","+
"[\"value\",1],"+
"[\"value\",2],"+
"[\"value\","+
"["+
"\"subValue\","+
"{\"svAttr\":\"svValue\"},"+
"\"abc\""+
"]"+
"],"+
"[\"value\",3],"+
"[\"value\",4.1],"+
"[\"value\",5.2]"+
"]"+
"]"+
"]";
// make a JSONObject and make sure it looks as expected
JSONObject jsonObject = JSONML.toJSONObject(xmlStr);
JSONObject expectedJsonObject = new JSONObject(expectedJSONObjectStr);
Util.compareActualVsExpectedJsonObjects(jsonObject,expectedJsonObject);
// restore the XML, then make another JSONObject and make sure it
// looks as expected
String jsonObjectXmlToStr = JSONML.toString(jsonObject);
JSONObject finalJsonObject = JSONML.toJSONObject(jsonObjectXmlToStr);
Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject);
// create a JSON array from the original string and make sure it
// looks as expected
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
JSONArray expectedJsonArray = new JSONArray(expectedJSONArrayStr);
Util.compareActualVsExpectedJsonArrays(jsonArray,expectedJsonArray);
// restore the XML, then make another JSONArray and make sure it
// looks as expected
String jsonArrayXmlToStr = JSONML.toString(jsonArray);
JSONArray finalJsonArray = JSONML.toJSONArray(jsonArrayXmlToStr);
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
// lastly, confirm the restored JSONObject XML and JSONArray XML look
// reasonably similar
JSONObject jsonObjectFromObject = JSONML.toJSONObject(jsonObjectXmlToStr);
JSONObject jsonObjectFromArray = JSONML.toJSONObject(jsonArrayXmlToStr);
Util.compareActualVsExpectedJsonObjects(jsonObjectFromObject, jsonObjectFromArray);
}
/**
* Convert an XML document which contains embedded comments into
* a JSONArray. Use JSONML.toString() to turn it into a string, then
* reconvert it into a JSONArray. Compare both JSONArrays to a control
* JSONArray to confirm the contents.
* <p>
* This test shows how XML comments are handled.
*/
@Test
public void commentsInXML() {
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<!-- this is a comment -->\n"+
"<addresses>\n"+
"<address>\n"+
"<!-- <!--[CDATA[ this is -- <another> comment ]] -->\n"+
"<name>Joe Tester</name>\n"+
"<!-- this is a - multi line \n"+
"comment -->\n"+
"<street>Baker street 5</street>\n"+
"</address>\n"+
"</addresses>";
String expectedStr =
"[\"addresses\","+
"[\"address\","+
"[\"name\",\"Joe Tester\"],"+
"[\"street\",\"Baker street 5\"]"+
"]"+
"]";
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
JSONArray expectedJsonArray = new JSONArray(expectedStr);
String xmlToStr = JSONML.toString(jsonArray);
JSONArray finalJsonArray = JSONML.toJSONArray(xmlToStr);
Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray);
Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray);
}
/**
* JSON string with lost leading zero and converted "True" to true. See test
* result in comment below.
*/
@Test
public void testToJSONArray_jsonOutput() {
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",1],[\"id\",\"00\"],[\"id\",0],[\"item\",{\"id\":\"01\"}],[\"title\",true]]";
final JSONArray actualJsonOutput = JSONML.toJSONArray(originalXml, false);
assertEquals(expectedJsonString, actualJsonOutput.toString());
}
/**
* JSON string cannot be reverted to original xml when type guessing is used.
*/
@Test
public void testToJSONArray_reversibility() {
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
final String revertedXml = JSONML.toString(JSONML.toJSONArray(originalXml, false));
assertNotEquals(revertedXml, originalXml);
}
/**
* JSON string cannot be reverted to original xml when type guessing is used.
* When we force all the values as string, the original text comes back.
*/
@Test
public void testToJSONArray_reversibility2() {
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",\"1\"],[\"id\",\"00\"],[\"id\",\"0\"],[\"item\",{\"id\":\"01\"}],[\"title\",\"True\"]]";
final JSONArray json = JSONML.toJSONArray(originalXml,true);
assertEquals(expectedJsonString, json.toString());
final String reverseXml = JSONML.toString(json);
assertEquals(originalXml, reverseXml);
}
/**
* JSON can be reverted to original xml.
*/
@Test
public void testToJSONArray_reversibility3() {
final String originalXml = "<readResult><errors someAttr=\"arrtValue\"><code>400</code></errors><errors><code>402</code></errors></readResult>";
final JSONArray jsonArray = JSONML.toJSONArray(originalXml, false);
final String revertedXml = JSONML.toString(jsonArray);
assertEquals(revertedXml, originalXml);
}
/**
* JSON string cannot be reverted to original xml. See test result in
* comment below.
*/
@Test
public void testToJSONObject_reversibility() {
final String originalXml = "<readResult><errors someAttr=\"arrtValue\"><code>400</code></errors><errors><code>402</code></errors></readResult>";
final JSONObject originalObject=JSONML.toJSONObject(originalXml,false);
final String originalJson = originalObject.toString();
final String xml = JSONML.toString(originalObject);
final JSONObject revertedObject = JSONML.toJSONObject(xml, false);
final String newJson = revertedObject.toString();
assertTrue("JSON Objects are not similar", originalObject.similar(revertedObject));
assertTrue("JSON Strings are not similar", new JSONObject(originalJson).similar(new JSONObject(newJson)));
}
// these tests do not pass for the following reasons:
// 1. Our XML parser does not handle generic HTML entities, only valid XML entities. Hence &nbsp;
// or other HTML specific entities would fail on reversability
// 2. Our JSON implementation for storing the XML attributes uses the standard unordered map.
// This means that <tag attr1="v1" attr2="v2" /> can not be reversed reliably.
//
// /**
// * Test texts taken from jsonml.org. Currently our implementation FAILS this conversion but shouldn't.
// * Technically JsonML should be able to transform any valid xhtml document, but ours only supports
// * standard XML entities, not HTML entities.
// */
// @Test
// public void testAttributeConversionReversabilityHTML() {
// final String originalXml = "<table class=\"MyTable\" style=\"background-color:yellow\"><tr><td class=\"MyTD\" style=\"border:1px solid black\">#5D28D1</td><td class=\"MyTD\" style=\"background-color:red\">Example text here</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AF44EF</td><td class=\"MyTD\" style=\"background-color:green\">127310656</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AAD034</td><td class=\"MyTD\" style=\"background-color:blue\">&nbsp;<span style=\"background-color:maroon\">&copy;</span>&nbsp;</td></tr></table>";
// final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"\u00A0\",[\"span\",{ \"style\" : \"background-color:maroon\" },\"\u00A9\"],\"\u00A0\"]]]";
// final JSONArray json = JSONML.toJSONArray(originalXml,true);
// final String actualJsonString = json.toString();
//
// final String reverseXml = JSONML.toString(json);
// assertNotEquals(originalXml, reverseXml);
//
// assertNotEquals(expectedJsonString, actualJsonString);
// }
//
// /**
// * Test texts taken from jsonml.org but modified to have XML entities only.
// */
// @Test
// public void testAttributeConversionReversabilityXML() {
// final String originalXml = "<table class=\"MyTable\" style=\"background-color:yellow\"><tr><td class=\"MyTD\" style=\"border:1px solid black\">#5D28D1</td><td class=\"MyTD\" style=\"background-color:red\">Example text here</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AF44EF</td><td class=\"MyTD\" style=\"background-color:green\">127310656</td></tr><tr><td class=\"MyTD\" style=\"border:1px solid black\">#AAD034</td><td class=\"MyTD\" style=\"background-color:blue\">&amp;<span style=\"background-color:maroon\">&gt;</span>&lt;</td></tr></table>";
// final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"&\",[\"span\",{ \"style\" : \"background-color:maroon\" },\">\"],\"<\"]]]";
// final JSONArray jsonML = JSONML.toJSONArray(originalXml,true);
// final String actualJsonString = jsonML.toString();
//
// final String reverseXml = JSONML.toString(jsonML);
// // currently not equal because the hashing of the attribute objects makes the attribute
// // order not happen the same way twice
// assertEquals(originalXml, reverseXml);
//
// assertEquals(expectedJsonString, actualJsonString);
// }
@Test (timeout = 6000)
public void testIssue484InfinteLoop1() {
try {
JSONML.toJSONObject("??*^M??|?CglR^F??`??>?w??PIlr^E??D^X^]?$?-^R?o??O?*??{OD?^FY??`2a????NM?b^Tq?:O?>S$^K?J?^FB.gUK?m^H??zE??^??!v]?^A???^[^A??^U?c??????h???s???g^Z???`?q^Dbi??:^QZl?)?}1^??k?0??:$V?$?Ovs(}J??^V????2;^QgQ?^_^A?^D?^U?Tg?K?`?h%c?hmGA?<!C*^P^Y?^X9?~?t?)??,z^XA???S}?Q??.q?j????]");
fail("Exception expected for invalid JSON.");
} catch (JSONException ex) {
assertEquals("Exception string did not match: ",
"Unterminated string at 271 [character 272 line 1]",
ex.getMessage());
}
}
@Test (timeout = 6000)
public void testIssue484InfinteLoop2() {
try {
String input = "??*\n" +
"??|?CglR??`??>?w??PIlr??D?$?-?o??O?*??{OD?Y??`2a????NM?bq?:O?>S$ ?J?B.gUK?m\b??zE???!v]???????c??????h???s???g???`?qbi??:Zl?)?}1^??k?0??:$V?$?Ovs(}J??????2;gQ????Tg?K?`?h%c?hmGA?<!C*?9?~?t?)??,zA???S}?Q??.q?j????]";
JSONML.toJSONObject(input);
fail("Exception expected for invalid JSON.");
} catch (JSONException ex) {
assertEquals("Exception string did not match: ",
"Unterminated string at 242 [character 238 line 2]",
ex.getMessage());
}
}
@Test
public void testToJSONArrayMaxNestingDepthOf42IsRespected() {
final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "<a>");
final int maxNestingDepth = 42;
try {
JSONML.toJSONArray(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONArrayMaxNestingDepthIsRespectedWithValidXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 1;
try {
JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONArrayMaxNestingDepthWithValidFittingXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 3;
try {
JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
} catch (JSONException e) {
e.printStackTrace();
fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
"parameter of the JSONMLParserConfiguration used");
}
}
@Test
public void testToJSONObjectMaxDefaultNestingDepthIsRespected() {
final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "<a>");
try {
JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL);
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH));
}
}
@Test
public void testToJSONObjectUnlimitedNestingDepthIsPossible() {
int actualDepth = JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH +10;
final String deeperThanDefaultMax = new String(new char[actualDepth]).replace("\0", "<a>") +
"value" +
new String(new char[actualDepth]).replace("\0", "</a>");
try {
JSONML.toJSONObject(deeperThanDefaultMax, JSONMLParserConfiguration.ORIGINAL
.withMaxNestingDepth(JSONMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH));
} catch (JSONException e) {
e.printStackTrace();
fail("XML document should be parsed beyond the default maximum depth if maxNestingDepth " +
"parameter is set to -1 in JSONMLParserConfiguration");
}
}
@Test
public void testToJSONObjectMaxNestingDepthOf42IsRespected() {
final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "<a>");
final int maxNestingDepth = 42;
try {
JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONObjectMaxNestingDepthIsRespectedWithValidXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 1;
try {
JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONObjectMaxNestingDepthWithValidFittingXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 3;
try {
JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
} catch (JSONException e) {
e.printStackTrace();
fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
"parameter of the JSONMLParserConfiguration used");
}
}
}

View File

@ -0,0 +1,60 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import java.util.*;
import org.json.*;
import org.json.junit.data.MyLocaleBean;
import org.junit.*;
/**
* Note: This file is saved as UTF-8. Do not save as ASCII or the tests will
* fail.
*
*/
public class JSONObjectLocaleTest {
/**
* JSONObject built from a bean with locale-specific keys.
* In the Turkish alphabet, there are 2 versions of the letter "i".
* 'eh' I ı (dotless i)
* 'ee' İ i (dotted i)
* A problem can occur when parsing the public get methods for a bean.
* If the method starts with getI... then the key name will be lowercased
* to 'i' in English, and 'ı' in Turkish.
* We want the keys to be consistent regardless of locale, so JSON-Java
* lowercase operations are made to be locale-neutral by specifying
* Locale.ROOT. This causes 'I' to be universally lowercased to 'i'
* regardless of the locale currently in effect.
*/
@Test
public void jsonObjectByLocaleBean() {
MyLocaleBean myLocaleBean = new MyLocaleBean();
/**
* This is just the control case which happens when the locale.ROOT
* lowercasing behavior is the same as the current locale.
*/
Locale.setDefault(new Locale("en"));
JSONObject jsonen = new JSONObject(myLocaleBean);
assertEquals("expected size 2, found: " +jsonen.length(), 2, jsonen.length());
assertEquals("expected jsonen[i] == beanI", "beanI", jsonen.getString("i"));
assertEquals("expected jsonen[id] == beanId", "beanId", jsonen.getString("id"));
/**
* Without the JSON-Java change, these keys would be stored internally as
* starting with the letter, 'ı' (dotless i), since the lowercasing of
* the getI and getId keys would be specific to the Turkish locale.
*/
Locale.setDefault(new Locale("tr"));
JSONObject jsontr = new JSONObject(myLocaleBean);
assertEquals("expected size 2, found: " +jsontr.length(), 2, jsontr.length());
assertEquals("expected jsontr[i] == beanI", "beanI", jsontr.getString("i"));
assertEquals("expected jsontr[id] == beanId", "beanId", jsontr.getString("id"));
}
}

View File

@ -0,0 +1,146 @@
package org.json.junit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(value = Parameterized.class)
public class JSONObjectNumberTest {
private final String objectString;
private Integer value = 50;
@Parameters(name = "{index}: {0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"{\"value\":50}", 1},
{"{\"value\":50.0}", 1},
{"{\"value\":5e1}", 1},
{"{\"value\":5E1}", 1},
{"{\"value\":5e1}", 1},
{"{\"value\":\"50\"}", 1},
{"{\"value\":-50}", -1},
{"{\"value\":-50.0}", -1},
{"{\"value\":-5e1}", -1},
{"{\"value\":-5E1}", -1},
{"{\"value\":-5e1}", -1},
{"{\"value\":\"-50\"}", -1}
// JSON does not support octal or hex numbers;
// see https://stackoverflow.com/a/52671839/6323312
// "{value:062}", // octal 50
// "{value:0x32}" // hex 50
});
}
public JSONObjectNumberTest(String objectString, int resultIsNegative) {
this.objectString = objectString;
this.value *= resultIsNegative;
}
private JSONObject object;
@Before
public void setJsonObject() {
object = new JSONObject(objectString);
}
@Test
public void testGetNumber() {
assertEquals(value.intValue(), object.getNumber("value").intValue());
}
@Test
public void testGetBigDecimal() {
assertTrue(BigDecimal.valueOf(value).compareTo(object.getBigDecimal("value")) == 0);
}
@Test
public void testGetBigInteger() {
assertEquals(BigInteger.valueOf(value), object.getBigInteger("value"));
}
@Test
public void testGetFloat() {
assertEquals(value.floatValue(), object.getFloat("value"), 0.0f);
}
@Test
public void testGetDouble() {
assertEquals(value.doubleValue(), object.getDouble("value"), 0.0d);
}
@Test
public void testGetInt() {
assertEquals(value.intValue(), object.getInt("value"));
}
@Test
public void testGetLong() {
assertEquals(value.longValue(), object.getLong("value"));
}
@Test
public void testOptNumber() {
assertEquals(value.intValue(), object.optNumber("value").intValue());
}
@Test
public void testOptBigDecimal() {
assertTrue(BigDecimal.valueOf(value).compareTo(object.optBigDecimal("value", null)) == 0);
}
@Test
public void testOptBigInteger() {
assertEquals(BigInteger.valueOf(value), object.optBigInteger("value", null));
}
@Test
public void testOptFloat() {
assertEquals(value.floatValue(), object.optFloat("value"), 0.0f);
}
@Test
public void testOptFloatObject() {
assertEquals((Float) value.floatValue(), object.optFloatObject("value"), 0.0f);
}
@Test
public void testOptDouble() {
assertEquals(value.doubleValue(), object.optDouble("value"), 0.0d);
}
@Test
public void testOptDoubleObject() {
assertEquals((Double) value.doubleValue(), object.optDoubleObject("value"), 0.0d);
}
@Test
public void testOptInt() {
assertEquals(value.intValue(), object.optInt("value"));
}
@Test
public void testOptIntegerObject() {
assertEquals((Integer) value.intValue(), object.optIntegerObject("value"));
}
@Test
public void testOptLong() {
assertEquals(value.longValue(), object.optLong("value"));
}
@Test
public void testOptLongObject() {
assertEquals((Long) value.longValue(), object.optLongObject("value"));
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,624 @@
package org.json.junit;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONParserConfiguration;
import org.json.JSONTokener;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class JSONParserConfigurationTest {
private static final String TEST_SOURCE = "{\"key\": \"value1\", \"key\": \"value2\"}";
@Test(expected = JSONException.class)
public void testThrowException() {
new JSONObject(TEST_SOURCE);
}
@Test
public void testOverwrite() {
JSONObject jsonObject = new JSONObject(TEST_SOURCE,
new JSONParserConfiguration().withOverwriteDuplicateKey(true));
assertEquals("duplicate key should be overwritten", "value2", jsonObject.getString("key"));
}
@Test
public void strictModeIsCloned(){
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true)
.withMaxNestingDepth(12);
assertTrue(jsonParserConfiguration.isStrictMode());
}
@Test
public void maxNestingDepthIsCloned(){
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.<JSONParserConfiguration>withKeepStrings(true)
.withStrictMode(true);
assertTrue(jsonParserConfiguration.isKeepStrings());
}
@Test
public void useNativeNullsIsCloned() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withUseNativeNulls(true)
.withStrictMode(true);
assertTrue(jsonParserConfiguration.isUseNativeNulls());
}
@Test
public void verifyDuplicateKeyThenMaxDepth() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withOverwriteDuplicateKey(true)
.withMaxNestingDepth(42);
assertEquals(42, jsonParserConfiguration.getMaxNestingDepth());
assertTrue(jsonParserConfiguration.isOverwriteDuplicateKey());
}
@Test
public void verifyMaxDepthThenDuplicateKey() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withMaxNestingDepth(42)
.withOverwriteDuplicateKey(true);
assertTrue(jsonParserConfiguration.isOverwriteDuplicateKey());
assertEquals(42, jsonParserConfiguration.getMaxNestingDepth());
}
@Test
public void givenInvalidInput_testStrictModeTrue_shouldThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
List<String> strictModeInputTestCases = getNonCompliantJSONArrayList();
// this is a lot easier to debug when things stop working
for (int i = 0; i < strictModeInputTestCases.size(); ++i) {
String testCase = strictModeInputTestCases.get(i);
try {
JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration);
String s = jsonArray.toString();
String msg = "Expected an exception, but got: " + s + " Noncompliant Array index: " + i;
fail(msg);
} catch (Exception e) {
// its all good
}
}
}
@Test
public void givenInvalidInputObjects_testStrictModeTrue_shouldThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
List<String> strictModeInputTestCases = getNonCompliantJSONObjectList();
// this is a lot easier to debug when things stop working
for (int i = 0; i < strictModeInputTestCases.size(); ++i) {
String testCase = strictModeInputTestCases.get(i);
try {
JSONObject jsonObject = new JSONObject(testCase, jsonParserConfiguration);
String s = jsonObject.toString();
String msg = "Expected an exception, but got: " + s + " Noncompliant Array index: " + i;
fail(msg);
} catch (Exception e) {
// its all good
}
}
}
@Test
public void givenEmptyArray_testStrictModeTrue_shouldNotThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[]";
JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration);
assertEquals(testCase, jsonArray.toString());
}
@Test
public void givenEmptyObject_testStrictModeTrue_shouldNotThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{}";
JSONObject jsonObject = new JSONObject(testCase, jsonParserConfiguration);
assertEquals(testCase, jsonObject.toString());
}
@Test
public void givenValidNestedArray_testStrictModeTrue_shouldNotThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[[\"c\"], [10.2], [true, false, true]]";
JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration);
JSONArray arrayShouldContainStringAt0 = jsonArray.getJSONArray(0);
JSONArray arrayShouldContainNumberAt0 = jsonArray.getJSONArray(1);
JSONArray arrayShouldContainBooleanAt0 = jsonArray.getJSONArray(2);
assertTrue(arrayShouldContainStringAt0.get(0) instanceof String);
assertTrue(arrayShouldContainNumberAt0.get(0) instanceof Number);
assertTrue(arrayShouldContainBooleanAt0.get(0) instanceof Boolean);
}
@Test
public void givenValidNestedObject_testStrictModeTrue_shouldNotThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{\"a0\":[\"c\"], \"a1\":[10.2], \"a2\":[true, false, true]}";
JSONObject jsonObject = new JSONObject(testCase, jsonParserConfiguration);
JSONArray arrayShouldContainStringAt0 = jsonObject.getJSONArray("a0");
JSONArray arrayShouldContainNumberAt0 = jsonObject.getJSONArray("a1");
JSONArray arrayShouldContainBooleanAt0 = jsonObject.getJSONArray("a2");
assertTrue(arrayShouldContainStringAt0.get(0) instanceof String);
assertTrue(arrayShouldContainNumberAt0.get(0) instanceof Number);
assertTrue(arrayShouldContainBooleanAt0.get(0) instanceof Boolean);
}
@Test
public void givenValidEmptyArrayInsideArray_testStrictModeTrue_shouldNotThrowJsonException(){
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[[]]";
JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration);
assertEquals(testCase, jsonArray.toString());
}
@Test
public void givenValidEmptyArrayInsideObject_testStrictModeTrue_shouldNotThrowJsonException(){
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{\"a0\":[]}";
JSONObject jsonObject = new JSONObject(testCase, jsonParserConfiguration);
assertEquals(testCase, jsonObject.toString());
}
@Test
public void givenValidEmptyArrayInsideArray_testStrictModeFalse_shouldNotThrowJsonException(){
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
String testCase = "[[]]";
JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration);
assertEquals(testCase, jsonArray.toString());
}
@Test
public void givenValidEmptyArrayInsideObject_testStrictModeFalse_shouldNotThrowJsonException(){
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
String testCase = "{\"a0\":[]}";
JSONObject jsonObject = new JSONObject(testCase, jsonParserConfiguration);
assertEquals(testCase, jsonObject.toString());
}
@Test
public void givenInvalidStringArray_testStrictModeTrue_shouldThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[badString]";
JSONException je = assertThrows(JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Value 'badString' is not surrounded by quotes at 10 [character 11 line 1]",
je.getMessage());
}
@Test
public void givenInvalidStringObject_testStrictModeTrue_shouldThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{\"a0\":badString}";
JSONException je = assertThrows(JSONException.class, () -> new JSONObject(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Value 'badString' is not surrounded by quotes at 15 [character 16 line 1]",
je.getMessage());
}
@Test
public void allowNullArrayInStrictMode() {
String expected = "[null]";
JSONArray jsonArray = new JSONArray(expected, new JSONParserConfiguration().withStrictMode(true));
assertEquals(expected, jsonArray.toString());
}
@Test
public void allowNullObjectInStrictMode() {
String expected = "{\"a0\":null}";
JSONObject jsonObject = new JSONObject(expected, new JSONParserConfiguration().withStrictMode(true));
assertEquals(expected, jsonObject.toString());
}
@Test
public void shouldHandleNumericArray() {
String expected = "[10]";
JSONArray jsonArray = new JSONArray(expected, new JSONParserConfiguration().withStrictMode(true));
assertEquals(expected, jsonArray.toString());
}
@Test
public void shouldHandleNumericObject() {
String expected = "{\"a0\":10}";
JSONObject jsonObject = new JSONObject(expected, new JSONParserConfiguration().withStrictMode(true));
assertEquals(expected, jsonObject.toString());
}
@Test
public void givenCompliantJSONArrayFile_testStrictModeTrue_shouldNotThrowAnyException() throws IOException {
try (Stream<String> lines = Files.lines(Paths.get("src/test/resources/compliantJsonArray.json"))) {
String compliantJsonArrayAsString = lines.collect(Collectors.joining());
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
new JSONArray(compliantJsonArrayAsString, jsonParserConfiguration);
}
}
@Test
public void givenCompliantJSONObjectFile_testStrictModeTrue_shouldNotThrowAnyException() throws IOException {
try (Stream<String> lines = Files.lines(Paths.get("src/test/resources/compliantJsonObject.json"))) {
String compliantJsonObjectAsString = lines.collect(Collectors.joining());
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
new JSONObject(compliantJsonObjectAsString, jsonParserConfiguration);
}
}
@Test
public void givenInvalidInputArrays_testStrictModeFalse_shouldNotThrowAnyException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
List<String> strictModeInputTestCases = getNonCompliantJSONArrayList();
// this is a lot easier to debug when things stop working
for (int i = 0; i < strictModeInputTestCases.size(); ++i) {
String testCase = strictModeInputTestCases.get(i);
try {
JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration);
} catch (Exception e) {
System.out.println("Unexpected exception: " + e.getMessage() + " Noncompliant Array index: " + i);
fail(String.format("Noncompliant array index: %d", i));
}
}
}
@Test
public void givenInvalidInputObjects_testStrictModeFalse_shouldNotThrowAnyException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
List<String> strictModeInputTestCases = getNonCompliantJSONObjectList();
// this is a lot easier to debug when things stop working
for (int i = 0; i < strictModeInputTestCases.size(); ++i) {
String testCase = strictModeInputTestCases.get(i);
try {
JSONObject jsonObject = new JSONObject(testCase, jsonParserConfiguration);
} catch (Exception e) {
System.out.println("Unexpected exception: " + e.getMessage() + " Noncompliant Array index: " + i);
fail(String.format("Noncompliant array index: %d", i));
}
}
}
@Test
public void givenInvalidInputArray_testStrictModeTrue_shouldThrowInvalidCharacterErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[1,2];[3,4]";
JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase,
JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Unparsed characters found at end of input text at 6 [character 7 line 1]",
je.getMessage());
}
@Test
public void givenInvalidInputObject_testStrictModeTrue_shouldThrowInvalidCharacterErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{\"a0\":[1,2];\"a1\":[3,4]}";
JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase,
JSONException.class, () -> new JSONObject(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Invalid character ';' found at 12 [character 13 line 1]", je.getMessage());
}
@Test
public void givenInvalidInputArrayWithNumericStrings_testStrictModeTrue_shouldThrowInvalidCharacterErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[\"1\",\"2\"];[3,4]";
JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase,
JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Unparsed characters found at end of input text at 10 [character 11 line 1]",
je.getMessage());
}
@Test
public void givenInvalidInputObjectWithNumericStrings_testStrictModeTrue_shouldThrowInvalidCharacterErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{\"a0\":[\"1\",\"2\"];\"a1\":[3,4]}";
JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase,
JSONException.class, () -> new JSONObject(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Invalid character ';' found at 16 [character 17 line 1]", je.getMessage());
}
@Test
public void givenInvalidInputArray_testStrictModeTrue_shouldThrowValueNotSurroundedByQuotesErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[{\"test\": implied}]";
JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase,
JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Value 'implied' is not surrounded by quotes at 17 [character 18 line 1]",
je.getMessage());
}
@Test
public void givenInvalidInputObject_testStrictModeTrue_shouldThrowValueNotSurroundedByQuotesErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{\"a0\":{\"test\": implied}]}";
JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase,
JSONException.class, () -> new JSONObject(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Value 'implied' is not surrounded by quotes at 22 [character 23 line 1]",
je.getMessage());
}
@Test
public void givenInvalidInputArray_testStrictModeFalse_shouldNotThrowAnyException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
String testCase = "[{\"test\": implied}]";
new JSONArray(testCase, jsonParserConfiguration);
}
@Test
public void givenInvalidInputObject_testStrictModeFalse_shouldNotThrowAnyException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
String testCase = "{\"a0\":{\"test\": implied}}";
new JSONObject(testCase, jsonParserConfiguration);
}
@Test
public void givenNonCompliantQuotesArray_testStrictModeTrue_shouldThrowJsonExceptionWithConcreteErrorDescription() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCaseOne = "[\"abc', \"test\"]";
String testCaseTwo = "['abc\", \"test\"]";
String testCaseThree = "['abc']";
String testCaseFour = "[{'testField': \"testValue\"}]";
JSONException jeOne = assertThrows(JSONException.class,
() -> new JSONArray(testCaseOne, jsonParserConfiguration));
JSONException jeTwo = assertThrows(JSONException.class,
() -> new JSONArray(testCaseTwo, jsonParserConfiguration));
JSONException jeThree = assertThrows(JSONException.class,
() -> new JSONArray(testCaseThree, jsonParserConfiguration));
JSONException jeFour = assertThrows(JSONException.class,
() -> new JSONArray(testCaseFour, jsonParserConfiguration));
assertEquals(
"Expected a ',' or ']' at 10 [character 11 line 1]",
jeOne.getMessage());
assertEquals(
"Strict mode error: Single quoted strings are not allowed at 2 [character 3 line 1]",
jeTwo.getMessage());
assertEquals(
"Strict mode error: Single quoted strings are not allowed at 2 [character 3 line 1]",
jeThree.getMessage());
assertEquals(
"Strict mode error: Single quoted strings are not allowed at 3 [character 4 line 1]",
jeFour.getMessage());
}
@Test
public void givenNonCompliantQuotesObject_testStrictModeTrue_shouldThrowJsonExceptionWithConcreteErrorDescription() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCaseOne = "{\"abc': \"test\"}";
String testCaseTwo = "{'abc\": \"test\"}";
String testCaseThree = "{\"a\":'abc'}";
String testCaseFour = "{'testField': \"testValue\"}";
JSONException jeOne = assertThrows(JSONException.class,
() -> new JSONObject(testCaseOne, jsonParserConfiguration));
JSONException jeTwo = assertThrows(JSONException.class,
() -> new JSONObject(testCaseTwo, jsonParserConfiguration));
JSONException jeThree = assertThrows(JSONException.class,
() -> new JSONObject(testCaseThree, jsonParserConfiguration));
JSONException jeFour = assertThrows(JSONException.class,
() -> new JSONObject(testCaseFour, jsonParserConfiguration));
assertEquals(
"Expected a ':' after a key at 10 [character 11 line 1]",
jeOne.getMessage());
assertEquals(
"Strict mode error: Single quoted strings are not allowed at 2 [character 3 line 1]",
jeTwo.getMessage());
assertEquals(
"Strict mode error: Single quoted strings are not allowed at 6 [character 7 line 1]",
jeThree.getMessage());
assertEquals(
"Strict mode error: Single quoted strings are not allowed at 2 [character 3 line 1]",
jeFour.getMessage());
}
@Test
public void givenUnbalancedQuotesArray_testStrictModeFalse_shouldThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
String testCaseOne = "[\"abc', \"test\"]";
String testCaseTwo = "['abc\", \"test\"]";
JSONException jeOne = assertThrows(JSONException.class,
() -> new JSONArray(testCaseOne, jsonParserConfiguration));
JSONException jeTwo = assertThrows(JSONException.class,
() -> new JSONArray(testCaseTwo, jsonParserConfiguration));
assertEquals("Expected a ',' or ']' at 10 [character 11 line 1]", jeOne.getMessage());
assertEquals("Unterminated string. Character with int code 0 is not allowed within a quoted string. at 15 [character 16 line 1]", jeTwo.getMessage());
}
@Test
public void givenUnbalancedQuotesObject_testStrictModeFalse_shouldThrowJsonException() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(false);
String testCaseOne = "{\"abc': \"test\"}";
String testCaseTwo = "{'abc\": \"test\"}";
JSONException jeOne = assertThrows(JSONException.class,
() -> new JSONObject(testCaseOne, jsonParserConfiguration));
JSONException jeTwo = assertThrows(JSONException.class,
() -> new JSONObject(testCaseTwo, jsonParserConfiguration));
assertEquals("Expected a ':' after a key at 10 [character 11 line 1]", jeOne.getMessage());
assertEquals("Unterminated string. Character with int code 0 is not allowed within a quoted string. at 15 [character 16 line 1]", jeTwo.getMessage());
}
@Test
public void givenInvalidInputArray_testStrictModeTrue_shouldThrowKeyNotSurroundedByQuotesErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "[{test: implied}]";
JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase,
JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Value 'test' is not surrounded by quotes at 6 [character 7 line 1]",
je.getMessage());
}
@Test
public void givenInvalidInputObject_testStrictModeTrue_shouldThrowKeyNotSurroundedByQuotesErrorMessage() {
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
.withStrictMode(true);
String testCase = "{test: implied}";
JSONException je = assertThrows("expected non-compliant json but got instead: " + testCase,
JSONException.class, () -> new JSONObject(testCase, jsonParserConfiguration));
assertEquals("Strict mode error: Value 'test' is not surrounded by quotes at 5 [character 6 line 1]",
je.getMessage());
}
@Test
public void givenInvalidInputObject_testStrictModeTrue_JSONObjectUsingJSONTokener_shouldThrowJSONException() {
JSONException exception = assertThrows(JSONException.class, () -> {
new JSONObject(new JSONTokener("{\"key\":\"value\"} invalid trailing text"), new JSONParserConfiguration().withStrictMode(true));
});
assertEquals("Strict mode error: Unparsed characters found at end of input text at 17 [character 18 line 1]", exception.getMessage());
}
@Test
public void givenInvalidInputObject_testStrictModeTrue_JSONObjectUsingString_shouldThrowJSONException() {
JSONException exception = assertThrows(JSONException.class, () -> {
new JSONObject("{\"key\":\"value\"} invalid trailing text", new JSONParserConfiguration().withStrictMode(true));
});
assertEquals("Strict mode error: Unparsed characters found at end of input text at 17 [character 18 line 1]", exception.getMessage());
}
@Test
public void givenInvalidInputObject_testStrictModeTrue_JSONArrayUsingJSONTokener_shouldThrowJSONException() {
JSONException exception = assertThrows(JSONException.class, () -> {
new JSONArray(new JSONTokener("[\"value\"] invalid trailing text"), new JSONParserConfiguration().withStrictMode(true));
});
assertEquals("Strict mode error: Unparsed characters found at end of input text at 11 [character 12 line 1]", exception.getMessage());
}
@Test
public void givenInvalidInputObject_testStrictModeTrue_JSONArrayUsingString_shouldThrowJSONException() {
JSONException exception = assertThrows(JSONException.class, () -> {
new JSONArray("[\"value\"] invalid trailing text", new JSONParserConfiguration().withStrictMode(true));
});
assertEquals("Strict mode error: Unparsed characters found at end of input text at 11 [character 12 line 1]", exception.getMessage());
}
/**
* This method contains short but focused use-case samples and is exclusively used to test strictMode unit tests in
* this class.
*
* @return List with JSON strings.
*/
private List<String> getNonCompliantJSONArrayList() {
return Arrays.asList(
"[1],",
"[1,]",
"[,]",
"[,,]",
"[[1],\"sa\",[2]]a",
"[1],\"dsa\": \"test\"",
"[[a]]",
"[]asdf",
"[]]",
"[]}",
"[][",
"[]{",
"[],",
"[]:",
"[],[",
"[],{",
"[1,2];[3,4]",
"[test]",
"[{'testSingleQuote': 'testSingleQuote'}]",
"[1, 2,3]:[4,5]",
"[{test: implied}]",
"[{\"test\": implied}]",
"[{\"number\":\"7990154836330\",\"color\":'c'},{\"number\":8784148854580,\"color\":RosyBrown},{\"number\":\"5875770107113\",\"color\":\"DarkSeaGreen\"}]",
"[{test: \"implied\"}]");
}
/**
* This method contains short but focused use-case samples and is exclusively used to test strictMode unit tests in
* this class.
*
* @return List with JSON strings.
*/
private List<String> getNonCompliantJSONObjectList() {
return Arrays.asList(
"{\"a\":1},",
"{\"a\":1,}",
"{\"a0\":[1],\"a1\":\"sa\",\"a2\":[2]}a",
"{\"a\":1},\"dsa\": \"test\"",
"{\"a\":[a]}",
"{}asdf",
"{}}",
"{}]",
"{}{",
"{}[",
"{},",
"{}:",
"{},{",
"{},[",
"{\"a0\":[1,2];\"a1\":[3,4]}",
"{\"a\":test}",
"{a:{'testSingleQuote': 'testSingleQuote'}}",
"{\"a0\":1, \"a1\":2,\"a2\":3}:{\"a3\":4,\"a4\":5}",
"{\"a\":{test: implied}}",
"{a:{\"test\": implied}}",
"{a:[{\"number\":\"7990154836330\",\"color\":'c'},{\"number\":8784148854580,\"color\":RosyBrown},{\"number\":\"5875770107113\",\"color\":\"DarkSeaGreen\"}]}",
"{a:{test: \"implied\"}}"
);
}
}

View File

@ -0,0 +1,398 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.InputStream;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONPointer;
import org.json.JSONPointerException;
import org.json.JSONTokener;
import org.junit.Test;
public class JSONPointerTest {
private static final JSONObject document;
private static final String EXPECTED_COMPLETE_DOCUMENT = "{\"\":0,\" \":7,\"g|h\":4,\"c%d\":2,\"k\\\"l\":6,\"a/b\":1,\"i\\\\j\":5," +
"\"obj\":{\"\":{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some other value\"}," +
"\"other~key\":{\"another/key\":[\"val\"]},\"key\":\"value\"},\"foo\":[\"bar\",\"baz\"],\"e^f\":3," +
"\"m~n\":8}";
static {
@SuppressWarnings("resource")
InputStream resourceAsStream = JSONPointerTest.class.getClassLoader().getResourceAsStream("jsonpointer-testdoc.json");
if(resourceAsStream == null) {
throw new ExceptionInInitializerError("Unable to locate test file. Please check your development environment configuration");
}
document = new JSONObject(new JSONTokener(resourceAsStream));
}
private Object query(String pointer) {
return new JSONPointer(pointer).queryFrom(document);
}
@Test
public void emptyPointer() {
assertTrue(new JSONObject(EXPECTED_COMPLETE_DOCUMENT).similar(query("")));
}
@SuppressWarnings("unused")
@Test(expected = NullPointerException.class)
public void nullPointer() {
new JSONPointer((String) null);
}
@Test
public void objectPropertyQuery() {
assertEquals("[\"bar\",\"baz\"]", query("/foo").toString());
}
@Test
public void arrayIndexQuery() {
assertEquals("bar", query("/foo/0"));
}
@Test(expected = JSONPointerException.class)
public void stringPropOfArrayFailure() {
query("/foo/bar");
}
@Test
public void queryByEmptyKey() {
assertEquals(0, query("/"));
}
@Test
public void queryByEmptyKeySubObject() {
JSONObject json = new JSONObject("{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some" +
" other value\"}");
JSONObject obj = (JSONObject) query("/obj/");
assertTrue(json.similar(obj));
}
@Test
public void queryByEmptyKeySubObjectSubOject() {
assertEquals("empty key of an object with an empty key", query("/obj//"));
}
@Test
public void queryByEmptyKeySubObjectValue() {
assertEquals("Some other value", query("/obj//subKey"));
}
@Test
public void slashEscaping() {
assertEquals(1, query("/a~1b"));
}
@Test
public void tildeEscaping() {
assertEquals(8, query("/m~0n"));
}
/**
* We pass backslashes as-is
*
* @see <a href="https://tools.ietf.org/html/rfc6901#section-3">rfc6901 section 3</a>
*/
@Test
public void backslashHandling() {
assertEquals(5, query("/i\\j"));
}
/**
* We pass quotations as-is
*
* @see <a href="https://tools.ietf.org/html/rfc6901#section-3">rfc6901 section 3</a>
*/
@Test
public void quotationHandling() {
assertEquals(6, query("/k\"l"));
}
@Test
public void whitespaceKey() {
assertEquals(7, query("/ "));
}
@Test
public void uriFragmentNotation() {
assertEquals("[\"bar\",\"baz\"]", query("#/foo").toString());
}
@Test
public void uriFragmentNotationRoot() {
assertTrue(new JSONObject(EXPECTED_COMPLETE_DOCUMENT).similar(query("#")));
}
@Test
public void uriFragmentPercentHandling() {
assertEquals(2, query("#/c%25d"));
assertEquals(3, query("#/e%5Ef"));
assertEquals(4, query("#/g%7Ch"));
assertEquals(8, query("#/m~0n"));
}
@SuppressWarnings("unused")
@Test(expected = IllegalArgumentException.class)
public void syntaxError() {
new JSONPointer("key");
}
@Test(expected = JSONPointerException.class)
public void arrayIndexFailure() {
query("/foo/2");
}
@Test(expected = JSONPointerException.class)
public void primitiveFailure() {
query("/obj/key/failure");
}
@Test
public void builderTest() {
JSONPointer pointer = JSONPointer.builder()
.append("obj")
.append("other~key").append("another/key")
.append(0)
.build();
assertEquals("val", pointer.queryFrom(document));
}
@Test(expected = NullPointerException.class)
public void nullToken() {
JSONPointer.builder().append(null);
}
@Test
public void toStringEscaping() {
JSONPointer pointer = JSONPointer.builder()
.append("obj")
.append("other~key").append("another/key")
.append("\"")
.append(0)
.build();
assertEquals("/obj/other~0key/another~1key/\"/0", pointer.toString());
}
@Test
public void emptyPointerToString() {
assertEquals("", new JSONPointer("").toString());
}
@Test
public void toURIFragment() {
assertEquals("#/c%25d", new JSONPointer("/c%d").toURIFragment());
assertEquals("#/e%5Ef", new JSONPointer("/e^f").toURIFragment());
assertEquals("#/g%7Ch", new JSONPointer("/g|h").toURIFragment());
assertEquals("#/m%7En", new JSONPointer("/m~n").toURIFragment());
}
@Test
public void tokenListIsCopiedInConstructor() {
JSONPointer.Builder b = JSONPointer.builder().append("key1");
JSONPointer jp1 = b.build();
b.append("key2");
JSONPointer jp2 = b.build();
if(jp1.toString().equals(jp2.toString())) {
fail("Oops, my pointers are sharing a backing array");
}
}
/**
* Coverage for JSONObject query(String)
*/
@Test
public void queryFromJSONObject() {
String str = "{"+
"\"stringKey\":\"hello world!\","+
"\"arrayKey\":[0,1,2],"+
"\"objectKey\": {"+
"\"a\":\"aVal\","+
"\"b\":\"bVal\""+
"}"+
"}";
JSONObject jsonObject = new JSONObject(str);
Object obj = jsonObject.query("/stringKey");
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
obj = jsonObject.query("/arrayKey/1");
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
obj = jsonObject.query("/objectKey/b");
assertTrue("Expected bVal", "bVal".equals(obj));
try {
obj = jsonObject.query("/a/b/c");
assertTrue("Expected JSONPointerException", false);
} catch (JSONPointerException e) {
assertTrue("Expected bad key/value exception",
"value [null] is not an array or object therefore its key b cannot be resolved".
equals(e.getMessage()));
}
}
/**
* Coverage for JSONObject query(JSONPointer)
*/
@Test
public void queryFromJSONObjectUsingPointer() {
String str = "{"+
"\"stringKey\":\"hello world!\","+
"\"arrayKey\":[0,1,2],"+
"\"objectKey\": {"+
"\"a\":\"aVal\","+
"\"b\":\"bVal\""+
"}"+
"}";
JSONObject jsonObject = new JSONObject(str);
Object obj = jsonObject.query(new JSONPointer("/stringKey"));
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
obj = jsonObject.query(new JSONPointer("/arrayKey/1"));
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
obj = jsonObject.query(new JSONPointer("/objectKey/b"));
assertTrue("Expected bVal", "bVal".equals(obj));
try {
obj = jsonObject.query(new JSONPointer("/a/b/c"));
assertTrue("Expected JSONPointerException", false);
} catch (JSONPointerException e) {
assertTrue("Expected bad key/value exception",
"value [null] is not an array or object therefore its key b cannot be resolved".
equals(e.getMessage()));
}
}
/**
* Coverage for JSONObject optQuery(JSONPointer)
*/
@Test
public void optQueryFromJSONObjectUsingPointer() {
String str = "{"+
"\"stringKey\":\"hello world!\","+
"\"arrayKey\":[0,1,2],"+
"\"objectKey\": {"+
"\"a\":\"aVal\","+
"\"b\":\"bVal\""+
"}"+
"}";
JSONObject jsonObject = new JSONObject(str);
Object obj = jsonObject.optQuery(new JSONPointer("/stringKey"));
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
obj = jsonObject.optQuery(new JSONPointer("/arrayKey/1"));
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
obj = jsonObject.optQuery(new JSONPointer("/objectKey/b"));
assertTrue("Expected bVal", "bVal".equals(obj));
obj = jsonObject.optQuery(new JSONPointer("/a/b/c"));
assertTrue("Expected null", obj == null);
}
/**
* Coverage for JSONArray query(String)
*/
@Test
public void queryFromJSONArray() {
String str = "["+
"\"hello world!\","+
"[0,1,2],"+
"{"+
"\"a\":\"aVal\","+
"\"b\":\"bVal\""+
"}"+
"]";
JSONArray jsonArray = new JSONArray(str);
Object obj = jsonArray.query("/0");
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
obj = jsonArray.query("/1/1");
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
obj = jsonArray.query("/2/b");
assertTrue("Expected bVal", "bVal".equals(obj));
try {
obj = jsonArray.query("/a/b/c");
assertTrue("Expected JSONPointerException", false);
} catch (JSONPointerException e) {
assertTrue("Expected bad index exception",
"a is not an array index".equals(e.getMessage()));
}
}
/**
* Coverage for JSONArray query(JSONPointer)
*/
@Test
public void queryFromJSONArrayUsingPointer() {
String str = "["+
"\"hello world!\","+
"[0,1,2],"+
"{"+
"\"a\":\"aVal\","+
"\"b\":\"bVal\""+
"}"+
"]";
JSONArray jsonArray = new JSONArray(str);
Object obj = jsonArray.query(new JSONPointer("/0"));
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
obj = jsonArray.query(new JSONPointer("/1/1"));
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
obj = jsonArray.query(new JSONPointer("/2/b"));
assertTrue("Expected bVal", "bVal".equals(obj));
try {
obj = jsonArray.query(new JSONPointer("/a/b/c"));
assertTrue("Expected JSONPointerException", false);
} catch (JSONPointerException e) {
assertTrue("Expected bad index exception",
"a is not an array index".equals(e.getMessage()));
}
}
/**
* Coverage for JSONArray optQuery(JSONPointer)
*/
@Test
public void optQueryFromJSONArrayUsingPointer() {
String str = "["+
"\"hello world!\","+
"[0,1,2],"+
"{"+
"\"a\":\"aVal\","+
"\"b\":\"bVal\""+
"}"+
"]";
JSONArray jsonArray = new JSONArray(str);
Object obj = jsonArray.optQuery(new JSONPointer("/0"));
assertTrue("Expected 'hello world!'", "hello world!".equals(obj));
obj = jsonArray.optQuery(new JSONPointer("/1/1"));
assertTrue("Expected 1", Integer.valueOf(1).equals(obj));
obj = jsonArray.optQuery(new JSONPointer("/2/b"));
assertTrue("Expected bVal", "bVal".equals(obj));
obj = jsonArray.optQuery(new JSONPointer("/a/b/c"));
assertTrue("Expected null", obj == null);
}
/**
* When creating a jsonObject we need to parse escaped characters "\\\\"
* --> it's the string representation of "\\", so when query'ing via the JSONPointer
* we DON'T escape them
*
*/
@Test
public void queryFromJSONObjectUsingPointer0() {
String str = "{"+
"\"string\\\\\\\\Key\":\"hello world!\","+
"\"\\\\\":\"slash test\"" +
"}";
JSONObject jsonObject = new JSONObject(str);
//Summary of issue: When a KEY in the jsonObject is "\\\\" --> it's held
// as "\\" which means when querying, we need to use "\\"
Object twoBackslahObj = jsonObject.optQuery(new JSONPointer("/\\"));
assertEquals("slash test", twoBackslahObj);
Object fourBackslashObj = jsonObject.optQuery(new JSONPointer("/string\\\\Key"));
assertEquals("hello world!", fourBackslashObj);
}
}

View File

@ -0,0 +1,401 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import java.io.StringWriter;
import java.util.*;
import org.json.*;
import org.junit.Test;
/**
* Tests for JSONString implementations, and the difference between
* {@link JSONObject#valueToString} and {@link JSONObject#writeValue}.
*/
public class JSONStringTest {
/**
* This tests the JSONObject.writeValue() method. We can't test directly
* due to it being a package-protected method. Instead, we can call
* JSONArray.write(), which delegates the writing of each entry to
* writeValue().
*/
@Test
public void writeValues() throws Exception {
JSONArray jsonArray = new JSONArray();
jsonArray.put((Object)null);
StringWriter writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[null]".equals(output));
jsonArray = new JSONArray();
jsonArray.put(JSONObject.NULL);
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[null]".equals(output));
jsonArray = new JSONArray();
jsonArray.put(new JSONObject());
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[{}]".equals(output));
jsonArray = new JSONArray();
jsonArray.put(new JSONArray());
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[[]]".equals(output));
jsonArray = new JSONArray();
Map<?,?> singleMap = Collections.singletonMap("key1", "value1");
jsonArray.put((Object)singleMap);
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[{\"key1\":\"value1\"}]".equals(output));
jsonArray = new JSONArray();
List<?> singleList = Collections.singletonList("entry1");
jsonArray.put((Object)singleList);
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[[\"entry1\"]]".equals(output));
jsonArray = new JSONArray();
int[] intArray = new int[] { 1, 2, 3 };
jsonArray.put(intArray);
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[[1,2,3]]".equals(output));
jsonArray = new JSONArray();
jsonArray.put(24);
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[24]".equals(output));
jsonArray = new JSONArray();
jsonArray.put("string value");
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[\"string value\"]".equals(output));
jsonArray = new JSONArray();
jsonArray.put(true);
} finally {
writer.close();
}
writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[true]".equals(output));
} finally {
writer.close();
}
}
/**
* This tests the JSONObject.valueToString() method. These should be
* identical to the values above, except for the enclosing [ and ].
*/
@SuppressWarnings("boxing")
@Test
public void valuesToString() throws Exception {
String output = JSONObject.valueToString(null);
assertTrue("String values should be equal", "null".equals(output));
output = JSONObject.valueToString(JSONObject.NULL);
assertTrue("String values should be equal", "null".equals(output));
output = JSONObject.valueToString(new JSONObject());
assertTrue("String values should be equal", "{}".equals(output));
output = JSONObject.valueToString(new JSONArray());
assertTrue("String values should be equal", "[]".equals(output));
Map<?,?> singleMap = Collections.singletonMap("key1", "value1");
output = JSONObject.valueToString(singleMap);
assertTrue("String values should be equal", "{\"key1\":\"value1\"}".equals(output));
List<?> singleList = Collections.singletonList("entry1");
output = JSONObject.valueToString(singleList);
assertTrue("String values should be equal", "[\"entry1\"]".equals(output));
int[] intArray = new int[] { 1, 2, 3 };
output = JSONObject.valueToString(intArray);
assertTrue("String values should be equal", "[1,2,3]".equals(output));
output = JSONObject.valueToString(24);
assertTrue("String values should be equal", "24".equals(output));
output = JSONObject.valueToString("string value");
assertTrue("String values should be equal", "\"string value\"".equals(output));
output = JSONObject.valueToString(true);
assertTrue("String values should be equal", "true".equals(output));
}
/**
* Test what happens when toJSONString() returns a well-formed JSON value.
* This is the usual case.
*/
@Test
public void testJSONStringValue() throws Exception {
JSONStringValue jsonString = new JSONStringValue();
JSONArray jsonArray = new JSONArray();
jsonArray.put(jsonString);
StringWriter writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[\"the JSON string value\"]".equals(output));
output = JSONObject.valueToString(jsonString);
assertTrue("String values should be equal", "\"the JSON string value\"".equals(output));
} finally {
writer.close();
}
}
/**
* Test what happens when toJSONString() returns null. In one case,
* use the object's toString() method. In the other, throw a JSONException.
*/
@Test
public void testJSONNullStringValue() throws Exception {
JSONNullStringValue jsonString = new JSONNullStringValue();
JSONArray jsonArray = new JSONArray();
jsonArray.put(jsonString);
StringWriter writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[\"the toString value\"]".equals(output));
// The only different between writeValue() and valueToString():
// in this case, valueToString throws a JSONException
try {
output = JSONObject.valueToString(jsonString);
fail("Expected an exception, got a String value");
} catch (Exception e) {
assertTrue("Expected JSONException", e instanceof JSONException);
assertTrue("Exception message does not match", "Bad value from toJSONString: null".equals(e.getMessage()));
}
} finally {
writer.close();
}
}
/**
* Test what happens when toJSONString() returns an exception. In both
* cases, a JSONException is thrown, with the cause and message set from
* the original exception.
*/
@Test
public void testJSONStringExceptionValue() {
JSONStringExceptionValue jsonString = new JSONStringExceptionValue();
JSONArray jsonArray = new JSONArray();
jsonArray.put(jsonString);
StringWriter writer = new StringWriter();
try {
jsonArray.write(writer).toString();
fail("Expected an exception, got a String value");
} catch (JSONException e) {
assertEquals("Unable to write JSONArray value at index: 0", e.getMessage());
} catch(Exception e) {
fail("Expected JSONException");
} finally {
try {
writer.close();
} catch (Exception e){}
}
try {
JSONObject.valueToString(jsonString);
fail("Expected an exception, got a String value");
} catch (JSONException e) {
assertTrue("Exception message does not match", "the exception value".equals(e.getMessage()));
} catch(Exception e) {
fail("Expected JSONException");
}
}
/**
* Test what happens when a Java object's toString() returns a String value.
* This is the usual case.
*/
@Test
public void testStringValue() throws Exception {
StringValue nonJsonString = new StringValue();
JSONArray jsonArray = new JSONArray();
jsonArray.put(nonJsonString);
StringWriter writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[\"the toString value for StringValue\"]".equals(output));
output = JSONObject.valueToString(nonJsonString);
assertTrue("String values should be equal", "\"the toString value for StringValue\"".equals(output));
} finally {
writer.close();
}
}
/**
* Test what happens when a Java object's toString() returns null.
* Defaults to empty string.
*/
@Test
public void testNullStringValue() throws Exception {
NullStringValue nonJsonString = new NullStringValue();
JSONArray jsonArray = new JSONArray();
jsonArray.put(nonJsonString);
StringWriter writer = new StringWriter();
try {
String output = jsonArray.write(writer).toString();
assertTrue("String values should be equal", "[\"\"]".equals(output));
output = JSONObject.valueToString(nonJsonString);
assertTrue("String values should be equal", "\"\"".equals(output));
} finally {
writer.close();
}
}
@Test
public void testEnumJSONString() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", MyEnum.MY_ENUM);
assertEquals("{\"key\":\"myJsonString\"}", jsonObject.toString());
}
private enum MyEnum implements JSONString {
MY_ENUM;
@Override
public String toJSONString() {
return "\"myJsonString\"";
}
}
/**
* A JSONString that returns a valid JSON string value.
*/
private static final class JSONStringValue implements JSONString {
@Override
public String toJSONString() {
return "\"the JSON string value\"";
}
@Override
public String toString() {
return "the toString value for JSONStringValue";
}
}
/**
* A JSONString that returns null when calling toJSONString().
*/
private static final class JSONNullStringValue implements JSONString {
@Override
public String toJSONString() {
return null;
}
@Override
public String toString() {
return "the toString value";
}
}
/**
* A JSONString that throw an exception when calling toJSONString().
*/
private static final class JSONStringExceptionValue implements JSONString {
@Override
public String toJSONString() {
throw new IllegalStateException("the exception value");
}
@Override
public String toString() {
return "the toString value for JSONStringExceptionValue";
}
}
public static final class StringValue {
@Override
public String toString() {
return "the toString value for StringValue";
}
}
public static final class NullStringValue {
@Override
public String toString() {
return null;
}
}
}

View File

@ -0,0 +1,357 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.util.*;
import org.json.*;
import org.junit.Test;
import com.jayway.jsonpath.*;
/**
* Tests for JSON-Java JSONStringer and JSONWriter.
*/
public class JSONStringerTest {
/**
* Object with a null key.
* Expects a JSONException.
*/
@Test
public void nullKeyException() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.object();
try {
jsonStringer.key(null);
assertTrue("Expected an exception", false);
} catch (JSONException e) {
assertTrue("Expected an exception message",
"Null key.".
equals(e.getMessage()));
}
}
/**
* Add a key with no object.
* Expects a JSONException.
*/
@Test
public void outOfSequenceException() {
JSONStringer jsonStringer = new JSONStringer();
try {
jsonStringer.key("hi");
assertTrue("Expected an exception", false);
} catch (JSONException e) {
assertTrue("Expected an exception message",
"Misplaced key.".
equals(e.getMessage()));
}
}
/**
* Missplace an array.
* Expects a JSONException
*/
@Test
public void missplacedArrayException() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.object().endObject();
try {
jsonStringer.array();
assertTrue("Expected an exception", false);
} catch (JSONException e) {
assertTrue("Expected an exception message",
"Misplaced array.".
equals(e.getMessage()));
}
}
/**
* Missplace an endErray.
* Expects a JSONException
*/
@Test
public void missplacedEndArrayException() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.object();
try {
jsonStringer.endArray();
assertTrue("Expected an exception", false);
} catch (JSONException e) {
assertTrue("Expected an exception message",
"Misplaced endArray.".
equals(e.getMessage()));
}
}
/**
* Missplace an endObject.
* Expects a JSONException
*/
@Test
public void missplacedEndObjectException() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.array();
try {
jsonStringer.endObject();
assertTrue("Expected an exception", false);
} catch (JSONException e) {
assertTrue("Expected an exception message",
"Misplaced endObject.".
equals(e.getMessage()));
}
}
/**
* Missplace an object.
* Expects a JSONException.
*/
@Test
public void missplacedObjectException() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.object().endObject();
try {
jsonStringer.object();
assertTrue("Expected an exception", false);
} catch (JSONException e) {
assertTrue("Expected an exception message",
"Misplaced object.".
equals(e.getMessage()));
}
}
/**
* Exceeds implementation max nesting depth.
* Expects a JSONException
*/
@Test
public void exceedNestDepthException() {
try {
JSONStringer s = new JSONStringer();
s.object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object();
s.key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object().
key("k").object().key("k").object().key("k").object().key("k").object().key("k").object();
fail("Expected an exception message");
} catch (JSONException e) {
assertTrue("Expected an exception message",
"Nesting too deep.".
equals(e.getMessage()));
}
}
/**
* Build a JSON doc using JSONString API calls,
* then convert to JSONObject
*/
@Test
public void simpleObjectString() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.object();
jsonStringer.key("trueValue").value(true);
jsonStringer.key("falseValue").value(false);
jsonStringer.key("nullValue").value(null);
jsonStringer.key("stringValue").value("hello world!");
jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!");
jsonStringer.key("intValue").value(42);
jsonStringer.key("doubleValue").value(-23.45e67);
jsonStringer.endObject();
String str = jsonStringer.toString();
JSONObject jsonObject = new JSONObject(str);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 7 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 7);
assertTrue("expected true", Boolean.TRUE.equals(jsonObject.query("/trueValue")));
assertTrue("expected false", Boolean.FALSE.equals(jsonObject.query("/falseValue")));
assertTrue("expected null", JSONObject.NULL.equals(jsonObject.query("/nullValue")));
assertTrue("expected hello world!", "hello world!".equals(jsonObject.query("/stringValue")));
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/complexStringValue")));
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/intValue")));
assertTrue("expected -23.45e67", BigDecimal.valueOf(-23.45e67).equals(jsonObject.query("/doubleValue")));
}
/**
* Build a JSON doc using JSONString API calls,
* then convert to JSONArray
*/
@Test
public void simpleArrayString() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.array();
jsonStringer.value(true);
jsonStringer.value(false);
jsonStringer.value(null);
jsonStringer.value("hello world!");
jsonStringer.value(42);
jsonStringer.value(-23.45e67);
jsonStringer.endArray();
String str = jsonStringer.toString();
JSONArray jsonArray = new JSONArray(str);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonArray.toString());
assertTrue("expected 6 top level items", ((List<?>)(JsonPath.read(doc, "$"))).size() == 6);
assertTrue("expected true", Boolean.TRUE.equals(jsonArray.query("/0")));
assertTrue("expected false", Boolean.FALSE.equals(jsonArray.query("/1")));
assertTrue("expected null", JSONObject.NULL.equals(jsonArray.query("/2")));
assertTrue("expected hello world!", "hello world!".equals(jsonArray.query("/3")));
assertTrue("expected 42", Integer.valueOf(42).equals(jsonArray.query("/4")));
assertTrue("expected -23.45e67", BigDecimal.valueOf(-23.45e67).equals(jsonArray.query("/5")));
}
/**
* Build a nested JSON doc using JSONString API calls, then convert to
* JSONObject. Will create a long cascade of output by reusing the
* returned values..
*/
@Test
public void complexObjectString() {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.object().
key("trueValue").value(true).
key("falseValue").value(false).
key("nullValue").value(null).
key("stringValue").value("hello world!").
key("object2").object().
key("k1").value("v1").
key("k2").value("v2").
key("k3").value("v3").
key("array1").array().
value(1).
value(2).
object().
key("k4").value("v4").
key("k5").value("v5").
key("k6").value("v6").
key("array2").array().
value(5).
value(6).
value(7).
value(8).
endArray().
endObject().
value(3).
value(4).
endArray().
endObject().
key("complexStringValue").value("h\be\tllo w\u1234orld!").
key("intValue").value(42).
key("doubleValue").value(-23.45e67).
endObject();
String str = jsonStringer.toString();
JSONObject jsonObject = new JSONObject(str);
// validate JSON content
Object doc = Configuration.defaultConfiguration().jsonProvider().parse(jsonObject.toString());
assertTrue("expected 8 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 8);
assertTrue("expected 4 object2 items", ((Map<?,?>)(JsonPath.read(doc, "$.object2"))).size() == 4);
assertTrue("expected 5 array1 items", ((List<?>)(JsonPath.read(doc, "$.object2.array1"))).size() == 5);
assertTrue("expected 4 array[2] items", ((Map<?,?>)(JsonPath.read(doc, "$.object2.array1[2]"))).size() == 4);
assertTrue("expected 4 array1[2].array2 items", ((List<?>)(JsonPath.read(doc, "$.object2.array1[2].array2"))).size() == 4);
assertTrue("expected true", Boolean.TRUE.equals(jsonObject.query("/trueValue")));
assertTrue("expected false", Boolean.FALSE.equals(jsonObject.query("/falseValue")));
assertTrue("expected null", JSONObject.NULL.equals(jsonObject.query("/nullValue")));
assertTrue("expected hello world!", "hello world!".equals(jsonObject.query("/stringValue")));
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/intValue")));
assertTrue("expected -23.45e67", BigDecimal.valueOf(-23.45e67).equals(jsonObject.query("/doubleValue")));
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/complexStringValue")));
assertTrue("expected v1", "v1".equals(jsonObject.query("/object2/k1")));
assertTrue("expected v2", "v2".equals(jsonObject.query("/object2/k2")));
assertTrue("expected v3", "v3".equals(jsonObject.query("/object2/k3")));
assertTrue("expected 1", Integer.valueOf(1).equals(jsonObject.query("/object2/array1/0")));
assertTrue("expected 2", Integer.valueOf(2).equals(jsonObject.query("/object2/array1/1")));
assertTrue("expected v4", "v4".equals(jsonObject.query("/object2/array1/2/k4")));
assertTrue("expected v5", "v5".equals(jsonObject.query("/object2/array1/2/k5")));
assertTrue("expected v6", "v6".equals(jsonObject.query("/object2/array1/2/k6")));
assertTrue("expected 5", Integer.valueOf(5).equals(jsonObject.query("/object2/array1/2/array2/0")));
assertTrue("expected 6", Integer.valueOf(6).equals(jsonObject.query("/object2/array1/2/array2/1")));
assertTrue("expected 7", Integer.valueOf(7).equals(jsonObject.query("/object2/array1/2/array2/2")));
assertTrue("expected 8", Integer.valueOf(8).equals(jsonObject.query("/object2/array1/2/array2/3")));
assertTrue("expected 3", Integer.valueOf(3).equals(jsonObject.query("/object2/array1/3")));
assertTrue("expected 4", Integer.valueOf(4).equals(jsonObject.query("/object2/array1/4")));
}
}

View File

@ -0,0 +1,373 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import org.json.*;
import org.junit.Test;
/**
* Test specific to the {@link org.json.JSONTokener} class.
* @author John Aylward
*
*/
public class JSONTokenerTest {
/**
* verify that back() fails as expected.
* @throws IOException thrown if something unexpected happens.
*/
@Test
public void verifyBackFailureZeroIndex() throws IOException {
Reader reader = new StringReader("some test string");
try {
final JSONTokener tokener = new JSONTokener(reader);
try {
// this should fail since the index is 0;
tokener.back();
fail("Expected an exception");
} catch (JSONException e) {
assertEquals("Stepping back two steps is not supported", e.getMessage());
} catch (Exception e) {
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
}
} finally {
reader.close();
}
}
/**
* verify that back() fails as expected.
* @throws IOException thrown if something unexpected happens.
*/
@Test
public void verifyBackFailureDoubleBack() throws IOException {
Reader reader = new StringReader("some test string");
try {
final JSONTokener tokener = new JSONTokener(reader);
tokener.next();
tokener.back();
try {
// this should fail since the index is 0;
tokener.back();
fail("Expected an exception");
} catch (JSONException e) {
assertEquals("Stepping back two steps is not supported", e.getMessage());
} catch (Exception e) {
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
}
} finally {
reader.close();
}
}
@Test
public void testValid() {
checkValid("0",Number.class);
checkValid(" 0 ",Number.class);
checkValid("23",Number.class);
checkValid("23.5",Number.class);
checkValid(" 23.5 ",Number.class);
checkValid("null",null);
checkValid(" null ",null);
checkValid("true",Boolean.class);
checkValid(" true\n",Boolean.class);
checkValid("false",Boolean.class);
checkValid("\nfalse ",Boolean.class);
checkValid("{}",JSONObject.class);
checkValid(" {} ",JSONObject.class);
checkValid("{\"a\":1}",JSONObject.class);
checkValid(" {\"a\":1} ",JSONObject.class);
checkValid("[]",JSONArray.class);
checkValid(" [] ",JSONArray.class);
checkValid("[1,2]",JSONArray.class);
checkValid("\n\n[1,2]\n\n",JSONArray.class);
// Test should fail if default strictMode is true, pass if false
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration();
if (jsonParserConfiguration.isStrictMode()) {
try {
checkValid("1 2", String.class);
assertEquals("Expected to throw exception due to invalid string", true, false);
} catch (JSONException e) { }
} else {
checkValid("1 2", String.class);
}
}
@Test
public void testErrors() {
// Check that stream can detect that a value is found after
// the first one
checkError(" { \"a\":1 } 4 ");
checkError("null \"a\"");
checkError("{} true");
}
private Object checkValid(String testStr, Class<?> aClass) {
Object result = nextValue(testStr);
// Check class of object returned
if( null == aClass ) {
if(JSONObject.NULL.equals(result)) {
// OK
} else {
throw new JSONException("Unexpected class: "+result.getClass().getSimpleName());
}
} else {
if( null == result ) {
throw new JSONException("Unexpected null result");
} else if(!aClass.isAssignableFrom(result.getClass()) ) {
throw new JSONException("Unexpected class: "+result.getClass().getSimpleName());
}
}
return result;
}
private void checkError(String testStr) {
try {
nextValue(testStr);
fail("Error should be triggered: (\""+testStr+"\")");
} catch (JSONException e) {
// OK
}
}
/**
* Verifies that JSONTokener can read a stream that contains a value. After
* the reading is done, check that the stream is left in the correct state
* by reading the characters after. All valid cases should reach end of stream.
* @param testStr
* @return
* @throws Exception
*/
private Object nextValue(String testStr) throws JSONException {
StringReader sr = new StringReader(testStr);
try {
JSONTokener tokener = new JSONTokener(sr);
Object result = tokener.nextValue();
if( result == null ) {
throw new JSONException("Unable to find value token in JSON stream: ("+tokener+"): "+testStr);
}
char c = tokener.nextClean();
if( 0 != c ) {
throw new JSONException("Unexpected character found at end of JSON stream: "+c+ " ("+tokener+"): "+testStr);
}
return result;
} finally {
sr.close();
}
}
/**
* Tests the failure of the skipTo method with a buffered reader. Preferably
* we'd like this not to fail but at this time we don't have a good recovery.
*
* @throws IOException thrown if something unexpected happens.
*/
@Test
public void testSkipToFailureWithBufferedReader() throws IOException {
final byte[] superLongBuffer = new byte[1000001];
// fill our buffer
for(int i=0;i<superLongBuffer.length;i++) {
superLongBuffer[i] = 'A';
}
Reader reader = new BufferedReader(new InputStreamReader(
new ByteArrayInputStream(superLongBuffer)));
try {
final JSONTokener tokener = new JSONTokener(reader);
try {
// this should fail since the internal markAhead buffer is only 1,000,000
// but 'B' doesn't exist in our buffer that is 1,000,001 in size
tokener.skipTo('B');
fail("Expected exception");
} catch (JSONException e) {
assertEquals("Mark invalid", e.getMessage());
} catch (Exception e) {
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
}
} finally {
reader.close();
}
}
/**
* Tests the success of the skipTo method with a String reader.
*
* @throws IOException thrown if something unexpected happens.
*/
@Test
public void testSkipToSuccessWithStringReader() throws IOException {
final StringBuilder superLongBuffer = new StringBuilder(1000001);
// fill our buffer
for(int i=0;i<superLongBuffer.length();i++) {
superLongBuffer.append('A');
}
Reader reader = new StringReader(superLongBuffer.toString());
try {
final JSONTokener tokener = new JSONTokener(reader);
try {
// this should not fail since the internal markAhead is ignored for StringReaders
tokener.skipTo('B');
} catch (Exception e) {
fail("Unknown Exception type " + e.getClass().getCanonicalName()+" with message "+e.getMessage());
}
} finally {
reader.close();
}
}
/**
* Verify that next and back are working properly and tracking the correct positions
* with different new line combinations.
*/
@Test
public void testNextBackComboWithNewLines() {
final String testString = "this is\nA test\r\nWith some different\rNew Lines";
// ^ ^ ^ ^
// index positions 0 8 16 36
final JSONTokener tokener = new JSONTokener(testString);
assertEquals(" at 0 [character 1 line 1]", tokener.toString());
assertEquals('t',tokener.next());
assertEquals(" at 1 [character 2 line 1]", tokener.toString());
tokener.skipTo('\n');
assertEquals("skipTo() improperly modifying indexes"," at 7 [character 8 line 1]", tokener.toString());
assertEquals('\n',tokener.next());
assertEquals(" at 8 [character 0 line 2]", tokener.toString());
assertEquals('A',tokener.next());
assertEquals(" at 9 [character 1 line 2]", tokener.toString());
tokener.back();
assertEquals(" at 8 [character 0 line 2]", tokener.toString());
tokener.skipTo('\r');
assertEquals("skipTo() improperly modifying indexes"," at 14 [character 6 line 2]", tokener.toString());
// verify \r\n combo doesn't increment the line twice
assertEquals('\r', tokener.next());
assertEquals(" at 15 [character 0 line 3]", tokener.toString());
assertEquals('\n', tokener.next());
assertEquals(" at 16 [character 0 line 3]", tokener.toString());
// verify stepping back after reading the \n of an \r\n combo doesn't increment the line incorrectly
tokener.back();
assertEquals(" at 15 [character 6 line 2]", tokener.toString());
assertEquals('\n', tokener.next());
assertEquals(" at 16 [character 0 line 3]", tokener.toString());
assertEquals('W', tokener.next());
assertEquals(" at 17 [character 1 line 3]", tokener.toString());
assertEquals('i', tokener.next());
assertEquals(" at 18 [character 2 line 3]", tokener.toString());
tokener.skipTo('\r');
assertEquals("skipTo() improperly modifying indexes"," at 35 [character 19 line 3]", tokener.toString());
assertEquals('\r', tokener.next());
assertEquals(" at 36 [character 0 line 4]", tokener.toString());
tokener.back();
assertEquals(" at 35 [character 19 line 3]", tokener.toString());
assertEquals('\r', tokener.next());
assertEquals(" at 36 [character 0 line 4]", tokener.toString());
assertEquals('N', tokener.next());
assertEquals(" at 37 [character 1 line 4]", tokener.toString());
// verify we get the same data just walking though, no calls to back
final JSONTokener t2 = new JSONTokener(testString);
for(int i=0; i<7; i++) {
assertTrue(t2.toString().startsWith(" at " + i + " "));
assertEquals(testString.charAt(i), t2.next());
}
assertEquals(" at 7 [character 8 line 1]", t2.toString());
assertEquals(testString.charAt(7), t2.next());
assertEquals(" at 8 [character 0 line 2]", t2.toString());
for(int i=8; i<14; i++) {
assertTrue(t2.toString().startsWith(" at " + i + " "));
assertEquals(testString.charAt(i), t2.next());
}
assertEquals(" at 14 [character 6 line 2]", t2.toString());
assertEquals('\r', t2.next());
assertEquals(" at 15 [character 0 line 3]", t2.toString());
assertEquals('\n', t2.next());
assertEquals(" at 16 [character 0 line 3]", t2.toString());
assertEquals('W', t2.next());
assertEquals(" at 17 [character 1 line 3]", t2.toString());
for(int i=17; i<37; i++) {
assertTrue(t2.toString().startsWith(" at " + i + " "));
assertEquals(testString.charAt(i), t2.next());
}
assertEquals(" at 37 [character 1 line 4]", t2.toString());
for(int i=37; i<testString.length(); i++) {
assertTrue(t2.toString().startsWith(" at " + i + " "));
assertEquals(testString.charAt(i), t2.next());
}
assertEquals(" at "+ testString.length() +" [character 9 line 4]", t2.toString());
// end of the input
assertEquals(0, t2.next());
assertFalse(t2.more());
}
@Test
public void testAutoClose(){
Reader reader = new StringReader("some test string");
try {
JSONTokener tokener = new JSONTokener(reader);
tokener.close();
tokener.next();
} catch (Exception exception){
assertEquals("Stream closed", exception.getMessage());
}
}
@Test
public void testInvalidInput_JSONObject_withoutStrictModel_shouldParseInput() {
String input = "{\"invalidInput\": [],}";
JSONTokener tokener = new JSONTokener(input);
// Test should fail if default strictMode is true, pass if false
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration();
if (jsonParserConfiguration.isStrictMode()) {
try {
Object value = tokener.nextValue();
assertEquals(new JSONObject(input).toString(), value.toString());
assertEquals("Expected to throw exception due to invalid string", true, false);
} catch (JSONException e) { }
} else {
Object value = tokener.nextValue();
assertEquals(new JSONObject(input).toString(), value.toString());
}
}
@Test
public void testInvalidInput_JSONArray_withoutStrictModel_shouldParseInput() {
String input = "[\"invalidInput\",]";
JSONTokener tokener = new JSONTokener(input);
// Test should fail if default strictMode is true, pass if false
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration();
if (jsonParserConfiguration.isStrictMode()) {
try {
Object value = tokener.nextValue();
assertEquals(new JSONArray(input).toString(), value.toString());
assertEquals("Expected to throw exception due to invalid string", true, false);
} catch (JSONException e) { }
} else {
Object value = tokener.nextValue();
assertEquals(new JSONArray(input).toString(), value.toString());
}
}
}

View File

@ -0,0 +1,102 @@
package org.json.junit;
/*
Public Domain.
*/
import java.util.*;
import static org.junit.Assert.*;
import org.json.*;
import org.junit.Test;
/**
* Tests for JSON-Java Property
*/
public class PropertyTest {
/**
* JSONObject from null properties object should
* result in an empty JSONObject.
*/
@Test
public void shouldHandleNullProperties() {
Properties properties = null;
JSONObject jsonObject = Property.toJSONObject(properties);
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
}
/**
* JSONObject from empty properties object should
* result in an empty JSONObject.
*/
@Test
public void shouldHandleEmptyProperties() {
Properties properties = new Properties();
JSONObject jsonObject = Property.toJSONObject(properties);
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
}
/**
* JSONObject from simple properties object.
*/
@Test
public void shouldHandleProperties() {
Properties properties = new Properties();
properties.put("Illinois", "Springfield");
properties.put("Missouri", "Jefferson City");
properties.put("Washington", "Olympia");
properties.put("California", "Sacramento");
properties.put("Indiana", "Indianapolis");
JSONObject jsonObject = Property.toJSONObject(properties);
assertTrue("jsonObject should contain 5 items", jsonObject.length() == 5);
assertTrue("jsonObject should contain Illinois property",
"Springfield".equals(jsonObject.get("Illinois")));
assertTrue("jsonObject should contain Missouri property",
"Jefferson City".equals(jsonObject.get("Missouri")));
assertTrue("jsonObject should contain Washington property",
"Olympia".equals(jsonObject.get("Washington")));
assertTrue("jsonObject should contain California property",
"Sacramento".equals(jsonObject.get("California")));
assertTrue("jsonObject should contain Indiana property",
"Indianapolis".equals(jsonObject.get("Indiana")));
}
/**
* Null JSONObject toProperties() should result in an empty
* Properties object.
*/
@Test
public void shouldHandleNullJSONProperty() {
JSONObject jsonObject= null;
Properties properties = Property.toProperties(jsonObject);
assertTrue("properties should be empty",
properties.size() == 0);
}
/**
* Properties should convert to JSONObject, and back to
* Properties without changing.
*/
@Test
public void shouldHandleJSONProperty() {
Properties properties = new Properties();
properties.put("Illinois", "Springfield");
properties.put("Missouri", "Jefferson City");
properties.put("Washington", "Olympia");
properties.put("California", "Sacramento");
properties.put("Indiana", "Indianapolis");
JSONObject jsonObject = Property.toJSONObject(properties);
Properties jsonProperties = Property.toProperties(jsonObject);
assertTrue("property objects should match",
properties.equals(jsonProperties));
}
}

View File

@ -0,0 +1,60 @@
package org.json.junit;
import static org.junit.Assert.assertEquals;
import org.json.StringBuilderWriter;
import org.junit.Before;
import org.junit.Test;
public class StringBuilderWriterTest {
private StringBuilderWriter writer;
@Before
public void setUp() {
writer = new StringBuilderWriter();
}
@Test
public void testWriteChar() {
writer.write('a');
assertEquals("a", writer.toString());
}
@Test
public void testWriteCharArray() {
char[] chars = {'a', 'b', 'c'};
writer.write(chars, 0, 3);
assertEquals("abc", writer.toString());
}
@Test
public void testWriteString() {
writer.write("hello");
assertEquals("hello", writer.toString());
}
@Test
public void testWriteStringWithOffsetAndLength() {
writer.write("hello world", 6, 5);
assertEquals("world", writer.toString());
}
@Test
public void testAppendCharSequence() {
writer.append("hello");
assertEquals("hello", writer.toString());
}
@Test
public void testAppendCharSequenceWithStartAndEnd() {
CharSequence csq = "hello world";
writer.append(csq, 6, 11);
assertEquals("world", writer.toString());
}
@Test
public void testAppendChar() {
writer.append('a');
assertEquals("a", writer.toString());
}
}

View File

@ -0,0 +1,201 @@
package org.json.junit;
/*
Public Domain.
*/
import static org.junit.Assert.*;
import java.util.*;
import org.json.*;
/**
* These are helpful utility methods that perform basic comparisons
* between various objects. In most cases, the comparisons are not
* order-dependent, or else the order is known.
*/
public class Util {
/**
* Compares two JSONArrays for equality.
* The arrays need not be in the same order.
* @param jsonArray created by the code to be tested
* @param expectedJsonArray created specifically for comparing
*/
public static void compareActualVsExpectedJsonArrays(JSONArray jsonArray,
JSONArray expectedJsonArray) {
assertTrue("jsonArray lengths should be equal",
jsonArray.length() == expectedJsonArray.length());
for (int i = 0; i < jsonArray.length(); ++i) {
Object value = jsonArray.get(i);
Object expectedValue = expectedJsonArray.get(i);
compareActualVsExpectedObjects(value, expectedValue);
}
}
/**
* Compares two JSONObjects for equality. The objects need not be
* in the same order
* @param jsonObject created by the code to be tested
* @param expectedJsonObject created specifically for comparing
*/
public static void compareActualVsExpectedJsonObjects(
JSONObject jsonObject, JSONObject expectedJsonObject) {
assertTrue("jsonObjects should have the same length",
jsonObject.length() == expectedJsonObject.length());
Iterator<String> keys = jsonObject.keys();
while (keys.hasNext()) {
String key = keys.next();
Object value = jsonObject.get(key);
Object expectedValue = expectedJsonObject.get(key);
compareActualVsExpectedObjects(value, expectedValue);
}
}
/**
* Compare two objects for equality. Might be JSONArray, JSONObject,
* or something else.
* @param value created by the code to be tested
* @param expectedValue created specifically for comparing
*/
private static void compareActualVsExpectedObjects(Object value,
Object expectedValue) {
if (value instanceof JSONObject && expectedValue instanceof JSONObject) {
// Compare JSONObjects
JSONObject jsonObject = (JSONObject)value;
JSONObject expectedJsonObject = (JSONObject)expectedValue;
compareActualVsExpectedJsonObjects(
jsonObject, expectedJsonObject);
} else if (value instanceof JSONArray && expectedValue instanceof JSONArray) {
// Compare JSONArrays
JSONArray jsonArray = (JSONArray)value;
JSONArray expectedJsonArray = (JSONArray)expectedValue;
compareActualVsExpectedJsonArrays(
jsonArray, expectedJsonArray);
} else {
/**
* Compare all other types using toString(). First, the types must
* also be equal, unless both are Number type. Certain helper
* classes (e.g. XML) may create Long instead of Integer for small
* int values.
*/
if (!(value instanceof Number && expectedValue instanceof Number)) {
// Non-Number and non-matching types
assertEquals("object types should be equal ",
expectedValue.getClass().toString(),
value.getClass().toString()
);
}
/**
* Same types or both Numbers, compare by toString()
*/
assertEquals("values should be equal",
expectedValue.toString(),
value.toString()
);
}
}
/**
* Asserts that all JSONObject maps are the same as the default ctor
* @param jsonObjects list of objects to be tested
*/
public static void checkJSONObjectsMaps(List<JSONObject> jsonObjects) {
if (jsonObjects == null || jsonObjects.size() == 0) {
return;
}
Class<? extends Map> mapType = new JSONObject().getMapType();
for (JSONObject jsonObject : jsonObjects) {
if (jsonObject != null) {
assertTrue(mapType == jsonObject.getMapType());
checkJSONObjectMaps(jsonObject, mapType);
}
}
}
/**
* Asserts that all JSONObject maps are the same as the default ctor
* @param jsonObject the object to be tested
*/
public static void checkJSONObjectMaps(JSONObject jsonObject) {
if (jsonObject != null) {
checkJSONObjectMaps(jsonObject, jsonObject.getMapType());
}
}
/**
* Asserts that all JSONObject maps are the same as mapType
* @param jsonObject object to be tested
* @param mapType mapType to test against
*/
public static void checkJSONObjectMaps(JSONObject jsonObject, Class<? extends Map> mapType) {
if (mapType == null) {
mapType = new JSONObject().getMapType();
}
Set<String> keys = jsonObject.keySet();
for (String key : keys) {
Object val = jsonObject.get(key);
if (val instanceof JSONObject) {
JSONObject jsonObjectVal = (JSONObject) val;
assertTrue(mapType == ((JSONObject) val).getMapType());
checkJSONObjectMaps(jsonObjectVal, mapType);
} else if (val instanceof JSONArray) {
JSONArray jsonArrayVal = (JSONArray)val;
checkJSONArrayMaps(jsonArrayVal, mapType);
}
}
}
/**
* Asserts that all JSONObject maps in the JSONArray object match the default map
* @param jsonArrays list of JSONArray objects to be tested
*/
public static void checkJSONArraysMaps(List<JSONArray> jsonArrays) {
if (jsonArrays == null || jsonArrays.size() == 0) {
return;
}
Class<? extends Map> mapType = new JSONObject().getMapType();
for (JSONArray jsonArray : jsonArrays) {
if (jsonArray != null) {
checkJSONArrayMaps(jsonArray, mapType);
}
}
}
/**
* Asserts that all JSONObject maps in the JSONArray object match mapType
* @param jsonArray object to be tested
* @param mapType map type to be tested against
*/
public static void checkJSONArrayMaps(JSONArray jsonArray, Class<? extends Map> mapType) {
if (jsonArray == null) {
return;
}
if (mapType == null) {
mapType = new JSONObject().getMapType();
}
Iterator<Object> it = jsonArray.iterator();
while (it.hasNext()) {
Object val = it.next();
if (val instanceof JSONObject) {
JSONObject jsonObjectVal = (JSONObject)val;
checkJSONObjectMaps(jsonObjectVal, mapType);
} else if (val instanceof JSONArray) {
JSONArray jsonArrayVal = (JSONArray)val;
checkJSONArrayMaps(jsonArrayVal, mapType);
}
}
}
/**
* Asserts that all JSONObject maps nested in the JSONArray match
* the default mapType
* @param jsonArray the object to be tested
*/
public static void checkJSONArrayMaps(JSONArray jsonArray) {
if (jsonArray != null) {
checkJSONArrayMaps(jsonArray, null);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
package org.json.junit;
import org.json.XMLTokener;
import org.junit.Test;
import java.io.StringReader;
import static org.junit.Assert.*;
/**
* Tests for JSON-Java XMLTokener.java
*/
public class XMLTokenerTest {
/**
* Tests that nextCDATA() correctly extracts content from within a CDATA section.
*/
@Test
public void testNextCDATA() {
String xml = "This is <![CDATA[ some <CDATA> content ]]> after";
XMLTokener tokener = new XMLTokener(new StringReader(xml));
tokener.skipPast("<![CDATA[");
String cdata = tokener.nextCDATA();
assertEquals(" some <CDATA> content ", cdata);
}
/**
* Tests that nextContent() returns plain text content before a tag.
*/
@Test
public void testNextContentWithText() {
String xml = "Some content<nextTag>";
XMLTokener tokener = new XMLTokener(xml);
Object content = tokener.nextContent();
assertEquals("Some content", content);
}
/**
* Tests that nextContent() returns '<' character when starting with a tag.
*/
@Test
public void testNextContentWithTag() {
String xml = "<tag>";
XMLTokener tokener = new XMLTokener(xml);
Object content = tokener.nextContent();
assertEquals('<', content);
}
/**
* Tests that nextEntity() resolves a known entity like &amp; correctly.
*/
@Test
public void testNextEntityKnown() {
XMLTokener tokener = new XMLTokener("amp;");
Object result = tokener.nextEntity('&');
assertEquals("&", result);
}
/**
* Tests that nextEntity() preserves unknown entities by returning them unchanged.
*/
@Test
public void testNextEntityUnknown() {
XMLTokener tokener = new XMLTokener("unknown;");
tokener.next(); // skip 'u'
Object result = tokener.nextEntity('&');
assertEquals("&nknown;", result); // malformed start to simulate unknown
}
/**
* Tests skipPast() to ensure the cursor moves past the specified string.
*/
@Test
public void testSkipPast() {
String xml = "Ignore this... endHere more text";
XMLTokener tokener = new XMLTokener(xml);
tokener.skipPast("endHere");
assertEquals(' ', tokener.next()); // should be the space after "endHere"
}
}

View File

@ -0,0 +1,13 @@
package org.json.junit.data;
/**
* test class for verifying write errors.
* @author John Aylward
*
*/
public class BrokenToString {
@Override
public String toString() {
throw new IllegalStateException("Something went horribly wrong!");
}
}

View File

@ -0,0 +1,66 @@
/**
*
*/
package org.json.junit.data;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
/**
* Object for testing the exception handling in {@link org.json.JSONObject#populateMap}.
*
* @author John Aylward
*/
public class ExceptionalBean {
/**
* @return a closeable.
*/
public Closeable getCloseable() {
// anonymous inner class did not work...
return new MyCloseable();
}
/**
* @return Nothing really. Just can't be void.
* @throws IllegalAccessException
* always thrown
*/
public int getIllegalAccessException() throws IllegalAccessException {
throw new IllegalAccessException("Yup, it's illegal");
}
/**
* @return Nothing really. Just can't be void.
* @throws IllegalArgumentException
* always thrown
*/
public int getIllegalArgumentException() throws IllegalArgumentException {
throw new IllegalArgumentException("Yup, it's illegal");
}
/**
* @return Nothing really. Just can't be void.
* @throws InvocationTargetException
* always thrown
*/
public int getInvocationTargetException() throws InvocationTargetException {
throw new InvocationTargetException(new Exception("Yup, it's illegal"));
}
/** My closeable class. */
public static final class MyCloseable implements Closeable {
/**
* @return a string
*/
public String getString() {
return "Yup, it's closeable";
}
@Override
public void close() throws IOException {
throw new IOException("Closing is too hard!");
}
}
}

View File

@ -0,0 +1,180 @@
package org.json.junit.data;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
/**
* basic fraction class, no frills.
* @author John Aylward
*
*/
public class Fraction extends Number implements Comparable<Fraction> {
/**
* serial id.
*/
private static final long serialVersionUID = 1L;
/**
* value as a big decimal.
*/
private final BigDecimal bigDecimal;
/**
* value of the denominator.
*/
private final BigInteger denominator;
/**
* value of the numerator.
*/
private final BigInteger numerator;
/**
* @param numerator
* numerator
* @param denominator
* denominator
*/
public Fraction(final BigInteger numerator, final BigInteger denominator) {
super();
if (numerator == null || denominator == null) {
throw new IllegalArgumentException("All values must be non-null");
}
if (denominator.compareTo(BigInteger.ZERO)==0) {
throw new IllegalArgumentException("Divide by zero");
}
final BigInteger n;
final BigInteger d;
// normalize fraction
if (denominator.signum()<0) {
n = numerator.negate();
d = denominator.negate();
} else {
n = numerator;
d = denominator;
}
this.numerator = n;
this.denominator = d;
if (n.compareTo(BigInteger.ZERO)==0) {
this.bigDecimal = BigDecimal.ZERO;
} else if (n.compareTo(d)==0) {// i.e. 4/4, 10/10
this.bigDecimal = BigDecimal.ONE;
} else {
this.bigDecimal = new BigDecimal(this.numerator).divide(new BigDecimal(this.denominator),
RoundingMode.HALF_EVEN);
}
}
/**
* @param numerator
* numerator
* @param denominator
* denominator
*/
public Fraction(final long numerator, final long denominator) {
this(BigInteger.valueOf(numerator),BigInteger.valueOf(denominator));
}
/**
* @return the decimal
*/
public BigDecimal bigDecimalValue() {
return this.bigDecimal;
}
@Override
public int compareTo(final Fraction o) {
// .equals call this, so no .equals compare allowed
// if they are the same reference, just return equals
if (this == o) {
return 0;
}
// if my denominators are already equal, just compare the numerators
if (this.denominator.compareTo(o.denominator)==0) {
return this.numerator.compareTo(o.numerator);
}
// get numerators of common denominators
// a x ay xb
// --- --- = ---- ----
// b y by yb
final BigInteger thisN = this.numerator.multiply(o.denominator);
final BigInteger otherN = o.numerator.multiply(this.denominator);
return thisN.compareTo(otherN);
}
@Override
public double doubleValue() {
return this.bigDecimal.doubleValue();
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final Fraction other = (Fraction) obj;
return this.compareTo(other) == 0;
}
@Override
public float floatValue() {
return this.bigDecimal.floatValue();
}
/**
* @return the denominator
*/
public BigInteger getDenominator() {
return this.denominator;
}
/**
* @return the numerator
*/
public BigInteger getNumerator() {
return this.numerator;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (this.bigDecimal == null ? 0 : this.bigDecimal.hashCode());
return result;
}
@Override
public int intValue() {
return this.bigDecimal.intValue();
}
@Override
public long longValue() {
return this.bigDecimal.longValue();
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.numerator + "/" + this.denominator;
}
}

View File

@ -0,0 +1,79 @@
package org.json.junit.data;
import java.io.StringReader;
/**
*
* @author John Aylward
*
* @param <T>
* generic number value
*/
public class GenericBean<T extends Number> implements MyBean {
/**
* @param genericValue
* value to initiate with
*/
public GenericBean(T genericValue) {
super();
this.genericValue = genericValue;
}
/** */
protected T genericValue;
/** to be used by the calling test to see how often the getter is called */
public int genericGetCounter;
/** to be used by the calling test to see how often the setter is called */
public int genericSetCounter;
/** @return the genericValue */
public T getGenericValue() {
this.genericGetCounter++;
return this.genericValue;
}
/**
* @param genericValue
* generic value to set
*/
public void setGenericValue(T genericValue) {
this.genericSetCounter++;
this.genericValue = genericValue;
}
@Override
public Integer getIntKey() {
return Integer.valueOf(42);
}
@Override
public Double getDoubleKey() {
return Double.valueOf(4.2);
}
@Override
public String getStringKey() {
return "MyString Key";
}
@Override
public String getEscapeStringKey() {
return "\"My String with \"s";
}
@Override
public Boolean isTrueKey() {
return Boolean.TRUE;
}
@Override
public Boolean isFalseKey() {
return Boolean.FALSE;
}
@Override
public StringReader getStringReaderKey() {
return new StringReader("Some String Value in a reader");
}
}

View File

@ -0,0 +1,69 @@
/**
*
*/
package org.json.junit.data;
/**
* @author john
*
*/
public class GenericBeanInt extends GenericBean<Integer> {
/** */
final char a = 'A';
/** @return the a */
public char getA() {
return this.a;
}
/**
* Should not be beanable
*
* @return false
*/
public boolean getable() {
return false;
}
/**
* Should not be beanable
*
* @return false
*/
public boolean get() {
return false;
}
/**
* Should not be beanable
*
* @return false
*/
public boolean is() {
return false;
}
/**
* Should be beanable
*
* @return false
*/
public boolean isB() {
return this.genericValue.equals((Integer.valueOf(this.a+1)));
}
/**
* @param genericValue
* the value to initiate with.
*/
public GenericBeanInt(Integer genericValue) {
super(genericValue);
}
/** override to generate a bridge method */
@Override
public Integer getGenericValue() {
return super.getGenericValue();
}
}

View File

@ -0,0 +1,16 @@
package org.json.junit.data;
import java.io.*;
/**
* Used in testing when Bean behavior is needed
*/
public interface MyBean {
public Integer getIntKey();
public Double getDoubleKey();
public String getStringKey();
public String getEscapeStringKey();
public Boolean isTrueKey();
public Boolean isFalseKey();
public StringReader getStringReaderKey();
}

View File

@ -0,0 +1,20 @@
package org.json.junit.data;
import org.json.JSONPropertyName;
/**
* Test bean for the {@link JSONPropertyName} annotation.
*/
public class MyBeanCustomName implements MyBeanCustomNameInterface {
public int getSomeInt() { return 42; }
@JSONPropertyName("")
public long getSomeLong() { return 42L; }
@JSONPropertyName("myStringField")
public String getSomeString() { return "someStringValue"; }
@JSONPropertyName("Some Weird NAme that Normally Wouldn't be possible!")
public double getMyDouble() { return 0.0d; }
@Override
public float getSomeFloat() { return 2.0f; }
@Override
public int getIgnoredInt() { return 40; }
}

View File

@ -0,0 +1,11 @@
package org.json.junit.data;
import org.json.JSONPropertyIgnore;
import org.json.JSONPropertyName;
public interface MyBeanCustomNameInterface {
@JSONPropertyName("InterfaceField")
float getSomeFloat();
@JSONPropertyIgnore
int getIgnoredInt();
}

View File

@ -0,0 +1,32 @@
/**
*
*/
package org.json.junit.data;
import org.json.JSONPropertyIgnore;
import org.json.JSONPropertyName;
/**
* Test bean to verify that the {@link org.json.JSONPropertyName} annotation
* is inherited.
*/
public class MyBeanCustomNameSubClass extends MyBeanCustomName {
@Override
@JSONPropertyName("forcedInt")
public int getIgnoredInt() { return 42*42; }
@Override
@JSONPropertyName("newIntFieldName")
public int getSomeInt() { return 43; }
@Override
public String getSomeString() { return "subClassString"; }
@Override
@JSONPropertyName("AMoreNormalName")
public double getMyDouble() { return 1.0d; }
@Override
public float getSomeFloat() { return 3.0f; }
@JSONPropertyIgnore
@JSONPropertyName("ShouldBeIgnored")
public boolean getShouldNotBeJSON() { return true; }
@JSONPropertyName("Getable")
public boolean getable() { return true; }
}

View File

@ -0,0 +1,11 @@
package org.json.junit.data;
import java.math.*;
/**
* Used in testing when a Bean containing big numbers is needed
*/
public interface MyBigNumberBean {
public BigInteger getBigInteger();
public BigDecimal getBigDecimal();
}

View File

@ -0,0 +1,10 @@
package org.json.junit.data;
/**
* An enum with no methods or data
*/
public enum MyEnum {
VAL1,
VAL2,
VAL3;
}

View File

@ -0,0 +1,22 @@
package org.json.junit.data;
/**
* this is simply a class that contains some enum instances
*/
public class MyEnumClass {
private MyEnum myEnum;
private MyEnumField myEnumField;
public MyEnum getMyEnum() {
return this.myEnum;
}
public void setMyEnum(MyEnum myEnum) {
this.myEnum = myEnum;
}
public MyEnumField getMyEnumField() {
return this.myEnumField;
}
public void setMyEnumField(MyEnumField myEnumField) {
this.myEnumField = myEnumField;
}
}

View File

@ -0,0 +1,28 @@
package org.json.junit.data;
/**
* An enum that contains getters and some internal fields
*/
@SuppressWarnings("boxing")
public enum MyEnumField {
VAL1(1, "val 1"),
VAL2(2, "val 2"),
VAL3(3, "val 3");
private String value;
private Integer intVal;
private MyEnumField(Integer intVal, String value) {
this.value = value;
this.intVal = intVal;
}
public String getValue() {
return this.value;
}
public Integer getIntVal() {
return this.intVal;
}
@Override
public String toString(){
return this.value;
}
}

View File

@ -0,0 +1,14 @@
package org.json.junit.data;
import org.json.*;
/**
* Used in testing when a JSONString is needed
*/
public class MyJsonString implements JSONString {
@Override
public String toJSONString() {
return "my string";
}
}

View File

@ -0,0 +1,12 @@
package org.json.junit.data;
public class MyLocaleBean {
private final String id = "beanId";
private final String i = "beanI";
public String getId() {
return this.id;
}
public String getI() {
return this.i;
}
}

View File

@ -0,0 +1,97 @@
package org.json.junit.data;
import java.math.BigDecimal;
/**
* Number override for testing. Number overrides should always override
* toString, hashCode, and Equals.
*
* @see <a
* href="https://docs.oracle.com/javase/tutorial/java/data/numberclasses.html">The
* Numbers Classes</a>
* @see <a
* href="https://docs.oracle.com/javase/tutorial/java/data/numberformat.html">Formatting
* Numeric Print Output</a>
*
* @author John Aylward
*/
public class MyNumber extends Number {
private Number number = BigDecimal.valueOf(42);
/**
*/
private static final long serialVersionUID = 1L;
/**
* @return number!
*/
public Number getNumber() {
return this.number;
}
@Override
public int intValue() {
return getNumber().intValue();
}
@Override
public long longValue() {
return getNumber().longValue();
}
@Override
public float floatValue() {
return getNumber().floatValue();
}
@Override
public double doubleValue() {
return getNumber().doubleValue();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*
* Number overrides should in general always override the toString method.
*/
@Override
public String toString() {
return getNumber().toString();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.number == null) ? 0 : this.number.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MyNumber)) {
return false;
}
MyNumber other = (MyNumber) obj;
if (this.number == null) {
if (other.number != null) {
return false;
}
} else if (!this.number.equals(other.number)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,13 @@
package org.json.junit.data;
/**
* Class that holds our MyNumber override as a property.
* @author John Aylward
*/
public class MyNumberContainer {
private MyNumber myNumber = new MyNumber();
/**
* @return a MyNumber.
*/
public Number getMyNumber() {return this.myNumber;}
}

View File

@ -0,0 +1,10 @@
package org.json.junit.data;
/**
* Need a class with some public data members for testing
*/
@SuppressWarnings("boxing")
public class MyPublicClass {
public Integer publicInt = 42;
public String publicString = "abc";
}

View File

@ -0,0 +1,23 @@
package org.json.junit.data;
/**
* test class for verifying if recursively defined bean can be correctly identified
* @author Zetmas
*
*/
public class RecursiveBean {
private String name;
private Object reference;
private Object reference2;
public String getName() { return name; }
public Object getRef() {return reference;}
public Object getRef2() {return reference2;}
public void setRef(Object refObj) {reference = refObj;}
public void setRef2(Object refObj) {reference2 = refObj;}
public RecursiveBean(String name) {
this.name = name;
reference = null;
reference2 = null;
}
}

View File

@ -0,0 +1,33 @@
package org.json.junit.data;
/** test class for verifying if recursively defined bean can be correctly identified */
public class RecursiveBeanEquals {
private final String name;
private Object reference;
public RecursiveBeanEquals(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Object getRef() {
return reference;
}
public void setRef(Object refObj) {
reference = refObj;
}
@Override
public boolean equals(Object other) {
return other instanceof RecursiveBeanEquals && name.equals(((RecursiveBeanEquals) other).name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}

View File

@ -0,0 +1,91 @@
package org.json.junit.data;
/**
* Sample singleton for use with bean testing.
*
* @author John Aylward
*
*/
public final class Singleton {
/** */
private int someInt;
/** */
private String someString;
/** single instance. */
private static final Singleton INSTANCE = new Singleton();
/** @return the singleton instance. */
public static final Singleton getInstance() {
return INSTANCE;
}
/** */
private Singleton() {
if (INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
return INSTANCE;
}
/** @return someInt */
public int getSomeInt() {
return this.someInt;
}
/**
* sets someInt.
*
* @param someInt
* the someInt to set
*/
public void setSomeInt(int someInt) {
this.someInt = someInt;
}
/** @return someString */
public String getSomeString() {
return this.someString;
}
/**
* sets someString.
*
* @param someString
* the someString to set
*/
public void setSomeString(String someString) {
this.someString = someString;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.someInt;
result = prime * result + ((this.someString == null) ? 0 : this.someString.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Singleton other = (Singleton) obj;
if (this.someInt != other.someInt)
return false;
if (this.someString == null) {
if (other.someString != null)
return false;
} else if (!this.someString.equals(other.someString))
return false;
return true;
}
}

View File

@ -0,0 +1,62 @@
package org.json.junit.data;
/**
* Sample singleton done as an Enum for use with bean testing.
*
* @author John Aylward
*
*/
public enum SingletonEnum {
/**
* the singleton instance.
*/
INSTANCE;
/** */
private int someInt;
/** */
private String someString;
/** single instance. */
/**
* @return the singleton instance. In a real application, I'd hope no one did
* this to an enum singleton.
*/
public static final SingletonEnum getInstance() {
return INSTANCE;
}
/** */
private SingletonEnum() {
}
/** @return someInt */
public int getSomeInt() {
return this.someInt;
}
/**
* sets someInt.
*
* @param someInt
* the someInt to set
*/
public void setSomeInt(int someInt) {
this.someInt = someInt;
}
/** @return someString */
public String getSomeString() {
return this.someString;
}
/**
* sets someString.
*
* @param someString
* the someString to set
*/
public void setSomeString(String someString) {
this.someString = someString;
}
}

Some files were not shown because too many files have changed in this diff Show More