From 4c985496415c6f6dca57488b93a5856aa4b20e1b Mon Sep 17 00:00:00 2001 From: miktim Date: Sat, 15 Jun 2024 10:59:58 +0300 Subject: [PATCH] 2.0.2 --- README | 28 ++++++++++------- dist/{json-2.0.1.jar => json-2.0.2.jar} | Bin 18232 -> 18229 bytes src/org/miktim/json/JSONObject.java | 3 +- test/json/JSONObjectTest.java | 38 +++++++++++++++++++++++- 4 files changed, 56 insertions(+), 13 deletions(-) rename dist/{json-2.0.1.jar => json-2.0.2.jar} (72%) diff --git a/README b/README index 3c6b7ef..cadd350 100644 --- a/README +++ b/README @@ -1,8 +1,9 @@ # Java 7+/Android JSON parser/generator, MIT (c) 2020-2022 miktim@mail.ru Release notes: - - Java SE 7+/Android compatible; - - in accordance with RFC 8259: https://datatracker.ietf.org/doc/rfc8259/?include_text=1 ; + - Java SE 7+/Android RFC 8259 compliant package + (see: https://datatracker.ietf.org/doc/rfc8259/?include_text=1 ); + - no external dependencies; - JavaScript JSON - like interface. package org.miktim.json @@ -23,13 +24,14 @@ Overview: - JSON text is generated as one line. Put, set, get notes: + - RFC 8259 does not recommend using Java BigDecimal and BigInteger as JSON member values; - put, set methods cast Java primitives to the corresponding objects. Java objects and arrays are stored "as is" (as reference). For example: int -> Integer, int[] -> int[], String[] -> String[] - after JSON text parsing or normalization, they are stored as: BigDecimal, Object[] {BigDecimal,...}, Object[] {String,...}; - getters eliminate these differences by casting types to JSON-declared. - + Constructors: JSON(Object... members) throws IndexOutOfBoundsException; // name,value pairs JSON(String jsonText) throws IOException, ParseException; @@ -55,8 +57,8 @@ Overview: Boolean getBoolean(String memberName, int... indices) throws ClassCastException; Object[] getArray(String memberName, int... indices) throws ClassCastException; - T cast(String memberName, T sample, int... indices); // cast value or array by sample - T cast(String memberName, Class cls, int... indices); // cast value or array by Class + T cast(String memberName, T sample, int... indices); // casting value or array by sample + T cast(String memberName, Class cls, int... indices); // casting value or array by Class JSON normalize() throws IOException, ParseException; // not required to generate JSON text @@ -66,7 +68,7 @@ Overview: Class JSONAdapter; - Casting by sample or Class of a JSON variable or array to a Java primitive or array. + Casting a JSON variable or array to a Java primitive or array using a sample or class. - sample must be initialized; - casting null to a Java primitive returns corresponding initial value; - casting null to an array returns an empty array; @@ -80,7 +82,7 @@ Overview: Abstract class JSONObject; - Unloads/loads the accessible fields of the Java object to/from the JSON object. + Unloads/loads the accessible fields (properties) of the Java object to/from the JSON object. - Java final, interface, abstract, transient, strict fields are ignored; - see JSON set/get/cast rules for Java object fields in the notes for JSON object and JSONAdapter. @@ -91,13 +93,17 @@ Overview: Methods: Object toJSON() throws IllegalArgumentException, IllegalAccessException; + // returns JSON object + // convertible object parameters must be initialized protected Object replacer(String name, Object value); // first call with object class name and empty JSON object as value - JSONObject fromJSON(Object obj) + Object fromJSON(Object jsonObj) throws IllegalArgumentException, IllegalAccessException; + // returns this object + // convertible object parameters must be initialized protected Object reviver(String name, Object value); // first call with object class name and obj argument as value - static boolean isClassName(String name); + static final boolean isClassName(String name); protected T castMember(String memberName, JSON jsonObj, T sample); // returns the sample if JSON member does not exists protected void setIgnored(String[] fldNames); // set ignored field names @@ -108,5 +114,5 @@ Usage see: ./test/json/JSONAdapterTest.java ./test/json/JSONObjectTest.java -RFC compatibility parsing test result: - https://miktim.github.io/JSONTestSuite/results/parsing.html \ No newline at end of file +The result of the JSON parsing test for compliance with RFC 8259: + https://miktim.github.io/JSONTestSuite/results/parsing.html diff --git a/dist/json-2.0.1.jar b/dist/json-2.0.2.jar similarity index 72% rename from dist/json-2.0.1.jar rename to dist/json-2.0.2.jar index 4ba53eecd7b58f36ce746b4b7556307822d43e93..e3fa03ce79e4fdcf99f98fa834140fd2722b82cf 100644 GIT binary patch delta 3576 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 UAeA_Iz_9^lC;$L$&6C-G0MVp9wg3PC delta 3620 zcmZvfcR1VIAIB558q|tS&6a31L5-Rj-p7(j3&*yy3`R9FVlYsR}z%ypZQ?wuefDr(= zu2*RF;EW{B{^);?$@oD9005Xc8sMX0jIh#@F)-1C8Ecss=pihvE*k3@54{4l!`WzO zLqxW!t|B=2pK0z9NC{>aq~-(2&v;|81{SaDf++b_#e6LhO6#m%nIC@PqVS$>=HFcm!m^`eI!$dL-GDthG0Wu-EP{uD^$uoO+&#_m>yrKXA zKRyr0Q=QIi#Y&~Cw**pvKcXn1(UZttc>Ery2oQ?ieQKBtywh;&b?Bhit;?)`#`cD8B84sEtHE+YtoM_4Ld3x$1 zLJsq}g3|!N6MUGG6wYQ9XW7lAZc4`IJi#_IvSn~H0)sp5k|es!2Dq80BjZjFpBvh# zmJvrLNeD2CLPaB>g%AghM>UX|lBQwq6cPNe*;v$bgHPWJX7H@{LNI&K{+;Tz8Plvx zCBNl?7oVm=Ts02o3qk;jvorkhK87SejnuiCuJ^$s*&}9man<>ki|5oFhrNNY(%%d^ z5Z6byPRc9`IjY=K3DwtNuA3J zbXa%yWfe-m+{e1ZH=85YtL&g<1t)@;X7ASo7r5WpY~=l_PfFh1z8IE2e~Zp-VL_&x zA#lsWZ0fZuGmcMzU3}7VY;wXiI>jEm7!#6Dte>cr^w4YM02wA>3~D78=5DeUsqN3* zRBkYikVj4Dy{wgg>mn`X0lNAst?iqMeAw_xV#a(dswdW;mr`}`{JcZ&H2gt-)(uKd z*0*hZM>)maxg`fJ1E{K-vDQJkL$UlM{-TF?56RfLk~8QsMD ze74&+y$O@@<{lAmHuY^2M!Zad%)0zP-Dl@p%&${DyJqUX!a8|nOlA<}D$K>g7w23J zY0l3jnZQ&v2W;)je-SI@vLSu6@mbLhF>6$C+GAzp<~AvQzxYx@eeezgLa;{i-Y^k^ zewnpjE02RGF8-RmpuW$rhWYRZcA7v5_YIEaSBh!ZX@>>Rbq>Zp&@bHBCSQ3dY(5J& zl|p6KrcHAqH{)3Jn&g1QD2V>Oj<_y==os>}eC8pFwZMIf6=bIbXOZA#*Q&FN{g)xoYPGI;P%^SwP8UdT^F-%zv`V{@4{$> zrHqN%as53x-i8Ujc(Z&dCC1Lam&CIlGHOS=*c5*^nj71DkoayQcWoKUJ7)Z67h_ZD zysI=W%;fv)7%>}#*OTZw6t-7ve3r^fq*@yNZgG^UpI`Eb`JDijvn1Pqb$})=;*^T# zY`Sz<(ZYCr?;ZcC_7G6o_tqX;N=p)}w>?)ZM2&!E4)PC;P4=H6d7+Fpp5_p&?9h2o zB~Ox~kkj7k3Y+2W#1NHIqD{A#?BGGRx+l(ms(Z`7ChqGeN(fy7#-}Msb2j;I*6N4% zDBFxows8soH%f6$TsvUW7@upl>@Cx%^^C2)uc z|2TVzWyeS21=y|Hi~wUb4_ikphg%!im4#C8lcKo#cA465uJ@QR6)Zy+vc zysl)L0;e&;SZKG5^COA`3yTh~y9o=z7xHSF)OTDu+U5;hB=%L&>=Cd{>&7Y1oNNiS zoHiyd*7wonaZn2;;jl4KM8qv#kjU`|EL_a(9GT_IWP5Pb?JyE=DrmVI=RFm@n+Bfg zu|c!aG;H%K`Vv$($5XxzF!=vU-5{KHaXiNyOxaJsKBEcte;A1B;*y1 z27WXlwo3C98RbJwEA6Ci>~S?*P2|5>I*eurwEG=fTvOF%Z*G2>{!`v{vdtBeVO$ej zCcSO{2G2;Upn4EGIVv<7_afo;Eo&E0j?-d-V|mM|tygY&4agh|ky;1i8ihS{gIbB$ z3z(k;&(O?JvNIU5i`DZ4nKHR1~gSz={ zT}V!4^JUOYaL)N)7 z77VdgTg|;ClqpY^f(}AU4*-LGsy$7hHwvKi-RPQ-zTD5yxAAiHT-WFokU~OH^Xro~?~7g96)xs{3S1)TPMx;o}e6=le>-(_aGTUmw!6 zFi0^TOn0P!(~@$vLt&>6HVZs>Nx&K9KIaa#ie2mEf~V56IHc1=9#g5D3Wbokafy{| z))Odvd1gp%taH{4lUg_IUY@w3_}p~XfP-xCabfX0bE~5yUq@x(nEUluzs+ z)ZJ0!C_u}M6s6(Z1#;O-rli*ue6%@^4zcra^f?d8L*nc8Tyfj`>mM$2&`X~qsL-rxssyU zN#ylPba*m`vrblGLiLIS{^^U97h#P?+fUiI?vfVdnjg;jKsy#PNCmtBeSa*Rs}L;< zs2)(?L1~Z*Adsv@3R6vS@S@in*WqGwh_0(yuWg{p)ra4=?}k>~n0+Vxh9m|KVl^rUyZmB5JH-}+w zJ2;9YON_5t1J$Equ2$)XR(>oSO1?4>SE&$l@utM0Wh?o18bcAA2jAoRc718rG~3Wv zLxwJMg@B-SCxufvMP4T6%gZP~lil;`9UH^)a)h_*DA9fs{uBGt9whn9Y%QGE$L@!@g*nh7(#*Ym9&yVS6#0J>V zlEDjU^Z&5Bs@nWO8@!FSu*mTe@}p|W+@s3ZIRStpxBK%ejJONLM=*2a%e48Z;6FU^ zPYeJkj6gFVfr2SI%s=w8>G0Fc2;hBm&*BYrIDcqPM_PaoRePiZ7CH91d3_qWPmcO% zrvU)O|B(+VOa(V|IH{mBJ@&VnBXI9u-~~}CsG-X#e4KIn()WtzN8r}KKoPvRt{j!2 zn(-rM=U)sDzD-w-TJSSutg8P1=3$kj7L-N&*xA$RDwTh+pUsV$}l05;G3@9p8> nN3amSUyp+d{(K}HJ?cdMaoR3Q)N9UEV#W(!Wuw>AI-dOxaS=3Z diff --git a/src/org/miktim/json/JSONObject.java b/src/org/miktim/json/JSONObject.java index d7c7d47..3646de3 100644 --- a/src/org/miktim/json/JSONObject.java +++ b/src/org/miktim/json/JSONObject.java @@ -28,9 +28,10 @@ protected Object replacer(String fldName, Object value) { return value; } - public void fromJSON(Object obj) + public Object fromJSON(Object obj) throws IllegalArgumentException, IllegalAccessException { fromJSON(this, obj); + return this; } @SuppressWarnings("unchecked") diff --git a/test/json/JSONObjectTest.java b/test/json/JSONObjectTest.java index b4b4ad2..1c1a997 100644 --- a/test/json/JSONObjectTest.java +++ b/test/json/JSONObjectTest.java @@ -11,6 +11,7 @@ public class JSONObjectTest extends JSONObject { + C[] mC = {new C(), new C()}; public static String mS = "mS value"; static final String mSf = "Final fields ignored"; private double md = 3.14159; @@ -40,13 +41,35 @@ protected Object replacer(String name, Object value) { return IGNORED; // another way to ignore the field } else if (name.equals("mS")) { return "mS value replaced"; + } else if (name.equals("mC")) { + Object[] mmC = new Object[mC.length]; + for (int i = 0; i < mC.length; i++) { + try { + mmC[i] = mC[i].toJSON(); + } catch (IllegalAccessException | IllegalArgumentException ex) { + log(ex); + } + } + value = mmC; } return value; } @Override protected Object reviver(String name, Object value) { - logName(this, name); +// logName(this, name); + if (name.equals("mC")) { + Object[] jmC = (Object[]) value; + this.mC = new C[jmC.length]; + for (int i = 0; i < jmC.length; i++) { + try { + (this.mC[i] = new C()).fromJSON(jmC[i]); + } catch (IllegalAccessException | IllegalArgumentException ex) { + log(ex); + } + } + return IGNORED; + } return value; } @@ -60,6 +83,7 @@ protected Object replacer(String name, Object value) { ((JSON) value).set("jc", getJc()); log("Unloaded J.jc by getter: " + getJc()); } + super.replacer(name, value); return value; } @@ -75,6 +99,18 @@ protected Object reviver(String name, Object value) { } } + class C extends JSONObject { + + public String mS = "mS value"; + static final String mSf = "Final fields ignored"; + private double md = 3.14159; + private int mi = 123; + private String mSp = "mSp value"; + + C() { + } + } + public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, Exception { log("\n\rJSONObject test\n\r");