pax_global_header00006660000000000000000000000064147530225520014517gustar00rootroot0000000000000052 comment=d4f7fa4f31e20145d20393c5e79c6255954cb81e netplex-json-smart-v2-20dff24/000077500000000000000000000000001475302255200162275ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/.github/000077500000000000000000000000001475302255200175675ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/.github/FUNDING.yml000066400000000000000000000000201475302255200213740ustar00rootroot00000000000000github: urielch netplex-json-smart-v2-20dff24/.github/dependabot.yml000066400000000000000000000003411475302255200224150ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "maven" directory: "json-smart" schedule: interval: "monthly" - package-ecosystem: "maven" directory: "json-smart-action" schedule: interval: "monthly" netplex-json-smart-v2-20dff24/.github/workflows/000077500000000000000000000000001475302255200216245ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/.github/workflows/json-smart-unit-tests.yml000066400000000000000000000015141475302255200265620ustar00rootroot00000000000000 name: json smart unit tests on: push: branches: - master - update2024 pull_request: branches: - master jobs: publish: runs-on: ubuntu-latest strategy: matrix: java-version: [8, 11, 16, 17, 21] steps: - uses: actions/checkout@v4 - name: Set up JDK ${{ matrix.java-version }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.java-version }} distribution: 'temurin' cache: 'maven' - name: Unit tests accessors-smart run: cd accessors-smart; mvn -B install; mvn -B clean test - name: Unit tests json-smart run: cd json-smart; mvn -B install; mvn -B clean test - name: Unit tests json-smart-action run: cd json-smart-action; mvn -B install; mvn -B clean test netplex-json-smart-v2-20dff24/.gitignore000066400000000000000000000001611475302255200202150ustar00rootroot00000000000000# file system .DS_Store **/.classpath **/.idea/ **/.project **/.settings/ **/*.iml **/bin **/target **/.vscode/ netplex-json-smart-v2-20dff24/.vscode/000077500000000000000000000000001475302255200175705ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/.vscode/settings.json000066400000000000000000000001021475302255200223140ustar00rootroot00000000000000{ "java.configuration.updateBuildConfiguration": "automatic" }netplex-json-smart-v2-20dff24/LICENSE000066400000000000000000000261361475302255200172440ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} 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 http://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. netplex-json-smart-v2-20dff24/README.md000066400000000000000000000142211475302255200175060ustar00rootroot00000000000000# json-smart-v2 [![Build Status](https://travis-ci.org/netplex/json-smart-v2.svg?branch=master)](https://travis-ci.org/netplex/json-smart-v2) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.minidev/json-smart/badge.svg?style=flat-square)](https://maven-badges.herokuapp.com/maven-central/net.minidev/json-smart/) [![Coverage Status](https://coveralls.io/repos/github/netplex/json-smart-v2/badge.svg?branch=master)](https://coveralls.io/github/netplex/json-smart-v2?branch=master) Json-smart development started in 2010, when SQL servers did not support native JSON fields, NoSQL databases were slowly emerging, and all the existing JSON APIs were bogus. I wrote lots of tests to benchmark and compare JSON java parsers. I never liked SQL databases because it's almost impossible to update a data model without impacting the production platform. Adding a column is a terrible operation. So I started json-smart. All non-indexed data in my datastores were stored in a column as a serialized JSON message. To fit MySQL varchar(255) fields, I tried to make my JSON as small as possible, so json-smart is optimized to produce small JSON-like Strings. Now times have changed: most of the JSON APIs are now stable, and I'm now using document-oriented databases and JSON-native SQL types. So I do not use my json-smart anymore. I had fun with this project. If you want to apply some change on json-smart create a pull request with lots of JUnit tests. [WIKI is here](https://github.com/netplex/json-smart/wiki) # Changelog ### *V 2.5.2* (next version) * Fix CVE-2024-57699 for predefined parsers. [PR 233](https://github.com/netplex/json-smart-v2/pull/233) ### *V 2.5.1* (2024-03-14) * Bump all dependencies. * Fix OSGi import package version for net.minidev.asm. [PR 180](https://github.com/netplex/json-smart-v2/pull/180) ### *V 2.5.0* (2023-07-10) * Add flag to drop the limit of json depth. [PR 156](https://github.com/netplex/json-smart-v2/pull/156) ### *V 2.4.11* (2023-05-18) * Fix error in isWritable in accessor-smart. [PR 147](https://github.com/netplex/json-smart-v2/pull/147) * Update json-smart dependency to use accessor-smart:2.4.11 ### *V 2.4.10* (2023-03-17) * Fix unstacking issue with more than 400 elements in an array. ### *V 2.4.9* (2023-03-07) * Add depth limit of 400 when parsing JSON. ### *V 2.4.8* (2022-02-13) * Fix the incorrect double compare with e,E+,e+ [PR 77](https://github.com/netplex/json-smart-v2/pull/77) ### *V 2.4.7* (2021-06-02) * full timezone support in date parsing * set default charset to UTF-8 when parsing byte[] contents * overwride system default encoding when parssing bytes[] [PR 71](https://github.com/netplex/json-smart-v2/pull/74) ### *V 2.4.6* (2021-04-23) * Correct publish issue 3th time [issue 69](https://github.com/netplex/json-smart-v2/issues/69) * Support latest asm in accessor-smart [issue 70](https://github.com/netplex/json-smart-v2/issues/70) * Drop legacy parent pom ### *V 2.4.5* (2021-04-19) * Correct publish issue 2nd time [issue 69](https://github.com/netplex/json-smart-v2/issues/69) ### *V 2.4.4* (2021-04-17) * Correct publish issue 1st time [issue 69](https://github.com/netplex/json-smart-v2/issues/69) * fix ArrayIndexOutOfBoundsException [issue 68](https://github.com/netplex/json-smart-v2/pull/68) ### *V 2.4.2* (2021-04-04) ### *V 2.4.2* (2021-04-03) * add BIG_DIGIT_UNRESTRICTED to avoid BigDigit usage on some Double. * fix CVE-2021-27568 * java 11 build ### *V 2.3.1* (2021-05-02) * Fixes [issue #60](https://github.com/netplex/json-smart-v2/issues/60) (CVE-2021-27568) * full timezone support in date parsing ### *V 2.3* (2017-03-26) * Patch 37 [issue 37](http://code.google.com/p/json-smart/issues/detail?id=37) * Explicite support of char 127 [issue 18](http://code.google.com/p/json-smart/issues/detail?id=18) * Integrate json-smart-action from Eitan Raviv [PR 31](https://github.com/netplex/json-smart-v2/pull/31) * Remove hard codded e.printStackTrace() [issue 33](https://github.com/netplex/json-smart-v2/issues/33) * Improve date parsing code to support all timeZones [issue 29](https://github.com/netplex/json-smart-v2/issues/29) ### *V 2.2.2* * Fix support for default java datetime format for US locale * Update my time Zone from Paris to San Francisco. ### *V 2.2.1* (2015-10-08) * Fix issue in strict mode [issue gh-17](https://github.com/netplex/json-smart-v2/issues/17) * Add a licence Copy at the root project level [issue gh-16](https://github.com/netplex/json-smart-v2/issues/16) * Change InputStream input reading to use UTF8. [issue 48](http://code.google.com/p/json-smart/issues/detail?id=48) ### *V 2.2* (2015-07-29) * Rename asm to accessors-smart due to conflict name with asm.ow2.org lib. fix [PR-10](https://github.com/netplex/json-smart-v2/pull/10) * Fix OSGI error fix [PR-2](https://github.com/netplex/json-smart-v2/pull/2) * Add support for BigDecimal * Improve JSONObject.getAsNumber() helper * Add a Field Remaper ### *V 2.1.0* (2014-10-19) * net.minidev.json.mapper renamed to net.minidev.json.writer * Add ACCEPT_TAILLING_SPACE Parssing Flag. * Mapper classes now non static. * Reader mapper are now available in net.minidev.json.reader.JsonReader class * Writer mapper are now available in net.minidev.json.writer.JsonWriter class ### *V 2.0* (2014-08-12) * Fix Double Identification [issue 44](http://code.google.com/p/json-smart/issues/detail?id=44) * Fix Collection Interface Serialisation * Fix security Exception in ASM code * Project moved to GitHub * Fix [issue 42](http://code.google.com/p/json-smart/issues/detail?id=42) ### *V 2.0-RC3* (2013-08-14) * Add custom data binding inside the ASM layer. * Add Date support * Add \x escape sequence support [issue 39](http://code.google.com/p/json-smart/issues/detail?id=39) * fix issue [issue 37](http://code.google.com/p/json-smart/issues/detail?id=37) ### *V 2.0-RC2* (2012-04-03) * Fix critical [issue 23](http://code.google.com/p/json-smart/issues/detail?id=23) * Improve Javadoc in JSONStyle [issue 24](http://code.google.com/p/json-smart/issues/detail?id=23) ### *V 2.0-RC1* (2012-02-18) * speed improvement in POJO manipulation * add JSONStyle.LT_COMPRESS predefined generate strct json, but ignoring / escapement.netplex-json-smart-v2-20dff24/accessors-smart/000077500000000000000000000000001475302255200213405ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/.gitignore000066400000000000000000000000111475302255200233200ustar00rootroot00000000000000/target/ netplex-json-smart-v2-20dff24/accessors-smart/pom.xml000066400000000000000000000271231475302255200226620ustar00rootroot00000000000000 4.0.0 net.minidev accessors-smart 2.5.2 ASM based accessors helper used by json-smart Java reflect give poor performance on getter setter an constructor calls, accessors-smart use ASM to speed up those calls. bundle https://urielch.github.io/ Chemouni Uriel https://urielch.github.io/ uriel Uriel Chemouni uchemouni@gmail.com GMT+1 hezhangjian Zhangjian He hezhangjian97gmail.com GMT+8 The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo All files under Apache 2 UTF-8 10 1.8 1.8 scm:git:https://github.com/netplex/json-smart-v2.git scm:git:https://github.com/netplex/json-smart-v2.git https://github.com/netplex/json-smart-v2 ossrh https://s01.oss.sonatype.org/content/repositories/snapshots ossrh https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ release-sign-artifacts performRelease true 53BE126D org.apache.maven.plugins maven-gpg-plugin 3.2.7 sign-artifacts verify sign org.apache.maven.plugins maven-javadoc-plugin 3.10.1 8 attach-javadocs jar org.apache.maven.plugins maven-release-plugin 3.1.1 forked-path -Psonatype-oss-release false false release deploy include-sources / true src/main/java **/*.java org.apache.maven.plugins maven-source-plugin 3.3.1 bind-sources jar-no-fork org.apache.maven.plugins maven-compiler-plugin 3.13.0 UTF-8 ${maven.compiler.source} ${maven.compiler.target} org.apache.maven.plugins maven-resources-plugin 3.3.1 UTF-8 org.apache.maven.plugins maven-jar-plugin 3.4.2 org.apache.maven.plugins maven-javadoc-plugin 3.10.1 8 false attach-javadocs jar org.apache.felix maven-bundle-plugin 5.1.9 true ${project.groupId}.${project.artifactId} ${project.artifactId} ${project.version} org.objectweb.asm;version="[8.0,10)",* net.minidev.asm, net.minidev.asm.ex org.junit.jupiter junit-jupiter-api 5.11.2 test org.ow2.asm asm 9.7.1 netplex-json-smart-v2-20dff24/accessors-smart/src/000077500000000000000000000000001475302255200221275ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/000077500000000000000000000000001475302255200230535ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/000077500000000000000000000000001475302255200237745ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/000077500000000000000000000000001475302255200245625ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/000077500000000000000000000000001475302255200262155ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/000077500000000000000000000000001475302255200267755ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/ASMUtil.java000066400000000000000000000211571475302255200311240ustar00rootroot00000000000000package net.minidev.asm; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static org.objectweb.asm.Opcodes.CHECKCAST; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import java.lang.reflect.Field; import java.util.HashMap; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; /** * ASM Utils used to simplify class generation * * @author uriel Chemouni */ public class ASMUtil { /** * default constructor */ public ASMUtil() { super(); } /** * Append the call of proper autoboxing method for the given primitive type. * * @param mv MethodVisitor * @param clz expected class */ public static void autoBoxing(MethodVisitor mv, Class clz) { autoBoxing(mv, Type.getType(clz)); } /** * Extract all Accessor for the field of the given class. * * @param type type * @param filter FieldFilter * @return all Accessor available */ static public Accessor[] getAccessors(Class type, FieldFilter filter) { Class nextClass = type; HashMap map = new HashMap(); if (filter == null) filter = BasicFiledFilter.SINGLETON; while (nextClass != Object.class) { Field[] declaredFields = nextClass.getDeclaredFields(); for (Field field : declaredFields) { String fn = field.getName(); if (map.containsKey(fn)) continue; Accessor acc = new Accessor(nextClass, field, filter); if (!acc.isUsable()) continue; map.put(fn, acc); } nextClass = nextClass.getSuperclass(); } return map.values().toArray(new Accessor[map.size()]); } /** * Append the call of proper autoboxing method for the given primitive type. * * @param mv MethodVisitor * @param fieldType expected class */ protected static void autoBoxing(MethodVisitor mv, Type fieldType) { switch (fieldType.getSort()) { case Type.BOOLEAN: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); break; case Type.BYTE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); break; case Type.CHAR: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); break; case Type.SHORT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); break; case Type.INT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); break; case Type.FLOAT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); break; case Type.LONG: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); break; case Type.DOUBLE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); break; } } /** * Append the call of proper extract primitive type of an boxed object. * * @param mv MethodVisitor * @param fieldType expected class */ protected static void autoUnBoxing1(MethodVisitor mv, Type fieldType) { switch (fieldType.getSort()) { case Type.BOOLEAN: mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); break; case Type.BYTE: mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); break; case Type.CHAR: mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false); break; case Type.SHORT: mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); break; case Type.INT: mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); break; case Type.FLOAT: mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); break; case Type.LONG: mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); break; case Type.DOUBLE: mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); break; case Type.ARRAY: mv.visitTypeInsn(CHECKCAST, fieldType.getInternalName()); break; default: mv.visitTypeInsn(CHECKCAST, fieldType.getInternalName()); } } /** * Append the call of proper extract primitive type of an boxed object. this * method use Number interface to unbox object * * @param mv MethodVisitor * @param fieldType expected class */ protected static void autoUnBoxing2(MethodVisitor mv, Type fieldType) { switch (fieldType.getSort()) { case Type.BOOLEAN: mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); break; case Type.BYTE: mv.visitTypeInsn(CHECKCAST, "java/lang/Number"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "byteValue", "()B", false); break; case Type.CHAR: mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false); break; case Type.SHORT: mv.visitTypeInsn(CHECKCAST, "java/lang/Number"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "shortValue", "()S", false); break; case Type.INT: mv.visitTypeInsn(CHECKCAST, "java/lang/Number"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false); break; case Type.FLOAT: mv.visitTypeInsn(CHECKCAST, "java/lang/Number"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F", false); break; case Type.LONG: mv.visitTypeInsn(CHECKCAST, "java/lang/Number"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J", false); break; case Type.DOUBLE: mv.visitTypeInsn(CHECKCAST, "java/lang/Number"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D", false); break; case Type.ARRAY: mv.visitTypeInsn(CHECKCAST, fieldType.getInternalName()); break; default: mv.visitTypeInsn(CHECKCAST, fieldType.getInternalName()); } } /** * return a array of new Label (used for switch/case generation) * * @param cnt number of label to return * @return a Label array */ public static Label[] newLabels(int cnt) { Label[] r = new Label[cnt]; for (int i = 0; i < cnt; i++) r[i] = new Label(); return r; } /** * Generates a setter method name for a given field name. * * @param key the field name * @return setter name */ public static String getSetterName(String key) { int len = key.length(); char[] b = new char[len + 3]; b[0] = 's'; b[1] = 'e'; b[2] = 't'; char c = key.charAt(0); if (c >= 'a' && c <= 'z') c += 'A' - 'a'; b[3] = c; for (int i = 1; i < len; i++) { b[i + 3] = key.charAt(i); } return new String(b); } /** * Generates a getter method name for a given field name. * * @param key the field name * @return getter name */ public static String getGetterName(String key) { int len = key.length(); char[] b = new char[len + 3]; b[0] = 'g'; b[1] = 'e'; b[2] = 't'; char c = key.charAt(0); if (c >= 'a' && c <= 'z') c += 'A' - 'a'; b[3] = c; for (int i = 1; i < len; i++) { b[i + 3] = key.charAt(i); } return new String(b); } /** * Generates a boolean getter method name (is-method) for a given field name. * * @param key the boolean field name * @return boolean getter name */ public static String getIsName(String key) { int len = key.length(); char[] b = new char[len + 2]; b[0] = 'i'; b[1] = 's'; char c = key.charAt(0); if (c >= 'a' && c <= 'z') c += 'A' - 'a'; b[2] = c; for (int i = 1; i < len; i++) { b[i + 2] = key.charAt(i); } return new String(b); } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/Accessor.java000066400000000000000000000102441475302255200314030ustar00rootroot00000000000000package net.minidev.asm; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; /** * Contains all information needed to access a java field. * * field, getter setter * * this object is used internally by BeansAccess * * @see BeansAccess * * @author Uriel Chemouni */ public class Accessor { /** * Field to access */ protected Field field; /** * Setter Methods if available */ protected Method setter; /** * getter Methods if available */ protected Method getter; /** * Filed index in object */ protected int index; /** * Filed Class */ protected Class type; /** * Filed Type using JDK 5+ generics if available */ protected Type genericType; /** * The name of the field. */ protected String fieldName; /** * getter for index * @return Index */ public int getIndex() { return index; } /** * is the field access using Field access type * @return if Accessor is public */ public boolean isPublic() { return setter == null && getter == null; } /** * is the field is an enum field * @return if Accessor return an Enum Class */ public boolean isEnum() { return type.isEnum(); } /** * return the field name * @return the field name */ public String getName() { return fieldName; } /** * return field Class * @return field Class */ public Class getType() { return type; } /** * return generics field Type. * @return generics field Type. */ public Type getGenericType() { return genericType; } /** * Determines if the field is accessible for reading or writing operations. * * @return true if the field can be read or write */ public boolean isUsable() { return field != null || getter != null || setter != null; } /** * Checks if the field is readable, either directly or through a getter method. * * @return true if the field can be read */ public boolean isReadable() { return field != null || getter != null; } /** * Determines if the field is writable, either directly or through a setter method. * * @return true if the field can be write */ public boolean isWritable() { return field != null || setter != null; } /** * build accessor for a field * * @param c the handled class * @param field the field to access * @param filter field filter */ public Accessor(Class c, Field field, FieldFilter filter) { this.fieldName = field.getName(); int m = field.getModifiers(); if ((m & (Modifier.STATIC | Modifier.TRANSIENT)) > 0) return; if ((m & Modifier.PUBLIC) > 0) this.field = field; String name = ASMUtil.getSetterName(field.getName()); try { setter = c.getDeclaredMethod(name, field.getType()); } catch (Exception e) { } boolean isBool = field.getType().equals(Boolean.TYPE); if (isBool) { name = ASMUtil.getIsName(field.getName()); } else { name = ASMUtil.getGetterName(field.getName()); } try { getter = c.getDeclaredMethod(name); } catch (Exception e) { } if (getter == null && isBool) { try { getter = c.getDeclaredMethod(ASMUtil.getGetterName(field.getName())); } catch (Exception e) { } } if (this.field == null && getter == null && setter == null) return; if (getter != null && !filter.canUse(field, getter)) getter = null; if (setter != null && !filter.canUse(field, setter)) setter = null; // no access disable if (getter == null && setter == null && this.field == null) return; this.type = field.getType(); this.genericType = field.getGenericType(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/BasicFiledFilter.java000066400000000000000000000036171475302255200330020ustar00rootroot00000000000000package net.minidev.asm; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * A basic implementation of the {@link FieldFilter} interface that permits all operations on fields. * This implementation returns {@code true} for all checks, indicating that any field can be used, read, and written. * It serves as a default or fallback strategy when no specific field filtering logic is required. */ public class BasicFiledFilter implements FieldFilter { /** * default constructor */ public BasicFiledFilter() { super(); } /** * A singleton instance of {@code BasicFieldFilter}. * Since the filter does not maintain any state and allows all operations, it can be reused across the application. */ public final static BasicFiledFilter SINGLETON = new BasicFiledFilter(); /** * Always allows using the specified field. * * @param field The field to check. * @return Always returns {@code true}. */ @Override public boolean canUse(Field field) { return true; } /** * Always allows using the specified field in conjunction with a method. * * @param field The field to check. * @param method The method to check. This parameter is not used in the current implementation. * @return Always returns {@code true}. */ @Override public boolean canUse(Field field, Method method) { return true; } /** * Always allows reading the specified field. * * @param field The field to check. * @return Always returns {@code true}. */ @Override public boolean canRead(Field field) { return true; } /** * Always allows writing to the specified field. * * @param field The field to check. * @return Always returns {@code true}. */ @Override public boolean canWrite(Field field) { return true; } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/BeansAccess.java000066400000000000000000000142721475302255200320200ustar00rootroot00000000000000package net.minidev.asm; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.util.HashMap; import java.util.LinkedList; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; /** * Allow access reflect field using runtime generated accessor. BeansAccessor is * faster than java.lang.reflect.Method.invoke() * * @param the type of the bean being accessed * @author uriel Chemouni */ public abstract class BeansAccess { /** * default constuctor */ public BeansAccess() { super(); } private HashMap map; private Accessor[] accs; /** * set Accessor * @param accs Accessor list */ protected void setAccessor(Accessor[] accs) { int i = 0; this.accs = accs; map = new HashMap(); for (Accessor acc : accs) { acc.index = i++; map.put(acc.getName(), acc); } } /** * get internal map * @return a map */ public HashMap getMap() { return map; } /** * get internal accessor * @return Accessor list */ public Accessor[] getAccessors() { return accs; } /** * cache used to store built BeansAccess */ private static ConcurrentHashMap, BeansAccess> cache = new ConcurrentHashMap, BeansAccess>(); // private final static ConcurrentHashMap> cache; /** * return the BeansAccess corresponding to a type * * @param type to be access * @param

working type * @return the BeansAccess */ static public

BeansAccess

get(Class

type) { return get(type, null); } /** * return the BeansAccess corresponding to a type * * @param filter FieldFilter * @param type to be access * @param

working type * @return the BeansAccess */ static public

BeansAccess

get(Class

type, FieldFilter filter) { { @SuppressWarnings("unchecked") BeansAccess

access = (BeansAccess

) cache.get(type); if (access != null) return access; } // extract all access methods Accessor[] accs = ASMUtil.getAccessors(type, filter); // create new class name String className = type.getName(); String accessClassName; if (className.startsWith("java.util.")) accessClassName = "net.minidev.asm." + className + "AccAccess"; else accessClassName = className.concat("AccAccess"); // extend class base loader DynamicClassLoader loader = new DynamicClassLoader(type.getClassLoader()); // try to load existing class Class accessClass = null; try { accessClass = loader.loadClass(accessClassName); } catch (ClassNotFoundException ignored) { } LinkedList> parentClasses = getParents(type); // if the class do not exists build it if (accessClass == null) { BeansAccessBuilder builder = new BeansAccessBuilder(type, accs, loader); for (Class c : parentClasses) builder.addConversion(BeansAccessConfig.classMapper.get(c)); accessClass = builder.bulid(); } try { @SuppressWarnings("unchecked") BeansAccess

access = (BeansAccess

) accessClass.newInstance(); access.setAccessor(accs); cache.putIfAbsent(type, access); // add fieldname alias for (Class c : parentClasses) addAlias(access, BeansAccessConfig.classFiledNameMapper.get(c)); return access; } catch (Exception ex) { throw new RuntimeException("Error constructing accessor class: " + accessClassName, ex); } } /** * @param type current type * @return parents hierarchy */ private static LinkedList> getParents(Class type) { LinkedList> m = new LinkedList>(); while (type != null && !type.equals(Object.class)) { m.addLast(type); for (Class c : type.getInterfaces()) m.addLast(c); type = type.getSuperclass(); } m.addLast(Object.class); return m; } /** * @param access accessor to use * @param m mapping */ private static void addAlias(BeansAccess access, HashMap m) { // HashMap m = // BeansAccessConfig.classFiledNameMapper.get(type); if (m == null) return; HashMap changes = new HashMap(); for (Entry e : m.entrySet()) { Accessor a1 = access.map.get(e.getValue()); if (a1 != null) changes.put(e.getValue(), a1); } access.map.putAll(changes); } /** * set field value by field index * * @param object object to alter * @param methodIndex field id to update * @param value new value */ abstract public void set(T object, int methodIndex, Object value); /** * get field value by field index * @param object object to operate * @param methodIndex field number to operate * @return value of the field */ abstract public Object get(T object, int methodIndex); /** * create a new targeted object * @return new instance */ abstract public T newInstance(); /** * set field value by field name * @param object target object * @param methodName methodName * @param value new field value */ public void set(T object, String methodName, Object value) { int i = getIndex(methodName); if (i == -1) throw new net.minidev.asm.ex.NoSuchFieldException(methodName + " in " + object.getClass() + " to put value : " + value); set(object, i, value); } /** * get field value by field name * @param object object to operate * @param methodName getter to call * @return field value returned by the getter */ public Object get(T object, String methodName) { return get(object, getIndex(methodName)); } /** * Returns the index of the field accessor. * @param name field name * @return id of the field */ public int getIndex(String name) { Accessor ac = map.get(name); if (ac == null) return -1; return ac.index; } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/BeansAccessBuilder.java000066400000000000000000000373731475302255200333360ustar00rootroot00000000000000package net.minidev.asm; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACONST_NULL; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.ARETURN; import static org.objectweb.asm.Opcodes.ASTORE; import static org.objectweb.asm.Opcodes.ATHROW; import static org.objectweb.asm.Opcodes.BIPUSH; import static org.objectweb.asm.Opcodes.CHECKCAST; import static org.objectweb.asm.Opcodes.DUP; import static org.objectweb.asm.Opcodes.F_SAME; import static org.objectweb.asm.Opcodes.GETFIELD; import static org.objectweb.asm.Opcodes.ICONST_1; import static org.objectweb.asm.Opcodes.ICONST_2; import static org.objectweb.asm.Opcodes.ICONST_3; import static org.objectweb.asm.Opcodes.ICONST_4; import static org.objectweb.asm.Opcodes.ICONST_5; import static org.objectweb.asm.Opcodes.IFEQ; import static org.objectweb.asm.Opcodes.IFNE; import static org.objectweb.asm.Opcodes.IFNULL; import static org.objectweb.asm.Opcodes.IF_ICMPNE; import static org.objectweb.asm.Opcodes.ILOAD; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import static org.objectweb.asm.Opcodes.NEW; import static org.objectweb.asm.Opcodes.PUTFIELD; import static org.objectweb.asm.Opcodes.RETURN; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; /** * A builder class for dynamically creating {@link BeansAccess} classes for accessing bean properties efficiently. * This class utilizes the ASM library to generate bytecode at runtime, thereby bypassing the need for Java reflection. */ public class BeansAccessBuilder { static private String METHOD_ACCESS_NAME = Type.getInternalName(BeansAccess.class); final Class type; final Accessor[] accs; final DynamicClassLoader loader; final String className; final String accessClassName; final String accessClassNameInternal; final String classNameInternal; final HashMap, Method> convMtds = new HashMap, Method>(); // Class exceptionClass = net.minidev.asm.ex.NoSuchFieldException.class; Class exceptionClass = NoSuchFieldException.class; /** * Initializes a new builder instance for a given bean class. * * @param type * type to be access * @param accs * used accessor * @param loader * Loader used to store the generated class */ public BeansAccessBuilder(Class type, Accessor[] accs, DynamicClassLoader loader) { this.type = type; this.accs = accs; this.loader = loader; this.className = type.getName(); if (className.startsWith("java.")) this.accessClassName = "net.minidev.asm." + className + "AccAccess"; else this.accessClassName = className.concat("AccAccess"); this.accessClassNameInternal = accessClassName.replace('.', '/'); this.classNameInternal = className.replace('.', '/'); } /** * register multiple new conversion * @param conv conv list */ public void addConversion(Iterable> conv) { if (conv == null) return; for (Class c : conv) addConversion(c); } /** * Resister a new conversion * @param conv the conv */ public void addConversion(Class conv) { if (conv == null) return; for (Method mtd : conv.getMethods()) { if ((mtd.getModifiers() & Modifier.STATIC) == 0) continue; Class[] param = mtd.getParameterTypes(); if (param.length != 1) continue; if (!param[0].equals(Object.class)) continue; Class rType = mtd.getReturnType(); if (rType.equals(Void.TYPE)) continue; convMtds.put(rType, mtd); } } /** * build the conversion class. * @return the new Class */ public Class bulid() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); MethodVisitor mv; boolean USE_HASH = accs.length > 10; int HASH_LIMIT = 14; String signature = "Lnet/minidev/asm/BeansAccess;"; cw.visit(Opcodes.V1_6, ACC_PUBLIC + Opcodes.ACC_SUPER, accessClassNameInternal, signature, METHOD_ACCESS_NAME, null); // init { mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, METHOD_ACCESS_NAME, "", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //////////// // Build SETter using filed index // // public void set(Object object, int fieldId, Object value) mv = cw.visitMethod(ACC_PUBLIC, "set", "(Ljava/lang/Object;ILjava/lang/Object;)V", null, null); mv.visitCode(); // if no Field simply return if (accs.length == 0) { // // mv.visitInsn(RETURN); } else if (accs.length > HASH_LIMIT) { // lots of field Use Switch Statement mv.visitVarInsn(ILOAD, 2); Label[] labels = ASMUtil.newLabels(accs.length); Label defaultLabel = new Label(); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); int i = 0; for (Accessor acc : accs) { mv.visitLabel(labels[i++]); if (!acc.isWritable()) { mv.visitInsn(RETURN); continue; } internalSetFiled(mv, acc); } mv.visitLabel(defaultLabel); } else { Label[] labels = ASMUtil.newLabels(accs.length); int i = 0; for (Accessor acc : accs) { ifNotEqJmp(mv, 2, i, labels[i]); internalSetFiled(mv, acc); mv.visitLabel(labels[i]); mv.visitFrame(F_SAME, 0, null, 0, null); i++; } } if (exceptionClass != null) throwExIntParam(mv, exceptionClass); else mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); //////////// // Build GETter using filed index // // public Object get(Object object, int fieldId) mv = cw.visitMethod(ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, null); mv.visitCode(); if (accs.length == 0) { mv.visitFrame(F_SAME, 0, null, 0, null); } else if (accs.length > HASH_LIMIT) { mv.visitVarInsn(ILOAD, 2); Label[] labels = ASMUtil.newLabels(accs.length); Label defaultLabel = new Label(); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); int i = 0; for (Accessor acc : accs) { mv.visitLabel(labels[i++]); mv.visitFrame(F_SAME, 0, null, 0, null); if (!acc.isReadable()) { mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); continue; } mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); Type fieldType = Type.getType(acc.getType()); if (acc.isPublic() || acc.getter == null) { mv.visitFieldInsn(GETFIELD, classNameInternal, acc.getName(), fieldType.getDescriptor()); } else { String sig = Type.getMethodDescriptor(acc.getter); mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, acc.getter.getName(), sig, false); } ASMUtil.autoBoxing(mv, fieldType); mv.visitInsn(ARETURN); } mv.visitLabel(defaultLabel); mv.visitFrame(F_SAME, 0, null, 0, null); } else { Label[] labels = ASMUtil.newLabels(accs.length); int i = 0; for (Accessor acc : accs) { ifNotEqJmp(mv, 2, i, labels[i]); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); Type fieldType = Type.getType(acc.getType()); if (acc.isPublic() || acc.getter == null) { mv.visitFieldInsn(GETFIELD, classNameInternal, acc.getName(), fieldType.getDescriptor()); } else { if (acc.getter == null) throw new RuntimeException("no Getter for field " + acc.getName() + " in class " + this.className); String sig = Type.getMethodDescriptor(acc.getter); mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, acc.getter.getName(), sig, false); } ASMUtil.autoBoxing(mv, fieldType); mv.visitInsn(ARETURN); mv.visitLabel(labels[i]); mv.visitFrame(F_SAME, 0, null, 0, null); i++; } } if (exceptionClass != null) throwExIntParam(mv, exceptionClass); else { mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); } mv.visitMaxs(0, 0); mv.visitEnd(); //////////// // Build SETter using filed Name // // public Object set(Object object, String methodName, Object value) if (!USE_HASH) { mv = cw.visitMethod(ACC_PUBLIC, "set", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V", null, null); mv.visitCode(); Label[] labels = ASMUtil.newLabels(accs.length); int i = 0; for (Accessor acc : accs) { mv.visitVarInsn(ALOAD, 2); mv.visitLdcInsn(acc.fieldName); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); mv.visitJumpInsn(IFEQ, labels[i]); internalSetFiled(mv, acc); mv.visitLabel(labels[i]); mv.visitFrame(F_SAME, 0, null, 0, null); i++; } if (exceptionClass != null) throwExStrParam(mv, exceptionClass); else mv.visitInsn(RETURN); mv.visitMaxs(0, 0); // 2,4 mv.visitEnd(); } //////////// // Build GETter using filed Name // // public Object get(Object object, String methodName) if (!USE_HASH) { mv = cw.visitMethod(ACC_PUBLIC, "get", "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;", null, null); mv.visitCode(); Label[] labels = ASMUtil.newLabels(accs.length); int i = 0; for (Accessor acc : accs) { mv.visitVarInsn(ALOAD, 2); // methodName mv.visitLdcInsn(acc.fieldName); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); mv.visitJumpInsn(IFEQ, labels[i]); mv.visitVarInsn(ALOAD, 1); // object mv.visitTypeInsn(CHECKCAST, classNameInternal); Type fieldType = Type.getType(acc.getType()); if (acc.isPublic() || acc.getter == null) { mv.visitFieldInsn(GETFIELD, classNameInternal, acc.getName(), fieldType.getDescriptor()); } else { String sig = Type.getMethodDescriptor(acc.getter); mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, acc.getter.getName(), sig, false); } ASMUtil.autoBoxing(mv, fieldType); mv.visitInsn(ARETURN); mv.visitLabel(labels[i]); mv.visitFrame(F_SAME, 0, null, 0, null); i++; } if (exceptionClass != null) throwExStrParam(mv, exceptionClass); else { mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); } mv.visitMaxs(0, 0); mv.visitEnd(); } //////////// // Build constructor // { mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "()Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, classNameInternal); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, classNameInternal, "", "()V", false); mv.visitInsn(ARETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } cw.visitEnd(); byte[] data = cw.toByteArray(); // dumpDebug(data, "/tmp/debug-" + accessClassName + ".txt"); return loader.defineClass(accessClassName, data); } /** * Dump Generate Code */ @SuppressWarnings("unused") private void dumpDebug(byte[] data, String destFile) { // try { // File debug = new File(destFile); // int flags = ClassReader.SKIP_DEBUG; // ClassReader cr = new ClassReader(new ByteArrayInputStream(data)); // cr.accept(new ASMifierClassVisitor(new PrintWriter(debug)), // ASMifierClassVisitor.getDefaultAttributes(), // flags); // } catch (Exception e) { // } } /** * Dump Set Field Code * * @param mv * @param acc */ private void internalSetFiled(MethodVisitor mv, Accessor acc) { /** * FNC params * * 1 -> object to alter * * 2 -> id of field * * 3 -> new value */ mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); // get VALUE mv.visitVarInsn(ALOAD, 3); Type fieldType = Type.getType(acc.getType()); Class type = acc.getType(); String destClsName = Type.getInternalName(type); Method conMtd = convMtds.get(type); if (conMtd != null) { // external conversion String clsSig = Type.getInternalName(conMtd.getDeclaringClass()); String mtdName = conMtd.getName(); String mtdSig = Type.getMethodDescriptor(conMtd); mv.visitMethodInsn(INVOKESTATIC, clsSig, mtdName, mtdSig, false); } else if (acc.isEnum()) { // builtIn Enum Conversion Label isNull = new Label(); mv.visitJumpInsn(IFNULL, isNull); mv.visitVarInsn(ALOAD, 3); // mv.visitTypeInsn(CHECKCAST, "java/lang/String"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false); mv.visitMethodInsn(INVOKESTATIC, destClsName, "valueOf", "(Ljava/lang/String;)L" + destClsName + ";", false); mv.visitVarInsn(ASTORE, 3); mv.visitLabel(isNull); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, this.classNameInternal); // "net/minidev/asm/bean/BEnumPriv" mv.visitVarInsn(ALOAD, 3); mv.visitTypeInsn(CHECKCAST, destClsName); } else if (type.equals(String.class)) { // built In String Conversion Label isNull = new Label(); mv.visitJumpInsn(IFNULL, isNull); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false); mv.visitVarInsn(ASTORE, 3); mv.visitLabel(isNull); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, this.classNameInternal); mv.visitVarInsn(ALOAD, 3); mv.visitTypeInsn(CHECKCAST, destClsName); } else { // just check Cast mv.visitTypeInsn(CHECKCAST, destClsName); } if (acc.isPublic() || acc.setter == null) { mv.visitFieldInsn(PUTFIELD, classNameInternal, acc.getName(), fieldType.getDescriptor()); } else { String sig = Type.getMethodDescriptor(acc.setter); mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, acc.setter.getName(), sig, false); } mv.visitInsn(RETURN); } /** * add Throws statement with int param 2 */ private void throwExIntParam(MethodVisitor mv, Class exCls) { String exSig = Type.getInternalName(exCls); mv.visitTypeInsn(NEW, exSig); mv.visitInsn(DUP); mv.visitLdcInsn("mapping " + this.className + " failed to map field:"); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString", "(I)Ljava/lang/String;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "concat", "(Ljava/lang/String;)Ljava/lang/String;", false); mv.visitMethodInsn(INVOKESPECIAL, exSig, "", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); } /** * add Throws statement with String param 2 */ private void throwExStrParam(MethodVisitor mv, Class exCls) { String exSig = Type.getInternalName(exCls); mv.visitTypeInsn(NEW, exSig); mv.visitInsn(DUP); mv.visitLdcInsn("mapping " + this.className + " failed to map field:"); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "concat", "(Ljava/lang/String;)Ljava/lang/String;", false); mv.visitMethodInsn(INVOKESPECIAL, exSig, "", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); } /** * dump a Jump if not EQ */ private void ifNotEqJmp(MethodVisitor mv, int param, int value, Label label) { mv.visitVarInsn(ILOAD, param); if (value == 0) { /* notest for value 0 */ mv.visitJumpInsn(IFNE, label); } else if (value == 1) { mv.visitInsn(ICONST_1); mv.visitJumpInsn(IF_ICMPNE, label); } else if (value == 2) { mv.visitInsn(ICONST_2); mv.visitJumpInsn(IF_ICMPNE, label); } else if (value == 3) { mv.visitInsn(ICONST_3); mv.visitJumpInsn(IF_ICMPNE, label); } else if (value == 4) { mv.visitInsn(ICONST_4); mv.visitJumpInsn(IF_ICMPNE, label); } else if (value == 5) { mv.visitInsn(ICONST_5); mv.visitJumpInsn(IF_ICMPNE, label); } else if (value >= 6) { mv.visitIntInsn(BIPUSH, value); mv.visitJumpInsn(IF_ICMPNE, label); } else { throw new RuntimeException("non supported negative values"); } } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/BeansAccessConfig.java000066400000000000000000000040741475302255200331450ustar00rootroot00000000000000package net.minidev.asm; import java.util.HashMap; import java.util.LinkedHashSet; /** * Beans Access Config */ public class BeansAccessConfig { /** * default constructor */ public BeansAccessConfig() { super(); } /** * Field type convertor for all classes * * Convertor classes should contains mapping method Prototyped as: * * public static DestinationType Method(Object data); * * @see DefaultConverter */ //static protected LinkedHashSet> globalMapper = new LinkedHashSet>(); /** * Field type convertor for custom Class * * Convertor classes should contains mapping method Prototyped as: * * public static DestinationType Method(Object data); * * @see DefaultConverter */ static protected HashMap, LinkedHashSet>> classMapper = new HashMap, LinkedHashSet>>(); /** * FiledName remapper for a specific class or interface */ static protected HashMap, HashMap> classFiledNameMapper = new HashMap, HashMap>(); static { addTypeMapper(Object.class, DefaultConverter.class); addTypeMapper(Object.class, ConvertDate.class); } // /** // * Field type convertor for all classes // * // * Convertor classes should contains mapping method Prototyped as: // * // * public static DestinationType Method(Object data); // * // * @see DefaultConverter // */ // public static void addGlobalTypeMapper(Class mapper) { // synchronized (globalMapper) { // globalMapper.add(mapper); // } // } /** * Field type convertor for all classes * * Convertor classes should contains mapping method Prototyped as: * * public static DestinationType Method(Object data); * * @see DefaultConverter * * @param clz class * @param mapper mapper */ public static void addTypeMapper(Class clz, Class mapper) { synchronized (classMapper) { LinkedHashSet> h = classMapper.get(clz); if (h == null) { h = new LinkedHashSet>(); classMapper.put(clz, h); } h.add(mapper); } } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/ConvertDate.java000066400000000000000000000250431475302255200320620ustar00rootroot00000000000000package net.minidev.asm; import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.Comparator; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashSet; import java.util.Locale; import java.util.StringTokenizer; import java.util.TimeZone; import java.util.TreeMap; /** * Utility class for converting strings into {@link Date} objects, considering various global date formats. * It handles different month and day names across languages, and supports timezone adjustments. */ public class ConvertDate { /** * default constructor */ public ConvertDate() { super(); } static TreeMap monthsTable = new TreeMap(new StringCmpNS()); // StringCmpNS.COMP static TreeMap daysTable = new TreeMap(new StringCmpNS()); // StringCmpNS.COMP private static HashSet voidData = new HashSet(); /** * Default TimeZone used for date conversions. Can be overwritten to change the default time zone. */ public static TimeZone defaultTimeZone; /** * Comparator for case-insensitive string comparison. Used for sorting and comparing month and day names. */ public static class StringCmpNS implements Comparator { /** * default constructor */ public StringCmpNS() { super(); } @Override public int compare(String o1, String o2) { return o1.compareToIgnoreCase(o2); } } /** * Retrieves the month's integer representation based on the provided month name. * * @param month the name of the month * @return the integer value of the month, or null if the month name is unrecognized */ public static Integer getMonth(String month) { return monthsTable.get(month); } private static Integer parseMonth(String s1) { if (Character.isDigit(s1.charAt(0))) { return Integer.parseInt(s1) - 1; } else { Integer month = monthsTable.get(s1); if (month == null) throw new NullPointerException("can not parse " + s1 + " as month"); return month.intValue(); } } /** * @return a current timezoned 01/01/2000 00:00:00 GregorianCalendar */ private static GregorianCalendar newCalandar() { GregorianCalendar cal = new GregorianCalendar(2000, 0, 0, 0, 0, 0); if (defaultTimeZone != null) cal.setTimeZone(defaultTimeZone); TimeZone TZ = cal.getTimeZone(); if (TZ == null) { TZ = TimeZone.getDefault(); } cal.setTimeInMillis(-TZ.getRawOffset()); return cal; } static TreeMap timeZoneMapping; static { timeZoneMapping = new TreeMap(); voidData.add("à"); // added for french 1st of may 2021 voidData.add("at"); voidData.add("MEZ"); voidData.add("Uhr"); voidData.add("h"); voidData.add("pm"); voidData.add("PM"); voidData.add("am"); voidData.add("AM"); voidData.add("min"); // Canada french voidData.add("um"); // German voidData.add("o'clock"); for (String tz : TimeZone.getAvailableIDs()) { timeZoneMapping.put(tz, TimeZone.getTimeZone(tz)); } for (Locale locale : DateFormatSymbols.getAvailableLocales()) { if ("ja".equals(locale.getLanguage())) continue; if ("ko".equals(locale.getLanguage())) continue; if ("zh".equals(locale.getLanguage())) continue; DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale); String[] keys = dfs.getMonths(); for (int i = 0; i < keys.length; i++) { if (keys[i].length() == 0) continue; fillMap(monthsTable, keys[i], Integer.valueOf(i)); } keys = dfs.getShortMonths(); for (int i = 0; i < keys.length; i++) { String s = keys[i]; if (s.length() == 0) continue; if (Character.isDigit(s.charAt(s.length() - 1))) continue; fillMap(monthsTable, keys[i], Integer.valueOf(i)); fillMap(monthsTable, keys[i].replace(".", ""), Integer.valueOf(i)); } keys = dfs.getWeekdays(); for (int i = 0; i < keys.length; i++) { String s = keys[i]; if (s.length() == 0) continue; fillMap(daysTable, s, Integer.valueOf(i)); fillMap(daysTable, s.replace(".", ""), Integer.valueOf(i)); } keys = dfs.getShortWeekdays(); for (int i = 0; i < keys.length; i++) { String s = keys[i]; if (s.length() == 0) continue; fillMap(daysTable, s, Integer.valueOf(i)); fillMap(daysTable, s.replace(".", ""), Integer.valueOf(i)); } } } private static void fillMap(TreeMap map, String key, Integer value) { map.put(key, value); key = key.replace("é", "e"); key = key.replace("û", "u"); map.put(key, value); } /** * try read a Date from a Object * @param obj object to convert to date * @return a date value */ public static Date convertToDate(Object obj) { if (obj == null) return null; if (obj instanceof Date) return (Date) obj; if (obj instanceof Number) return new Date(((Number)obj).longValue()); if (obj instanceof String) { obj = ((String) obj) .replace("p.m.", "pm") .replace("a.m.", "am"); // added on 1st of may 2021 // contains 2 differents spaces StringTokenizer st = new StringTokenizer((String) obj, "  -/:,.+年月日曜時分秒"); // 2012年1月23日月曜日 13時42分59秒 中央ヨーロッパ標準時 String s1 = ""; if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); if (s1.length() == 4 && Character.isDigit(s1.charAt(0))) return getYYYYMMDD(st, s1); // skip Day if present. if (daysTable.containsKey(s1)) { if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); } if (monthsTable.containsKey(s1)) return getMMDDYYYY(st, s1); if (Character.isDigit(s1.charAt(0))) return getDDMMYYYY(st, s1); return null; } throw new RuntimeException("Primitive: Can not convert " + obj.getClass().getName() + " to int"); } /** * * @param st StringTokenizer * @param s1 previous token * @return a Date */ private static Date getYYYYMMDD(StringTokenizer st, String s1) { GregorianCalendar cal = newCalandar(); int year = Integer.parseInt(s1); cal.set(Calendar.YEAR, year); if (!st.hasMoreTokens()) return cal.getTime(); s1 = st.nextToken(); cal.set(Calendar.MONTH, parseMonth(s1)); if (!st.hasMoreTokens()) return cal.getTime(); s1 = st.nextToken(); if (Character.isDigit(s1.charAt(0))) { if (s1.length() == 5 && s1.charAt(2) == 'T') { // TIME + TIMEZONE int day = Integer.parseInt(s1.substring(0,2)); cal.set(Calendar.DAY_OF_MONTH, day); return addHour(st, cal, s1.substring(3)); } int day = Integer.parseInt(s1); cal.set(Calendar.DAY_OF_MONTH, day); return addHour(st, cal, null); } return cal.getTime(); } /** * @param s1 2 years date * @return a 1900 or 2000 year */ private static int getYear(String s1) { int year = Integer.parseInt(s1); // CET ? if (year < 100) { if (year > 30) year += 2000; else year += 1900; } return year; } /** * @param st StringTokenizer * @param s1 privious token * @return a date */ private static Date getMMDDYYYY(StringTokenizer st, String s1) { GregorianCalendar cal = newCalandar(); Integer month = monthsTable.get(s1); if (month == null) throw new NullPointerException("can not parse " + s1 + " as month"); cal.set(Calendar.MONTH, month); if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); // DAY int day = Integer.parseInt(s1); cal.set(Calendar.DAY_OF_MONTH, day); if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); if (Character.isLetter(s1.charAt(0))) { if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); } if (s1.length() == 4) cal.set(Calendar.YEAR, getYear(s1)); else if (s1.length() == 2) { return addHour2(st, cal, s1); } // /if (st.hasMoreTokens()) // return null; // s1 = st.nextToken(); return addHour(st, cal, null); // return cal.getTime(); } /** * parse a date as DDMMYYYY * @param st StringTokenizer * @param s1 previous token * @return a Date */ private static Date getDDMMYYYY(StringTokenizer st, String s1) { GregorianCalendar cal = newCalandar(); int day = Integer.parseInt(s1); cal.set(Calendar.DAY_OF_MONTH, day); if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); cal.set(Calendar.MONTH, parseMonth(s1)); if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); cal.set(Calendar.YEAR, getYear(s1)); return addHour(st, cal, null); } /** * @param st StringTokenizer * @param cal Calendar * @param s1 previous token * @return a Date */ private static Date addHour(StringTokenizer st, Calendar cal, String s1) { // String s1; if (s1 == null) { if (!st.hasMoreTokens()) return cal.getTime(); s1 = st.nextToken(); } return addHour2(st, cal, s1); } /** * @param st StringTokenizer * @param cal Calendar * @param s1 previous token * @return a Date */ private static Date addHour2(StringTokenizer st, Calendar cal, String s1) { s1 = trySkip(st, s1, cal); cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(s1)); if (!st.hasMoreTokens()) return cal.getTime(); s1 = st.nextToken(); s1 = trySkip(st, s1, cal); if (s1 == null) return cal.getTime(); // if (s1.equalsIgnoreCase("h")) { // if (!st.hasMoreTokens()) // return cal.getTime(); // s1 = st.nextToken(); // } cal.set(Calendar.MINUTE, Integer.parseInt(s1)); if (!st.hasMoreTokens()) return cal.getTime(); s1 = st.nextToken(); s1 = trySkip(st, s1, cal); if (s1 == null) return cal.getTime(); cal.set(Calendar.SECOND, Integer.parseInt(s1)); if (!st.hasMoreTokens()) return cal.getTime(); s1 = st.nextToken(); s1 = trySkip(st, s1, cal); if (s1 == null) return cal.getTime(); // TODO ADD TIME ZONE s1 = trySkip(st, s1, cal); // if (s1.equalsIgnoreCase("pm")) // cal.add(Calendar.HOUR_OF_DAY, 12); if (s1.length() == 4 && Character.isDigit(s1.charAt(0))) cal.set(Calendar.YEAR, getYear(s1)); return cal.getTime(); } /** * Handle some Date Keyword like PST UTC am pm ... * @param st StringTokenizer * @param s1 previous token * @param cal Calendar * @return a date */ private static String trySkip(StringTokenizer st, String s1, Calendar cal) { while (true) { TimeZone tz = timeZoneMapping.get(s1); if (tz != null) { cal.setTimeZone(tz); if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); continue; } if (voidData.contains(s1)) { if (s1.equalsIgnoreCase("pm")) cal.add(Calendar.AM_PM, Calendar.PM); if (s1.equalsIgnoreCase("am")) cal.add(Calendar.AM_PM, Calendar.AM); if (!st.hasMoreTokens()) return null; s1 = st.nextToken(); continue; } return s1; } } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/DefaultConverter.java000066400000000000000000000245271475302255200331260ustar00rootroot00000000000000package net.minidev.asm; import net.minidev.asm.ex.ConvertException; /** * Provides utility methods to convert objects to different primitive types and their wrapper classes. * It supports conversion from {@link Number} instances and {@link String} representations of numbers * to their corresponding primitive types or wrapper classes. Conversion from types that are not supported * will result in a {@link ConvertException}. */ public class DefaultConverter { /** * Default constructor */ public DefaultConverter() { super(); } /** * Converts the given object to an {@code int}. * * @param obj the object to convert * @return the converted int value, or 0 if the object is {@code null} * @throws ConvertException if the object cannot be converted to an int */ public static int convertToint(Object obj) { if (obj == null) return 0; if (obj instanceof Number) return ((Number) obj).intValue(); if (obj instanceof String) return Integer.parseInt((String) obj); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to int"); } /** * Converts the given object to an {@link Integer}. * * @param obj the object to convert * @return the converted Integer, or {@code null} if the object is {@code null} * @throws ConvertException if the object cannot be converted to an Integer */ public static Integer convertToInt(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Integer.class) return (Integer) obj; if (obj instanceof Number) return Integer.valueOf(((Number) obj).intValue()); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to Integer"); } /** * Converts the given object to a {@code short}. * * @param obj the object to convert * @return the converted short value, or 0 if the object is {@code null} * @throws ConvertException if the object cannot be converted to a short */ public static short convertToshort(Object obj) { if (obj == null) return 0; if (obj instanceof Number) return ((Number) obj).shortValue(); if (obj instanceof String) return Short.parseShort((String) obj); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to short"); } /** * Converts the given object to a {@code short}. * * @param obj the object to convert * @return the converted short value, or 0 if the object is {@code null} * @throws ConvertException if the object cannot be converted to a short */ public static Short convertToShort(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Short.class) return (Short) obj; if (obj instanceof Number) return Short.valueOf(((Number) obj).shortValue()); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to Short"); } /** * Converts the given object to a {@code long}. * * @param obj the object to convert * @return the converted long value, or 0 if the object is {@code null} * @throws ConvertException if the object cannot be converted to a long */ public static long convertTolong(Object obj) { if (obj == null) return 0; if (obj instanceof Number) return ((Number) obj).longValue(); if (obj instanceof String) return Long.parseLong((String) obj); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to long"); } /** * Converts the given object to a {@link Long}. * * @param obj the object to convert * @return the converted Long, or {@code null} if the object is {@code null} * @throws ConvertException if the object cannot be converted to a Long */ public static Long convertToLong(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Long.class) return (Long) obj; if (obj instanceof Number) return Long.valueOf(((Number) obj).longValue()); throw new ConvertException("Primitive: Can not convert value '" + obj+ "' As " + obj.getClass().getName() + " to Long"); } /** * Converts the given object to a {@code byte}. * * @param obj the object to convert * @return the converted byte value, or 0 if the object is {@code null} * @throws ConvertException if the object cannot be converted to a byte */ public static byte convertTobyte(Object obj) { if (obj == null) return 0; if (obj instanceof Number) return ((Number) obj).byteValue(); if (obj instanceof String) return Byte.parseByte((String) obj); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to byte"); } /** * Converts the given object to a {@link Byte}. * * @param obj the object to convert * @return the converted Byte, or {@code null} if the object is {@code null} * @throws ConvertException if the object cannot be converted to a Byte */ public static Byte convertToByte(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Byte.class) return (Byte) obj; if (obj instanceof Number) return Byte.valueOf(((Number) obj).byteValue()); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to Byte"); } /** * Converts the given object to a {@code float}. * * @param obj the object to convert * @return the converted float value, or 0f if the object is {@code null} * @throws ConvertException if the object cannot be converted to a float */ public static float convertTofloat(Object obj) { if (obj == null) return 0f; if (obj instanceof Number) return ((Number) obj).floatValue(); if (obj instanceof String) return Float.parseFloat((String) obj); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to float"); } /** * Converts the given object to a {@link Byte}. * * @param obj the object to convert * @return the converted Byte, or {@code null} if the object is {@code null} * @throws ConvertException if the object cannot be converted to a Byte */ public static Float convertToFloat(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Float.class) return (Float) obj; if (obj instanceof Number) return Float.valueOf(((Number) obj).floatValue()); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to Float"); } /** * Converts the given object to a {@code double}. * * @param obj the object to convert * @return the converted double value, or 0.0 if the object is {@code null} * @throws ConvertException if the object cannot be converted to a double */ public static double convertTodouble(Object obj) { if (obj == null) return 0.0; if (obj instanceof Number) return ((Number) obj).doubleValue(); if (obj instanceof String) return Double.parseDouble((String) obj); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to float"); } /** * Converts the given object to a {@link Double}. * * @param obj the object to convert * @return the converted Double, or {@code null} if the object is {@code null} * @throws ConvertException if the object cannot be converted to a Double */ public static Double convertToDouble(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Double.class) return (Double) obj; if (obj instanceof Number) return Double.valueOf(((Number) obj).doubleValue()); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to Float"); } /** * Converts the given object to a {@code char}. * * @param obj the object to convert * @return the converted char value, or a space character if the object is {@code null} or the string is empty * @throws ConvertException if the object cannot be converted to a char */ public static char convertTochar(Object obj) { if (obj == null) return ' '; if (obj instanceof String) if (((String) obj).length() > 0) return ((String) obj).charAt(0); else return ' '; throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to char"); } /** * Converts the given object to a {@link Character}. * * @param obj the object to convert * @return the converted Character, or {@code null} if the object is {@code null} * @throws ConvertException if the object cannot be converted to a Character */ public static Character convertToChar(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Character.class) return (Character) obj; if (obj instanceof String) if (((String) obj).length() > 0) return ((String) obj).charAt(0); else return ' '; throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to Character"); } /** * Converts the given object to a {@code boolean}. * * @param obj the object to convert * @return the converted boolean value, false if the object is {@code null} or represents the numeric value 0 * @throws ConvertException if the object cannot be converted to a boolean */ public static boolean convertTobool(Object obj) { if (obj == null) return false; if (obj.getClass() == Boolean.class) return ((Boolean) obj).booleanValue(); if (obj instanceof String) return Boolean.parseBoolean((String) obj); if (obj instanceof Number) { if (obj.toString().equals("0")) return false; else return true; } throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to boolean"); } /** * Converts the given object to a {@link Boolean}. * * @param obj the object to convert * @return the converted Boolean, or {@code null} if the object is {@code null} * @throws ConvertException if the object cannot be converted to a Boolean */ public static Boolean convertToBool(Object obj) { if (obj == null) return null; Class c = obj.getClass(); if (c == Boolean.class) return (Boolean) obj; if (obj instanceof String) return Boolean.parseBoolean((String) obj); throw new ConvertException("Primitive: Can not convert " + obj.getClass().getName() + " to Boolean"); } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/DynamicClassLoader.java000066400000000000000000000055521475302255200333500ustar00rootroot00000000000000package net.minidev.asm; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.lang.reflect.Method; /** * Simple extension from ClassLoader overriding the loadClass(String name, * boolean resolve) method and allowing to register new classes * * @author uriel * */ class DynamicClassLoader extends ClassLoader { DynamicClassLoader(ClassLoader parent) { super(parent); } private final static String BEAN_AC = BeansAccess.class.getName(); /** * Predefined define defineClass method signature (name, bytes, offset, * length) */ private final static Class[] DEF_CLASS_SIG = new Class[] { String.class, byte[].class, int.class, int.class }; /** * * @param parent used to choose the ClassLoader * @param clsName C * @param clsData * @return */ public static Class directLoad(Class parent, String clsName, byte[] clsData) { DynamicClassLoader loader = new DynamicClassLoader(parent.getClassLoader()); @SuppressWarnings("unchecked") Class clzz = (Class) loader.defineClass(clsName, clsData); return clzz; } public static T directInstance(Class parent, String clsName, byte[] clsData) throws InstantiationException, IllegalAccessException { Class clzz = directLoad(parent, clsName, clsData); return clzz.newInstance(); } @Override protected synchronized java.lang.Class loadClass(String name, boolean resolve) throws ClassNotFoundException { /* * check class by fullname as String. */ if (name.equals(BEAN_AC)) return BeansAccess.class; /* * Use default class loader */ return super.loadClass(name, resolve); } /** * Call defineClass into the parent classLoader using the * method.setAccessible(boolean) hack * * @see ClassLoader#defineClass(String, byte[], int, int) */ Class defineClass(String name, byte[] bytes) throws ClassFormatError { try { // Attempt to load the access class in the same loader, which makes // protected and default access members accessible. Method method = ClassLoader.class.getDeclaredMethod("defineClass", DEF_CLASS_SIG); method.setAccessible(true); return (Class) method.invoke(getParent(), new Object[] { name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length) }); } catch (Exception ignored) { } return defineClass(name, bytes, 0, bytes.length); } } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/FieldFilter.java000066400000000000000000000013301475302255200320260ustar00rootroot00000000000000package net.minidev.asm; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * allow to control read/write access to field * */ public interface FieldFilter { /** * NOT Implemented YET * * @param field the field * @return boolean */ public boolean canUse(Field field); /** * Can the field be used * * @param field the field * @param method the method * @return boolean */ public boolean canUse(Field field, Method method); /** * NOT Implemented YET * * @param field the field * @return boolean */ public boolean canRead(Field field); /** * NOT Implemented YET * * @param field the field * @return boolean */ public boolean canWrite(Field field); } netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/ex/000077500000000000000000000000001475302255200274115ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/ex/ConvertException.java000066400000000000000000000020731475302255200335550ustar00rootroot00000000000000package net.minidev.asm.ex; /** * An exception that is thrown to indicate a problem occurred during a conversion process. * This class extends {@link RuntimeException} and is used to signify errors encountered * while converting between types, typically within a dynamic type conversion framework or library. */ public class ConvertException extends RuntimeException { private static final long serialVersionUID = 1L; /** * Constructs a new {@code ConvertException} with {@code null} as its detail message. * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}. */ public ConvertException() { super(); } /** * Constructs a new {@code ConvertException} with the specified detail message. * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}. * * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method. */ public ConvertException(String message) { super(message); } } NoSuchFieldException.java000066400000000000000000000011151475302255200342150ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/main/java/net/minidev/asm/expackage net.minidev.asm.ex; /** * Same exception as java.lang.NoSuchFieldException but extends RuntimException * * @author uriel * */ public class NoSuchFieldException extends RuntimeException { private static final long serialVersionUID = 1L; /** * default constructor */ public NoSuchFieldException() { super(); } /** * constuctor from message. * @param message the detail message. The detail message is saved for * later retrieval by the Throwable.getMessage() method. */ public NoSuchFieldException(String message) { super(message); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/000077500000000000000000000000001475302255200231065ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/000077500000000000000000000000001475302255200240275ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/com/000077500000000000000000000000001475302255200246055ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/com/mindev/000077500000000000000000000000001475302255200260675ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/com/mindev/pojos/000077500000000000000000000000001475302255200272215ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/com/mindev/pojos/AccessorTestPojo.java000066400000000000000000000012271475302255200333200ustar00rootroot00000000000000package com.mindev.pojos; public class AccessorTestPojo { // Field with only setter method @SuppressWarnings("unused") private int writeOnlyField; // Field with only getter method private int readOnlyField; // Field with both getter and setter methods private int readAndWriteableField; public void setWriteOnlyField(int writeOnlyField) { this.writeOnlyField = writeOnlyField; } public int getReadOnlyField() { return readOnlyField; } public int getReadAndWriteableField() { return readAndWriteableField; } public void setReadAndWriteableField(int readAndWriteableField) { this.readAndWriteableField = readAndWriteableField; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/000077500000000000000000000000001475302255200246155ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/000077500000000000000000000000001475302255200262505ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/000077500000000000000000000000001475302255200270305ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/ASMTest.java000066400000000000000000000055311475302255200311570ustar00rootroot00000000000000package net.minidev.asm; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashMap; import org.junit.jupiter.api.Test; import net.minidev.asm.bean.BTest; public class ASMTest { @Test public void testGet() throws Exception { // long T1; BeansAccess acBT = BeansAccess.get(BTest.class); // BeansAccess acHand = new BTestBeansAccessB(); HashMap m = new HashMap(); m.put("A", "ab"); m.put("B", "Bc"); m.put("C", "cD"); m.put("D", "de"); m.put("E", "ef"); // String clsPath = FastMap1Builder.getName(m.size()); // String clsName = clsPath.replace("/", "."); // byte[] data; // data = FastMap1Builder.dump(m.size()); // data = FastMap2Builder.dump(m); // data = FastMapTestDump.dump(clsPath); // DynamicClassLoader loader = new // DynamicClassLoader(BTest.class.getClassLoader()); // byte[] data = BTestBeansAccessDump.dump(); // Class cls = (Class) loader.defineClass(clsName, // data); // Constructor c = (Constructor) // cls.getConstructors()[0]; // FastMap f = c.newInstance(m); // f = new FastMapTest_2(m); // f = new FastMapTest_3(); // f = new FastMapTest_2(m); // f = new FastMapTest_3(); // 4 entré // map => 1.279 // fastMap => 3.323 // FastMapTest_1 3.323 // FastMapTest_2 3.323 // FastMapTest_3 0.015 // 3 entry // map => 0.983 // fastmap => 1.014 // 2 entry // map => 0,920 // fastMap => 0,608 // 7 entry // f 2.667 // m 0,640 // 6 entree // f 2.215 // m 0,608 // 4 entree // f 0.032 // m 0,593 // 5 entree // f // m 0.609 // V2 2.402 // V3 2.247 // for (int i = 0; i < 20000; i++) { // f.get("A"); // f.get("B"); // f.get("C"); // f.get("D"); // f.get("E"); // f.get("F"); // f.get("G"); // f.get("H"); // f.get("I"); // } // System.gc(); // long T = System.nanoTime(); // for (int i = 0; i < 20000000; i++) { // m.get("A"); // m.get("B"); // m.get("C"); // m.get("D"); // m.get("E"); // m.get("F"); // m.get("G"); // m.get("H"); // m.get("I"); // } // T = System.nanoTime() - T; // 10 774 968 // 596 295 451 // 2 321 087 341 BeansAccess ac; ac = acBT; // ac = acHand; // ac = acASMHand; subtext(ac); // T1 = System.currentTimeMillis(); // for (int i = 0; i < 2000000; i++) // subtext(ac); // T1 = System.currentTimeMillis() - T1; } @Test private void subtext(BeansAccess acc) { BTest t = new BTest(); acc.set(t, "pubBoolValue", true); acc.set(t, "pubIntValue", 13); acc.set(t, "pubStrValue", "Test"); acc.set(t, "privIntValue", 16); acc.set(t, "privStrValue", "test Priv"); assertEquals(Integer.valueOf(13), acc.get(t, "pubIntValue")); acc.set(t, "pubIntValue", 14); assertEquals(Integer.valueOf(14), acc.get(t, "pubIntValue")); } }netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/AccessorTest.java000066400000000000000000000051571475302255200323050ustar00rootroot00000000000000package net.minidev.asm; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.jupiter.api.Test; import com.mindev.pojos.AccessorTestPojo; public class AccessorTest { private static class AcceptAllFilter implements FieldFilter { @Override public boolean canUse(Field field) { return true; } @Override public boolean canUse(Field field, Method method) { return true; } @Override public boolean canRead(Field field) { return true; } @Override public boolean canWrite(Field field) { return true; } } private static class AcceptNoneFilter implements FieldFilter { @Override public boolean canUse(Field field) { return false; } @Override public boolean canUse(Field field, Method method) { return false; } @Override public boolean canRead(Field field) { return false; } @Override public boolean canWrite(Field field) { return false; } } @Test public void testWriteOnlyField() throws NoSuchFieldException, SecurityException { Field writeOnlyField = AccessorTestPojo.class.getDeclaredField("writeOnlyField"); Accessor accessor = new Accessor(AccessorTestPojo.class, writeOnlyField, new AcceptAllFilter()); assertTrue(accessor.isWritable()); assertFalse(accessor.isReadable()); accessor = new Accessor(AccessorTestPojo.class, writeOnlyField, new AcceptNoneFilter()); assertFalse(accessor.isWritable()); assertFalse(accessor.isReadable()); } @Test public void testReadOnlyField() throws NoSuchFieldException, SecurityException { Field readOnlyField = AccessorTestPojo.class.getDeclaredField("readOnlyField"); Accessor accessor = new Accessor(AccessorTestPojo.class, readOnlyField, new AcceptAllFilter()); assertFalse(accessor.isWritable()); assertTrue(accessor.isReadable()); accessor = new Accessor(AccessorTestPojo.class, readOnlyField, new AcceptNoneFilter()); assertFalse(accessor.isWritable()); assertFalse(accessor.isReadable()); } @Test public void testReadAndWriteableField() throws NoSuchFieldException, SecurityException { Field readAndWriteableField = AccessorTestPojo.class.getDeclaredField("readAndWriteableField"); Accessor accessor = new Accessor(AccessorTestPojo.class, readAndWriteableField, new AcceptAllFilter()); assertTrue(accessor.isWritable()); assertTrue(accessor.isReadable()); accessor = new Accessor(AccessorTestPojo.class, readAndWriteableField, new AcceptNoneFilter()); assertFalse(accessor.isWritable()); assertFalse(accessor.isReadable()); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/BTestBeansAccessB.java000066400000000000000000000116441475302255200331170ustar00rootroot00000000000000package net.minidev.asm; import net.minidev.asm.bean.BTest; import net.minidev.asm.bean.TEnum; @SuppressWarnings("rawtypes") public class BTestBeansAccessB extends BeansAccess { public BTestBeansAccessB() { Accessor[] accs = ASMUtil.getAccessors(BTest.class, null); super.setAccessor(accs); } /** * set field value by fieldname */ @Override public void set(Object object, String methodName, Object value) { if ("privIntValue".equals(methodName)) { ((BTest) object).setPrivIntValue(DefaultConverter.convertToint(value)); return; } if ("privStrValue".equals(methodName)) { if (value != null) value = value.toString(); ((BTest) object).setPrivStrValue((String) value); return; } if ("pubStrValue".equals(methodName)) { if (value != null) value = value.toString(); ((BTest) object).pubStrValue = (String) value; return; } if ("pubIntValue".equals(methodName)) { ((BTest) object).pubIntValue = DefaultConverter.convertToint(value); return; } if ("pubBoolValue".equals(methodName)) { ((BTest) object).pubBoolValue = DefaultConverter.convertTobool(value); return; } if ("pubIntegerValue".equals(methodName)) { ((BTest) object).pubIntegerValue = DefaultConverter.convertToInt(value); return; } if ("pubTEnum".equals(methodName)) { ((BTest) object).pubTEnum = TEnum.valueOf((String) value); return; } } /** * get field value by fieldname */ @Override public Object get(Object object, String methodName) { if ("privIntValue".equals(methodName)) return ((BTest) object).getPrivIntValue(); if ("privStrValue".equals(methodName)) return ((BTest) object).getPrivStrValue(); if ("pubStrValue".equals(methodName)) return ((BTest) object).pubStrValue; if ("pubIntValue".equals(methodName)) return ((BTest) object).pubIntValue; if ("privStrValue".equals(methodName)) return ((BTest) object).pubBoolValue; if ("pubIntegerValue".equals(methodName)) return ((BTest) object).pubIntegerValue; if ("pubTEnum".equals(methodName)) return ((BTest) object).pubTEnum; return null; } @Override public void set(Object object, int methodIndex, Object value) { switch (methodIndex) { case 0: // privIntValue; ((BTest) object).setPrivIntValue(((Number) value).intValue()); break; case 1: // privStrValue; ((BTest) object).setPrivStrValue((String) value); break; case 2: // pubStrValue; ((BTest) object).pubStrValue = (String) value; break; case 3: // pubIntValue; ((BTest) object).pubIntValue = ((Number) value).intValue(); break; case 4: // pubBoolValue; ((BTest) object).pubBoolValue = ((Boolean) value).booleanValue(); break; case 5: ((BTest) object).pubIntegerValue = DefaultConverter.convertToInt(value); break; case 6: ((BTest) object).pubTEnum = TEnum.valueOf((String) value); break; default: break; } } public void setInt(Object object, int methodIndex, Object value) { if (methodIndex == 0) { ((BTest) object).setPrivIntValue(((Number) value).intValue()); return; } if (methodIndex == 1) { ((BTest) object).setPrivStrValue((String) value); return; } if (methodIndex == 2) { ((BTest) object).pubStrValue = (String) value; return; } if (methodIndex == 3) { ((BTest) object).pubIntValue = ((Number) value).intValue(); return; } if (methodIndex == 4) { ((BTest) object).pubBoolValue = ((Boolean) value).booleanValue(); return; } if (methodIndex == 5) { ((BTest) object).pubBoolValue = ((Boolean) value).booleanValue(); return; } if (methodIndex == 0) { ((BTest) object).pubBoolValue = ((Boolean) value).booleanValue(); return; } if (methodIndex == 7) { ((BTest) object).pubBoolValue = ((Boolean) value).booleanValue(); return; } if (methodIndex == 8) { ((BTest) object).pubBoolValue = ((Boolean) value).booleanValue(); return; } } @Override public Object get(Object object, int methodIndex) { switch (methodIndex) { case 0: // privIntValue; return ((BTest) object).getPrivIntValue(); case 1: // privStrValue; return ((BTest) object).getPrivStrValue(); case 2: // pubStrValue; return ((BTest) object).pubStrValue; case 3: // pubIntValue; return ((BTest) object).pubIntValue; case 4: // privStrValue; return ((BTest) object).pubBoolValue; case 5: // privStrValue; return ((BTest) object).pubIntegerValue; case 6: // privStrValue; return ((BTest) object).pubTEnum; default: break; } return null; } // public Object getInt(Object object, int methodIndex) { // if (methodIndex == 0) // return ((BTest) object).getPrivIntValue(); // if (methodIndex == 1) // return ((BTest) object).getPrivStrValue(); // if (methodIndex == 2) // return ((BTest) object).pubStrValue; // if (methodIndex == 3) // return ((BTest) object).pubIntValue; // if (methodIndex == 4) // return ((BTest) object).pubBoolValue; // return null; // } @Override public Object newInstance() { return new BTest(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/TestDateConvert.java000066400000000000000000000116671475302255200327640ustar00rootroot00000000000000package net.minidev.asm; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import org.junit.jupiter.api.Test; public class TestDateConvert { // we do not test the century static TimeZone MY_TZ = TimeZone.getTimeZone("PST"); SimpleDateFormat sdfFull = new SimpleDateFormat("dd/MM/yy HH:mm:ss"); SimpleDateFormat sdfLT = new SimpleDateFormat("dd/MM/yy HH:mm"); /** * some old java version date API works differently an cause error in tests * @return */ static int getJavaVersion() { String javaVersion = System.getProperty("java.version"); // Extracting major version from java version string int majorVersion = Integer.parseInt(javaVersion.split("\\.")[1]); return majorVersion; } @Test public void testDateFR() throws Exception { String expectedDateText = "23/01/12 13:42:12"; ArrayList tests = new ArrayList(); tests.add("23 janvier 2012 13:42:12"); tests.add("lundi 23 janvier 2012 13:42:12"); tests.add("2012-01-23 13:42:12"); // need to use the same time Zone // tests.add("Thu Jan 23 13:42:12 PST 2012"); // // tests.add("Thu Jan 23 13:42:12 CET 2012"); ConvertDate.convertToDate(null); for (String testDate : tests) { String jobName = "Parsing FR Date:" + testDate; Date parsed = null; try { parsed = ConvertDate.convertToDate(testDate); } catch (Exception e) { throw new Exception(jobName, e); } assertEquals(expectedDateText, sdfFull.format(parsed), jobName); } } public TestDateConvert() { super(); ConvertDate.defaultTimeZone = MY_TZ; if (MY_TZ != null) { sdfFull.setTimeZone(MY_TZ); sdfLT.setTimeZone(MY_TZ); } } @Test public void testAdvanceTimeStamp() throws Exception { String testDate = "2014-08-27T12:53:10+02:00"; ConvertDate.convertToDate(testDate); } @Test public void testDateUS() throws Exception { testDateLocalized(Locale.US); } @Test public void testDateFRANCE() throws Exception { testDateLocalized(Locale.FRANCE); } @Test public void testDateCANADA() throws Exception { testDateLocalized(Locale.CANADA); } @Test public void testDateGERMANY() throws Exception { testDateLocalized(Locale.GERMANY); } @Test public void testDateITALY() throws Exception { testDateLocalized(Locale.ITALY); } @Test public void testDateCANADA_FRENCH() throws Exception { testDateLocalized(Locale.CANADA_FRENCH); } @Test public void testDateJAPAN() throws Exception { if (getJavaVersion() == 8) { assertTrue(true, "Ignoring Japan Date test for Java 8"); } else { testDateLocalized(Locale.JAPAN); } } // public void testDateCHINA() throws Exception { // testDateLocalized(Locale.CHINA); // } // public void testDateCHINESE() throws Exception { // testDateLocalized(Locale.CHINESE); // } // MISSING CHINA / CHINESE public void testDateLocalized(Locale locale) throws Exception { // PM test Date pm = sdfFull.parse("23/01/2012 13:42:59"); fullTestDate(pm, locale); // AM test Date am = sdfFull.parse("23/01/2012 01:42:59"); fullTestDate(am, locale); } /** * Parse all JDK DateTimeFormat */ public void fullTestDate(Date expectedDate, Locale locale) throws Exception { fullTestDate(expectedDate, locale, "SHORT", DateFormat.SHORT); fullTestDate(expectedDate, locale, "MEDIUM", DateFormat.MEDIUM); fullTestDate(expectedDate, locale, "LONG", DateFormat.LONG); fullTestDate(expectedDate, locale, "FULL", DateFormat.FULL); } public void fullTestDate(Date expectedDate, Locale locale, String sizeName, int sizeId) throws Exception { DateFormat FormatEN = DateFormat.getDateTimeInstance(sizeId, sizeId, locale); if (MY_TZ != null) { FormatEN.setTimeZone(MY_TZ); } String testDate = FormatEN.format(expectedDate); Date parse = null; String jobName = "Test date format Local:" + locale + " size:" + sizeName + " String:\"" + testDate + "\""; try { // can not parse US style Date in short mode (due to reversed day/month). if (sizeId == DateFormat.SHORT) { if (locale.equals(Locale.US)) return; if (locale.equals(Locale.CANADA_FRENCH)) return; } parse = ConvertDate.convertToDate(testDate); } catch (Exception e) { throw new Exception(jobName, e); } // System.err.println("TEST: " + testDate + " readed as: " + resultStr); // is source format contains second if (testDate.contains("59")) { String resultStr = sdfFull.format(parse); String expectedDateText = sdfFull.format(expectedDate); assertEquals(expectedDateText, resultStr, jobName); } else { String resultStr = sdfLT.format(parse); String expectedDateText = sdfLT.format(expectedDate); assertEquals(expectedDateText, resultStr, jobName); } // System.err.printf("no sec for Format %-6s %-40s -> %10s\n", sizeName, testDate, resultStr); } } TestDateConvertCustom.java000066400000000000000000000006751475302255200340750ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asmpackage net.minidev.asm; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; public class TestDateConvertCustom { /** * some JAVA version use aternative space. * @throws Exception */ @Test public void testCANADACustom() throws Exception { String testDate = "Jan 23, 2012, 1:42:59 PM"; ConvertDate.convertToDate(testDate); assertTrue(true, "parse " + testDate + " do not crash"); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/TestNewInstance.java000066400000000000000000000004311475302255200327470ustar00rootroot00000000000000package net.minidev.asm; import java.util.TreeMap; import org.junit.jupiter.api.Test; public class TestNewInstance { @Test public void testLangUtilPkg() { @SuppressWarnings("rawtypes") BeansAccess acTm = BeansAccess.get(TreeMap.class); acTm.newInstance(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/000077500000000000000000000000001475302255200277355ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BBoolPriv.java000066400000000000000000000003031475302255200324320ustar00rootroot00000000000000package net.minidev.asm.bean; public class BBoolPriv { private boolean value; public boolean isValue() { return value; } public void setValue(boolean value) { this.value = value; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BBoolPub.java000066400000000000000000000001201475302255200322350ustar00rootroot00000000000000package net.minidev.asm.bean; public class BBoolPub { public boolean value; } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BBooleanPriv.java000066400000000000000000000003071475302255200331220ustar00rootroot00000000000000package net.minidev.asm.bean; public class BBooleanPriv { private Boolean value; public Boolean getValue() { return value; } public void setValue(Boolean value) { this.value = value; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BBooleanPub.java000066400000000000000000000001231475302255200327240ustar00rootroot00000000000000package net.minidev.asm.bean; public class BBooleanPub { public Boolean value; } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BEnumPriv.java000066400000000000000000000002761475302255200324540ustar00rootroot00000000000000package net.minidev.asm.bean; public class BEnumPriv { private TEnum value; public TEnum getValue() { return value; } public void setValue(TEnum value) { this.value = value; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BEnumPrivAc.java000066400000000000000000000030671475302255200327210ustar00rootroot00000000000000package net.minidev.asm.bean; import net.minidev.asm.BeansAccess; @SuppressWarnings("rawtypes") public class BEnumPrivAc extends BeansAccess { @Override public void set(Object object, int methodIndex, Object value) { if (methodIndex == 0) { if (value != null) // value = TEnum.valueOf((String) value); value = TEnum.valueOf(value.toString()); ((BEnumPriv) object).setValue((TEnum) value); return; } throw new net.minidev.asm.ex.NoSuchFieldException("mapping BEnumPriv failed to map field:".concat(Integer.toString(methodIndex))); } @Override public Object get(Object object, int methodIndex) { if (methodIndex == 0) { return ((BEnumPriv) object).getValue(); } throw new net.minidev.asm.ex.NoSuchFieldException("mapping BEnumPriv failed to map field:".concat(Integer.toString(methodIndex))); } @Override public void set(Object object, String methodIndex, Object value) { if (methodIndex.equals("value")) { if (value != null) // value = TEnum.valueOf((String) value); value = TEnum.valueOf(value.toString()); ((BEnumPriv) object).setValue((TEnum) value); return; } throw new net.minidev.asm.ex.NoSuchFieldException("mapping BEnumPriv failed to map field:".concat(methodIndex)); } @Override public Object get(Object object, String methodIndex) { if (methodIndex.equals("value")) { return ((BEnumPriv) object).getValue(); } throw new net.minidev.asm.ex.NoSuchFieldException("mapping BEnumPriv failed to map field:".concat(methodIndex)); } @Override public Object newInstance() { return new BEnumPriv(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BEnumPub.java000066400000000000000000000001161475302255200322530ustar00rootroot00000000000000package net.minidev.asm.bean; public class BEnumPub { public TEnum value; } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BLongPriv.java000066400000000000000000000002731475302255200324440ustar00rootroot00000000000000package net.minidev.asm.bean; public class BLongPriv { private Long value; public Long getValue() { return value; } public void setValue(Long value) { this.value = value; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BLongPrivAc.java000066400000000000000000000017351475302255200327140ustar00rootroot00000000000000package net.minidev.asm.bean; import net.minidev.asm.BeansAccess; import net.minidev.asm.DefaultConverter; @SuppressWarnings("rawtypes") public class BLongPrivAc extends BeansAccess { @Override public void set(Object object, int methodIndex, Object value) { if (methodIndex == 0) { ((BLongPriv) object).setValue(DefaultConverter.convertToLong(value)); return; } } @Override public Object get(Object object, int methodIndex) { if (methodIndex == 0) { return ((BLongPriv) object).getValue(); } return null; } @Override public void set(Object object, String methodIndex, Object value) { if (methodIndex.equals("value")) { ((BLongPriv) object).setValue(DefaultConverter.convertToLong(value)); return; } } @Override public Object get(Object object, String methodIndex) { if (methodIndex.equals("value")) { return ((BLongPriv) object).getValue(); } return null; } @Override public Object newInstance() { return new BLongPriv(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BLongPub.java000066400000000000000000000001151475302255200322450ustar00rootroot00000000000000package net.minidev.asm.bean; public class BLongPub { public Long value; } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BLongPubAc.java000066400000000000000000000017111475302255200325140ustar00rootroot00000000000000package net.minidev.asm.bean; import net.minidev.asm.BeansAccess; import net.minidev.asm.DefaultConverter; @SuppressWarnings("rawtypes") public class BLongPubAc extends BeansAccess { @Override public void set(Object object, int methodIndex, Object value) { if (methodIndex == 0) { ((BLongPub) object).value = DefaultConverter.convertToLong(value); return; } } @Override public Object get(Object object, int methodIndex) { if (methodIndex == 0) { return ((BLongPub) object).value; } return null; } @Override public void set(Object object, String methodIndex, Object value) { if (methodIndex.equals("value")) { ((BLongPub) object).value = DefaultConverter.convertToLong(value); return; } } @Override public Object get(Object object, String methodIndex) { if (methodIndex.equals("value")) { return ((BLongPub) object).value; } return null; } @Override public Object newInstance() { return new BLongPub(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BObjectPriv.java000066400000000000000000000003031475302255200327450ustar00rootroot00000000000000package net.minidev.asm.bean; public class BObjectPriv { private Object value; public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BObjectPub.java000066400000000000000000000001211475302255200325510ustar00rootroot00000000000000package net.minidev.asm.bean; public class BObjectPub { public Object value; } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BStrPriv.java000066400000000000000000000003011475302255200323050ustar00rootroot00000000000000package net.minidev.asm.bean; public class BStrPriv { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BStrPrivAc.java000066400000000000000000000017501475302255200325620ustar00rootroot00000000000000package net.minidev.asm.bean; import net.minidev.asm.BeansAccess; @SuppressWarnings("rawtypes") public class BStrPrivAc extends BeansAccess { @Override public void set(Object object, int methodIndex, Object value) { if (methodIndex == 0) { if (value != null) value = value.toString(); ((BStrPriv) object).setValue((String) value); return; } } @Override public Object get(Object object, int methodIndex) { if (methodIndex == 0) { return ((BStrPriv) object).getValue(); } return null; } @Override public void set(Object object, String methodIndex, Object value) { if (methodIndex.equals("value")) { if (value != null) value = value.toString(); ((BStrPriv) object).setValue((String) value); return; } } @Override public Object get(Object object, String methodIndex) { if (methodIndex.equals("value")) { return ((BStrPriv) object).getValue(); } return null; } @Override public Object newInstance() { return new BStrPriv(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BStrPub.java000066400000000000000000000001161475302255200321170ustar00rootroot00000000000000package net.minidev.asm.bean; public class BStrPub { public String value; } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BStrPubAc.java000066400000000000000000000017231475302255200323700ustar00rootroot00000000000000package net.minidev.asm.bean; import net.minidev.asm.BeansAccess; @SuppressWarnings("rawtypes") public class BStrPubAc extends BeansAccess { @Override public void set(Object object, int methodIndex, Object value) { if (methodIndex == 0) { if (value != null) value = value.toString(); ((BStrPub)object).value = (String) value; return; } } @Override public Object get(Object object, int methodIndex) { if (methodIndex == 0) { return ((BStrPub)object).value; } return null; } @Override public void set(Object object, String methodIndex, Object value) { if (methodIndex.equals("value")) { if (value != null) value = value.toString(); ((BStrPub) object).value = (String) value; return; } } @Override public Object get(Object object, String methodIndex) { if (methodIndex.equals("value")) { return ((BStrPub) object).value; } return null; } @Override public BStrPub newInstance() { return new BStrPub(); } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/BTest.java000066400000000000000000000013361475302255200316240ustar00rootroot00000000000000package net.minidev.asm.bean; public class BTest { public int pubIntValue; public String pubStrValue; private int privIntValue; private String privStrValue; public boolean pubBoolValue; public Integer pubIntegerValue; public TEnum pubTEnum; public void setPrivIntValue(int privIntValue) { this.privIntValue = privIntValue; } public int getPrivIntValue() { return privIntValue; } public void setPrivStrValue(String privStrValue) { this.privStrValue = privStrValue; } public String getPrivStrValue() { return privStrValue; } public String toString() { return "Public(i:" + pubIntValue + " s:" + pubStrValue + "B: " + pubBoolValue + ") Private(i:" + privIntValue + " s:" + privStrValue + ")"; } } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/TEnum.java000066400000000000000000000001011475302255200316200ustar00rootroot00000000000000package net.minidev.asm.bean; public enum TEnum { V1, V2, V3 } netplex-json-smart-v2-20dff24/accessors-smart/src/test/java/net/minidev/asm/bean/TestAsmAtom.java000066400000000000000000000054421475302255200330060ustar00rootroot00000000000000package net.minidev.asm.bean; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import net.minidev.asm.BeansAccess; public class TestAsmAtom { @Test public void testpub() throws Exception { // int fieldID = 0; String fieldID = "value"; { BeansAccess ac = BeansAccess.get(BStrPub.class); BStrPub p = ac.newInstance(); String val = "toto"; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BLongPub.class); BLongPub p = ac.newInstance(); Long val = 123L; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BBooleanPub.class); BBooleanPub p = ac.newInstance(); Boolean val = Boolean.TRUE; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BBoolPub.class); BBoolPub p = ac.newInstance(); Boolean val = Boolean.TRUE; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BEnumPriv.class); BEnumPriv p = ac.newInstance(); TEnum val = TEnum.V2; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BObjectPriv.class); BObjectPriv p = ac.newInstance(); TEnum val = TEnum.V2; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } } public void testPriv() throws Exception { // int fieldID = 0; String fieldID = "value"; { BeansAccess ac = BeansAccess.get(BStrPriv.class); BStrPriv p = ac.newInstance(); String val = "toto"; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BLongPriv.class); BLongPriv p = ac.newInstance(); Long val = 123L; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BBooleanPriv.class); BBooleanPriv p = ac.newInstance(); Boolean val = Boolean.TRUE; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BBoolPriv.class); BBoolPriv p = ac.newInstance(); Boolean val = Boolean.TRUE; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BEnumPub.class); BEnumPub p = ac.newInstance(); TEnum val = TEnum.V2; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } { BeansAccess ac = BeansAccess.get(BObjectPub.class); BObjectPub p = ac.newInstance(); TEnum val = TEnum.V2; ac.set(p, fieldID, val); assertEquals(val, ac.get(p, fieldID)); } } }netplex-json-smart-v2-20dff24/json-smart-action/000077500000000000000000000000001475302255200215775ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/.gitignore000066400000000000000000000000111475302255200235570ustar00rootroot00000000000000/target/ netplex-json-smart-v2-20dff24/json-smart-action/pom.xml000066400000000000000000000272621475302255200231250ustar00rootroot00000000000000 4.0.0 net.minidev json-smart-action 2.5.2 JSON-smart-action Small and Fast Parser JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language. bundle https://urielch.github.io/ Chemouni Uriel https://urielch.github.io/ uriel Uriel Chemouni uchemouni@gmail.com GMT+1 erav Eitan Raviv adoneitan@gmail.com GMT+2 hezhangjian Zhangjian He hezhangjian97gmail.com GMT+8 The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo All files under Apache 2 UTF-8 10 1.8 1.8 5.11.4 scm:git:https://github.com/netplex/json-smart-v2.git scm:git:https://github.com/netplex/json-smart-v2.git https://github.com/netplex/json-smart-v2 ossrh https://s01.oss.sonatype.org/content/repositories/snapshots ossrh https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ release-sign-artifacts performRelease true 53BE126D org.apache.maven.plugins maven-gpg-plugin 3.2.7 sign-artifacts verify sign org.apache.maven.plugins maven-javadoc-plugin 3.11.2 8 attach-javadocs jar org.apache.maven.plugins maven-release-plugin 3.1.1 forked-path -Psonatype-oss-release false false release deploy include-sources / true src/main/java **/*.java org.apache.maven.plugins maven-source-plugin 3.3.1 bind-sources jar-no-fork org.apache.maven.plugins maven-compiler-plugin 3.13.0 UTF-8 ${maven.compiler.source} ${maven.compiler.target} org.apache.maven.plugins maven-resources-plugin 3.3.1 UTF-8 org.apache.maven.plugins maven-jar-plugin 3.4.2 org.apache.maven.plugins maven-javadoc-plugin 3.11.2 8 false attach-javadocs jar org.apache.felix maven-bundle-plugin 5.1.9 true ${project.groupId}.${project.artifactId} ${project.artifactId} ${project.version} net.minidev.json.actions, net.minidev.json.actions.navigate, net.minidev.json.actions.path, net.minidev.json.actions.traverse org.junit.jupiter junit-jupiter-api ${junit.version} test org.junit.jupiter junit-jupiter-params ${junit.version} test net.minidev json-smart 2.5.2 netplex-json-smart-v2-20dff24/json-smart-action/src/000077500000000000000000000000001475302255200223665ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/000077500000000000000000000000001475302255200233125ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/000077500000000000000000000000001475302255200242335ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/000077500000000000000000000000001475302255200250215ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/000077500000000000000000000000001475302255200264545ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/000077500000000000000000000000001475302255200274255ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/000077500000000000000000000000001475302255200310655ustar00rootroot00000000000000ElementRemover.java000066400000000000000000000031301475302255200345770ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actionspackage net.minidev.json.actions; import net.minidev.json.JSONObject; import net.minidev.json.actions.traverse.JSONTraverser; import net.minidev.json.actions.traverse.RemoveElementsJsonAction; import net.minidev.json.actions.traverse.JSONTraverseAction; import java.util.*; /** * Removes key:value elements from every node of a {@link JSONObject} matching the list of user-specified elements. *

* An element to remove must be specified as a key:value pair *

* Usage Example: *

* To remove the element k2:v2 from the {@link JSONObject} {k0:{k2:v2, k3:v3}, k1:{k2:v2, k4:v4}} use the remover like so: *

 * PathRemover pr = new PathRemover("k2.v2");
 * JSONObject cleanObject = pr.remove(new JSONObject(...));
 * 
* The resulting object 'cleanObject' would be {k0:{k3:v3}, k1:{k4:v4}} *

* See unit tests for more examples * * @author adoneitan@gmail.com * */ public class ElementRemover { private Map elementsToRemove; public ElementRemover(Map elementsToRemove) { this.elementsToRemove = elementsToRemove == null ? Collections. emptyMap() : elementsToRemove; } public ElementRemover(JSONObject elementsToRemove) { this.elementsToRemove = elementsToRemove == null ? Collections. emptyMap() : elementsToRemove; } public JSONObject remove(JSONObject objectToClean) { JSONTraverseAction strategy = new RemoveElementsJsonAction(this.elementsToRemove); JSONTraverser traversal = new JSONTraverser(strategy); traversal.traverse(objectToClean); return (JSONObject) strategy.result(); } } PathLocator.java000066400000000000000000000044361475302255200341000ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actionspackage net.minidev.json.actions; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.path.DotDelimiter; import net.minidev.json.actions.path.PathDelimiter; import net.minidev.json.actions.traverse.JSONTraverser; import net.minidev.json.actions.traverse.LocatePathsJsonAction; import net.minidev.json.actions.traverse.JSONTraverseAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * Searches for paths in a {@link JSONObject} and returns those found. *

* Traverses the specified {@link JSONObject} searching for nodes whose paths (from the root down) match * any of the user-specified paths. The paths that match are returned. *

* A path to locate must be specified in the n-gram format - a list of keys from the root down separated by dots: * K0[[[[.K1].K2].K3]...] *
* A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in their name are * not supported. *

* * @author adoneitan@gmail.com */ public class PathLocator { protected List pathsToFind; protected PathDelimiter pathDelimiter = new DotDelimiter().withAcceptDelimiterInNodeName(false); public PathLocator(JSONArray pathsToFind) { if (pathsToFind == null || pathsToFind.isEmpty()) { this.pathsToFind = Collections.emptyList(); } else { this.pathsToFind = new ArrayList(); for (Object s : pathsToFind) { this.pathsToFind.add((String) s); } } } public PathLocator(List pathsToFind) { this.pathsToFind = pathsToFind == null || pathsToFind.size() == 0 ? Collections. emptyList() : pathsToFind; } public PathLocator(String... pathsToFind) { this.pathsToFind = pathsToFind == null || pathsToFind.length == 0 ? Collections. emptyList() : Arrays.asList(pathsToFind); } public PathLocator with(PathDelimiter pathDelimiter) { this.pathDelimiter = pathDelimiter; return this; } @SuppressWarnings("unchecked") public List locate(JSONObject object) { JSONTraverseAction action = new LocatePathsJsonAction(this.pathsToFind, pathDelimiter); JSONTraverser traversal = new JSONTraverser(action).with(pathDelimiter); traversal.traverse(object); return (List) action.result(); } } PathRemover.java000066400000000000000000000042621475302255200341110ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actionspackage net.minidev.json.actions; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.traverse.JSONTraverser; import net.minidev.json.actions.traverse.RemovePathsJsonAction; import net.minidev.json.actions.traverse.JSONTraverseAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * Removes branches of nodes from a {@link JSONObject} matching the list of user-specified paths. *

* A path to remove must be specified in the n-gram format - a list of keys from the root down separated by dots: * K0[[[[.K1].K2].K3]...] *
* A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in their name are * not supported. *

* Usage Example: *

* To remove the field k1.k2 from the {@link JSONObject} {k1:{k2:v2}, k3:{k4:v4}} use the remover like so: *

 * PathRemover pr = new PathRemover("k1.k2");
 * JSONObject cleanObject = pr.remove(new JSONObject(...));
 * 
* The resulting object 'cleanObject' would be {k1:{k3:{k4:v4}}} *

* See unit tests for more examples * * @author adoneitan@gmail.com * */ public class PathRemover { protected List pathsToRemove; public PathRemover(JSONArray pathsToRemove) { if (pathsToRemove == null || pathsToRemove.isEmpty()) { this.pathsToRemove = Collections.emptyList(); } else { this.pathsToRemove = new ArrayList(); for (Object s : pathsToRemove) { this.pathsToRemove.add((String) s); } } } public PathRemover(List pathsToRemove) { this.pathsToRemove = pathsToRemove == null || pathsToRemove.size() == 0 ? Collections. emptyList() : pathsToRemove; } public PathRemover(String... pathsToRemove) { this.pathsToRemove = pathsToRemove == null || pathsToRemove.length == 0 ? Collections. emptyList() : Arrays.asList(pathsToRemove); } public JSONObject remove(JSONObject objectToClean) { JSONTraverseAction strategy = new RemovePathsJsonAction(this.pathsToRemove); JSONTraverser traversal = new JSONTraverser(strategy); traversal.traverse(objectToClean); return (JSONObject) strategy.result(); } } PathReplicator.java000066400000000000000000000044511475302255200345760ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actionspackage net.minidev.json.actions; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.navigate.CopyPathsAction; import net.minidev.json.actions.navigate.JSONNavigator; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * Creates a copy of a {@link JSONObject} consisting only of the nodes on the user-specified paths. *

* Paths that do not exist in the specified object are ignored silently. Specifying an empty list of paths * to copy or only non-existent paths will result in an empty object being returned. *

* A path to copy must be specified in the n-gram format - a list of keys from the root down separated by dots: * K0[[[[.K1].K2].K3]...] *
* A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in their name are * not supported. *

* Sample usage: *

* To replicate the branch k1.k2 from {k1:{k2:v2}, k3:{k4:v4}} use the {@link PathReplicator} like so: *

 * PathReplicator pr = new {@link PathReplicator}("k1.k2")
 * JSONObject copiedObject = pr.copy(new JSONObject(...))
 * 
* The resulting object 'copiedObject' would be {k1:{k2:v2}} *

* see unit tests for more examples * * @author adoneitan@gmail.com * @since 15 March 2016. */ public class PathReplicator { protected List pathsToCopy; public PathReplicator(JSONArray pathsToCopy) { if (pathsToCopy == null || pathsToCopy.isEmpty()) { this.pathsToCopy = Collections.emptyList(); } else { this.pathsToCopy = new LinkedList(); for (Object s : pathsToCopy) { this.pathsToCopy.add((String) s); } } } public PathReplicator(List pathsToCopy) { this.pathsToCopy = pathsToCopy == null || pathsToCopy.size() == 0 ? Collections. emptyList() : pathsToCopy; } public PathReplicator(String... pathsToCopy) { this.pathsToCopy = pathsToCopy == null || pathsToCopy.length == 0 ? Collections. emptyList() : new LinkedList(Arrays.asList(pathsToCopy)); } public JSONObject replicate(JSONObject sourceObj) throws Exception { CopyPathsAction s = new CopyPathsAction(); JSONNavigator n = new JSONNavigator(s, pathsToCopy); n.nav(sourceObj); return (JSONObject) s.result(); } } PathsRetainer.java000066400000000000000000000063171475302255200344310ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actionspackage net.minidev.json.actions; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.path.DotDelimiter; import net.minidev.json.actions.path.PathDelimiter; import net.minidev.json.actions.traverse.JSONTraverseAction; import net.minidev.json.actions.traverse.JSONTraverser; import net.minidev.json.actions.traverse.LocatePathsJsonAction; import net.minidev.json.actions.traverse.RetainPathsJsonAction; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * Retains branches of nodes of a {@link JSONObject} matching the list of user-specified paths. *

* A path to copy must be specified in the n-gram format - a list of keys from the root down separated by dots: * K0[[[[.K1].K2].K3]...] *
* A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in their name are * not supported. *

* Example: *

* to retain the field k1.k2 in the {@link JSONObject} {k1:{k2:v1}, k3:{k4:v2}} instantiate the retainer like so: * new JSONObjectCleaner("k1.k2") * The resulting object would be {k1:{k2:v1}} *

* See unit tests in JSONObjectRetainerTest for more examples * * @author adoneitan@gmail.com */ public class PathsRetainer { protected List pathsToRetain; protected PathDelimiter pathDelimiter = new DotDelimiter().withAcceptDelimiterInNodeName(false); public PathsRetainer(JSONArray pathsToRetain) { if (pathsToRetain == null || pathsToRetain.isEmpty()) { this.pathsToRetain = Collections.emptyList(); } else { this.pathsToRetain = new LinkedList(); for (Object s : pathsToRetain) { this.pathsToRetain.add((String) s); } } } public PathsRetainer(List pathsToRetain) { this.pathsToRetain = pathsToRetain == null || pathsToRetain.size() == 0 ? Collections. emptyList() : pathsToRetain; } public PathsRetainer(String... pathsToRetain) { this.pathsToRetain = pathsToRetain == null || pathsToRetain.length == 0 ? Collections. emptyList() : new LinkedList(Arrays.asList(pathsToRetain)); } public PathsRetainer with(PathDelimiter pathDelimiter) { this.pathDelimiter = pathDelimiter; return this; } @SuppressWarnings("unchecked") public JSONObject retain(JSONObject object) { /** * a path to retain which contains a path in the object, but is not itself a path in the object, * will cause the sub-path to be retained although it shouldn't: * object = {k0:v0} retain = {k0.k1} * so the false path to retain has to be removed from the pathsToRetain list. * * The {@link LocatePathsJsonAction} returns only paths which exist in the object. */ JSONTraverseAction locateAction = new LocatePathsJsonAction(pathsToRetain, pathDelimiter); JSONTraverser t1 = new JSONTraverser(locateAction); t1.traverse(object); List realPathsToRetain = (List) locateAction.result(); //now reduce the object using only existing paths JSONTraverseAction retainer = new RetainPathsJsonAction(realPathsToRetain, pathDelimiter); JSONTraverser t2 = new JSONTraverser(retainer).with(pathDelimiter); t2.traverse(object); return (JSONObject) retainer.result(); } } netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/navigate/000077500000000000000000000000001475302255200326635ustar00rootroot00000000000000CopyPathsAction.java000066400000000000000000000064701475302255200365260ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/navigatepackage net.minidev.json.actions.navigate; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.path.TreePath; import java.util.Collection; import java.util.Stack; /** * Creates a copy of a {@link JSONObject} containing just the nodes on the paths specified. *

* Specified paths that do not exist in the source object are ignored silently. * Specifying an empty list of paths to navigate or only non-existent paths will result in an empty * object being returned. *

* See package-info for more details *

* Example: *

* To copy the branch k1.k2 from {k1:{k2:v1}, k3:{k4:v2}} instantiate the copier like so: * new JSONObjectCopier("k1.k2") * The resulting copy would be {k1:{k2:v1}} *

* See unit tests for more examples * * @author adoneitan@gmail.com * @since 15 March 2016. * */ public class CopyPathsAction implements JSONNavigateAction { protected JSONObject destTree; protected JSONObject destBranch; protected Stack destNodeStack; @Override public boolean start(JSONObject source, Collection pathsToCopy) { if (source == null) { destTree = null; return false; } destTree = new JSONObject(); if (pathsToCopy == null || pathsToCopy.size() == 0) { return false; } return true; } @Override public boolean recurInto(TreePath jp, JSONObject o) { //reached JSONObject node - instantiate it and recur handleNewNode(jp, new JSONObject()); return true; } private void handleNewNode(TreePath jp, Object node) { if (!jp.hasPrev()) { return; } if (destNodeStack.peek() instanceof JSONObject) { ((JSONObject) destNodeStack.peek()).put(jp.curr(), node); } else if (destNodeStack.peek() instanceof JSONArray) { ((JSONArray) destNodeStack.peek()).add(node); } destNodeStack.push(node); } @Override public boolean recurInto(TreePath jp, JSONArray o) { //reached JSONArray node - instantiate it and recur handleNewNode(jp, new JSONArray()); return true; } @Override public void foundLeafBeforePathEnd(TreePath jp, Object obj) { throw new IllegalArgumentException("branch is shorter than path - path not found in source: '" + jp.origin() + "'"); } @Override public void pathTailNotFound(TreePath jp, Object source) { throw new IllegalArgumentException("cannot find next element of path - path not found in source: '" + jp.origin() + "'"); } @Override public void handleLeaf(TreePath jp, Object o) { ((JSONObject) destNodeStack.peek()).put(jp.curr(), o); } @Override public void handleLeaf(TreePath jp, int arrIndex, Object o) { ((JSONArray) destNodeStack.peek()).add(o); } @Override public void recurEnd(TreePath jp, JSONObject jo) { destNodeStack.pop(); } @Override public void recurEnd(TreePath jp, JSONArray ja) { destNodeStack.pop(); } @Override public boolean pathStart(String path) { destBranch = new JSONObject(); destNodeStack = new Stack(); destNodeStack.push(destBranch); return true; } @Override public void pathEnd(String path) { destTree.merge(destBranch); } @Override public boolean failSilently(String path, Exception e) { return false; } @Override public boolean failFast(String path, Exception e) { return false; } @Override public void end() { } @Override public Object result() { return destTree; } } JSONNavigateAction.java000066400000000000000000000006451475302255200370420ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/navigatepackage net.minidev.json.actions.navigate; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; /** * An interface for a processing action on the nodes of a {@link JSONObject} while navigating its branches. *

* See package-info for more details * * @author adoneitan@gmail.com * @since 15 June 2016. */ public interface JSONNavigateAction extends NavigateAction { } JSONNavigator.java000066400000000000000000000010021475302255200360640ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/navigatepackage net.minidev.json.actions.navigate; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import java.util.List; /** * @author adoneitan@gmail.com * @since 15 June 2016. */ public class JSONNavigator extends TreeNavigator { public JSONNavigator(JSONNavigateAction action, List pathsToNavigate) { super(action, pathsToNavigate); } public JSONNavigator(JSONNavigateAction action, String... pathsToNavigate) { super(action, pathsToNavigate); } } NavigateAction.java000066400000000000000000000067571475302255200363620ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/navigatepackage net.minidev.json.actions.navigate; import net.minidev.json.actions.path.TreePath; import java.util.Collection; import java.util.List; import java.util.Map; /** * An interface for a processing action on the nodes of a {@link M} while navigating its branches. *

* See package-info for more details * * @author adoneitan@gmail.com * @since 15 June 2016 */ public interface NavigateAction, L extends List> { /** * called before navigation of a new path starts * @param path TODO * @return true if the specified path should be navigated */ boolean pathStart(String path); /** * called before any navigation of the {@link M} starts * * @param objectToNavigate TODO * @param pathsToNavigate TODO * * @return true if navigation should start at all */ boolean start(M objectToNavigate, Collection pathsToNavigate); /** * reached end of branch in source before end of specified path - * the specified path does not exist in the source * * @param tp TODO * @param source TODO */ void pathTailNotFound(TreePath tp, Object source); /** * called after the navigation of a path ends * * @param path TODO */ void pathEnd(String path); /** * called if navigation of a path throws an exception * * @param path TODO * @param e TODO * @return true if the failure on this path should not abort the rest of the navigation */ boolean failSilently(String path, Exception e); /** * called if navigation of a path throws an exception * * @param path TODO * @param e TODO * @return true if the failure on this path should abort the rest of the navigation */ boolean failFast(String path, Exception e); /** * called when an object node is encountered on the path * * @param tp TODO * @param sourceNode TODO * @return true if the navigator should navigate into the object */ boolean recurInto(TreePath tp, M sourceNode); /** * called when an array node is encountered on the path * * @param tp TODO * @param sourceNode TODO * @return true if the navigator should navigate into the array */ boolean recurInto(TreePath tp, L sourceNode); /** * reached leaf node (not a container) in source but specified path expects children - * the specified path does not exist in the source * @param jp TODO * @param obj TODO */ void foundLeafBeforePathEnd(TreePath jp, Object obj); /** * called when a leaf node is reached in a M. * a leaf in a M is a key-value pair where the value is not a container itself * (it is not a M nor a L) * @param tp - the JsonPath pointing to the leaf * @param value TODO */ void handleLeaf(TreePath tp, Object value); /** * called when a leaf in a L is reached. * a leaf in a L is a non-container item * (it is not a M nor a L) * @param tp - * @param arrIndex - * @param arrItem - the item */ void handleLeaf(TreePath tp, int arrIndex, Object arrItem); /** * called when navigation of an {@link M} type object ends * @param tp the path pointing to the object * @param m TODO */ void recurEnd(TreePath tp, M m); /** * called when navigation of an {@link L} type object ends * @param tp the path pointing to the object * @param l TODO */ void recurEnd(TreePath tp, L l); /** * called after all navigation ends, and just before the navigation method exits */ void end(); /** * holds the result of the navigation, as assigned by the action implementing this interface * @return - result */ Object result(); } TreeNavigator.java000066400000000000000000000103041475302255200362170ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/navigatepackage net.minidev.json.actions.navigate; import net.minidev.json.JSONObject; import net.minidev.json.actions.path.DotDelimiter; import net.minidev.json.actions.path.TreePath; import java.util.Arrays; import java.util.List; import java.util.Map; /** * Navigates only the branches of a {@link JSONObject} corresponding to the paths specified. *

* For each specified path to navigate, the {@link TreeNavigator} only traverses the matching * branch. *

* The navigator accepts an action and provides callback hooks for it to act on the traversed * nodes at each significant step. See {@link NavigateAction}. *

* See package-info for more details *

* Example: *

* To navigate the branch k1.k2 of the object {"k1":{"k2":"v1"}, "k3":{"k4":"v2"}} instantiate * the navigator like so: new JSONNavigator("k1.k2") * * @author adoneitan@gmail.com * @since 15 June 2016. * */ public class TreeNavigator, L extends List> { protected List pathsToNavigate; protected NavigateAction action; protected String pathPrefix = ""; public TreeNavigator(NavigateAction action, List pathsToNavigate) { if (action == null) { throw new IllegalArgumentException("NavigateAction cannot be null"); } this.action = action; this.pathsToNavigate = pathsToNavigate; } public TreeNavigator with(String pathPrefix) { this.pathPrefix = pathPrefix; return this; } public TreeNavigator(NavigateAction action, String... pathsToNavigate) { this(action, Arrays.asList(pathsToNavigate)); } public void nav(M object) throws Exception { if (action.start(object, pathsToNavigate)) { for (String path : pathsToNavigate) { try { if (path != null && !path.equals("") && action.pathStart(path)) { TreePath jp = new TreePath(path, new DotDelimiter().withAcceptDelimiterInNodeName(true)); nav(jp, object); action.pathEnd(path); } } catch (Exception e) { if (action.failSilently(path, e)) { break; } else if (action.failFast(path, e)) { throw e; } } } } action.end(); } @SuppressWarnings("unchecked") public void nav(TreePath jp, M map) { if (map == null || !action.recurInto(jp, map)) { //source is null - navigation impossible return; } if (jp.hasNext()) { String key = jp.next(); if (!map.containsKey(key)) { // cannot find next element of path in the source - // the specified path does not exist in the source action.pathTailNotFound(jp, map); } else if (map.get(key) instanceof Map) { //reached Map type node - handle it and recur into it nav(jp, (M) map.get(key)); } else if (map.get(key) instanceof List) { //reached List type node - handle it and recur into it nav(jp, (L) map.get(key)); } else if (jp.hasNext()) { // reached leaf node (not a container) in source but specified path expects children - // the specified path is illegal because it does not exist in the source. action.foundLeafBeforePathEnd(jp, map.get(key)); } else if (!jp.hasNext()) { //reached leaf in source and specified path is also at leaf -> handle it action.handleLeaf(jp, map.get(key)); } else { throw new IllegalStateException("fatal: unreachable code reached at '" + jp.origin() + "'"); } } action.recurEnd(jp, (M) map); } @SuppressWarnings("unchecked") public void nav(TreePath jp, L list) { if (list == null || !action.recurInto(jp, (L) list)) { //list is null - navigation impossible return; } int arrIndex = 0; for (Object arrItem : list.toArray()) { if (arrItem instanceof Map) { // clone the path so that for each object in the array, // the iterator continues from the same position in the path TreePath jpClone = getClone(jp); nav(jpClone, (M) arrItem); } else if (arrItem instanceof List) { nav(jp, (L) arrItem); } else if (!jp.hasNext()) { //reached leaf - handle it action.handleLeaf(jp, arrIndex, arrItem); } arrIndex++; } action.recurEnd(jp, (L) list); } private TreePath getClone(TreePath jp) { try { return jp.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException("failed to clone path", e); } } } package-info.java000066400000000000000000000023561475302255200360010ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/navigate/** * Navigate user-specified paths in a tree made up of {@link java.util.Map}s and {@link java.util.List} and process them *

* {@link net.minidev.json.actions.navigate.TreeNavigator} only navigates through branches corresponding * to user-specified paths. For each path, the navigation starts at the root and moves down the branch. *

* The {@link net.minidev.json.actions.navigate.TreeNavigator} accepts a * {@link net.minidev.json.actions.navigate.NavigateAction} and provides callback hooks at each significant * step which the {@link net.minidev.json.actions.navigate.NavigateAction} may use to process * the nodes. *

* A path to navigate must be specified in the n-gram format - a list of keys from the root down separated by dots: * K0[[[[.K1].K2].K3]...] *
* A key to the right of a dot is a direct child of a key to the left of a dot. Keys with a dot in their name are * not supported. *

* Sample usage: *

 * NavigateAction navAction = new NavigateAction(){...};
 * JSONNavigator jsonNav = new JSONNavigator(navAction, "foo.bar.path");
 * jsonNav.nav(new JSONObject(...));
 * Object result = navAction.result();
 * 
* * @author adoneitan@gmail.com */ package net.minidev.json.actions.navigate;netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/path/000077500000000000000000000000001475302255200320215ustar00rootroot00000000000000DotDelimiter.java000066400000000000000000000006611475302255200351750ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/pathpackage net.minidev.json.actions.path; /** * Encapsulates the delimiter '.' of the path parts when the path is specified in n-gram format. * For example: root.node1.node11.leaf * * @author adoneitan@gmail.com * @since 31 May2016 */ public class DotDelimiter extends PathDelimiter { protected static final char DELIM_CHAR = '.'; public DotDelimiter() { super(DELIM_CHAR); } public String regex() { return "\\."; } } PathDelimiter.java000066400000000000000000000014551475302255200353450ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/pathpackage net.minidev.json.actions.path; /** * Encapsulates the delimiter of the path parts when given in n-gram format. * * @author adoneitan@gmail.com * @since 31 May 2016 */ public abstract class PathDelimiter { protected char delimChar; protected String delimStr; protected boolean acceptDelimInKey; public PathDelimiter(char delim) { this.delimChar = delim; this.delimStr = String.valueOf(delim); } public PathDelimiter withAcceptDelimiterInNodeName(boolean acceptDelimInKey) { this.acceptDelimInKey = acceptDelimInKey; return this; } public boolean accept(String key) { if (!acceptDelimInKey && key.contains(delimStr)) return false; return true; } public String str() { return delimStr; } public char chr() { return delimChar; } public abstract String regex(); } SlashDelimiter.java000066400000000000000000000007441475302255200355230ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/pathpackage net.minidev.json.actions.path; /** * Encapsulates the delimiter '.' of the path parts when the path is specified in n-gram format. * For example: root.node1.node11.leaf * * @author adoneitan@gmail.com * @since 31 May 2016 */ public class SlashDelimiter extends PathDelimiter { protected static final char DELIM_CHAR = '/'; public SlashDelimiter() { super(DELIM_CHAR); super.withAcceptDelimiterInNodeName(false); } public String regex() { return "\\/"; } } TreePath.java000066400000000000000000000132001475302255200343150ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/pathpackage net.minidev.json.actions.path; import java.util.Arrays; import java.util.Map; import java.util.List; import java.util.ListIterator; /** * {@link TreePath} represents an n-gram formatted path * corresponding to a branch in a tree of {@link Map}s * and {@link List}s *

* See package-info for more details * * @author adoneitan@gmail.com */ public class TreePath { protected enum Step { NONE, NEXT, PREV } protected final String path; protected List keys; protected ListIterator keysItr; protected String currKey; protected Step lastStep; protected StringBuilder origin; protected StringBuilder remainder; protected PathDelimiter delim; public TreePath(String path, PathDelimiter delim) { this.delim = delim; checkPath(path); this.path = path; this.keys = Arrays.asList(path.split(delim.regex())); reset(); } public void reset() { keysItr = keys.listIterator(); currKey = ""; lastStep = Step.NONE; origin = new StringBuilder(""); remainder = new StringBuilder(path); } public boolean hasNext() { return keysItr.hasNext(); } public int nextIndex() { return keysItr.nextIndex(); } public String next() { currKey = keysItr.next(); /** when changing direction the {@link ListIterator} does not really * move backward so an extra step is performed */ if (!lastStep.equals(Step.PREV)) { originIncrement(); remainderDecrement(); } lastStep = Step.NEXT; return currKey; } public boolean hasPrev() { return keysItr.hasPrevious(); } public int prevIndex() { return keysItr.previousIndex(); } public String prev() { String temp = currKey; currKey = keysItr.previous(); /** when changing direction the {@link ListIterator} does not really * move backward so an extra step is performed */ if (!lastStep.equals(Step.NEXT)) { remainderIncrement(temp); originDecrement(); } lastStep = Step.PREV; return currKey; } private void remainderDecrement() { if (length() == 1) remainder = new StringBuilder(""); else if (remainder.indexOf(delim.str()) < 0) remainder = new StringBuilder(""); else remainder.delete(0, remainder.indexOf(delim.str()) + 1); } private void originDecrement() { if (length() == 1) origin = new StringBuilder(""); else if (origin.indexOf(delim.str()) < 0) origin = new StringBuilder(""); else origin.delete(origin.lastIndexOf(delim.str()), origin.length()); } private void originIncrement() { if (origin.length() != 0) { origin.append(delim.chr()); } origin.append(currKey); } private void remainderIncrement(String prev) { if (remainder.length() == 0) remainder = new StringBuilder(prev); else remainder = new StringBuilder(prev).append(delim.chr()).append(remainder); } /** * @return An n-gram path from the first key to the current key (inclusive) */ public String path() { return path; } /** * @return An n-gram path from the first key to the current key (inclusive) */ public String origin() { return origin.toString(); } /** * @return An n-gram path from the current key to the last key (inclusive) */ public String remainder() { return remainder.toString(); } /** * @return first element in the JSONPath */ public String first() { return keys.get(0); } /** * @return last element in the JSONPath */ public String last() { return keys.get(keys.size() - 1); } /** * @return current element pointed to by the path iterator */ public String curr() { return currKey; } public int length() { return keys.size(); } public String subPath(int firstIndex, int lastIndex) { if (lastIndex < firstIndex) { throw new IllegalArgumentException("bad call to subPath"); } StringBuilder sb = new StringBuilder(path.length()); for (int i = firstIndex; i <= lastIndex; i++) { sb.append(keys.get(i)); if (i < lastIndex) { sb.append(delim.chr()); } } sb.trimToSize(); return sb.toString(); } private void checkPath(String path) { if (path == null || path.equals("")) throw new IllegalArgumentException("path cannot be null or empty"); if (path.startsWith(delim.str()) || path.endsWith(delim.str()) || path.contains(delim.str() + delim.str())) throw new IllegalArgumentException(String.format("path cannot start or end with %s or contain '%s%s'", delim.str(), delim.str(), delim.str())); } @Override public TreePath clone() throws CloneNotSupportedException { TreePath cloned = new TreePath(this.path, this.delim); while (cloned.nextIndex() != this.nextIndex()) { cloned.next(); } if (cloned.prevIndex() != this.prevIndex()) { cloned.prev(); } cloned.lastStep = this.lastStep; cloned.currKey = new String(this.currKey); cloned.origin = new StringBuilder(this.origin); cloned.remainder = new StringBuilder(this.remainder); return cloned; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TreePath treePath = (TreePath) o; return path().equals(treePath.path()) && hasNext() == treePath.hasNext() && hasPrev() == treePath.hasPrev() && curr().equals(treePath.curr()) && origin().equals(treePath.origin()) && remainder().equals(treePath.remainder()) && lastStep == treePath.lastStep && delim.equals(treePath.delim); } @Override public int hashCode() { int result = path.hashCode(); result = 31 * result + keys.hashCode(); result = 31 * result + keysItr.hashCode(); result = 31 * result + currKey.hashCode(); result = 31 * result + lastStep.hashCode(); result = 31 * result + origin.hashCode(); result = 31 * result + remainder.hashCode(); result = 31 * result + delim.hashCode(); return result; } } netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traverse/000077500000000000000000000000001475302255200327205ustar00rootroot00000000000000JSONTraverseAction.java000066400000000000000000000006061475302255200371310ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; /** * An interface for a processing action on the nodes of a {@link JSONObject} while traversing it. *

* See package-info for more details * * @author adoneitan@gmail.com */ public interface JSONTraverseAction extends TreeTraverseAction { } JSONTraverser.java000066400000000000000000000016511475302255200361560ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.path.DotDelimiter; import net.minidev.json.actions.path.PathDelimiter; /** * Traverses every node of a {@link JSONObject} *

* {@link JSONTraverser} accepts an action and provides callback hooks for it to act * on the traversed nodes at each significant step. See {@link JSONTraverseAction}. *

* A key to the right of a dot is a direct child of a key to the left of a dot. * Keys with a dot in their name are not supported. *

* See package-info for more details * * @author adoneitan@gmail.com * */ public class JSONTraverser extends TreeTraverser { public JSONTraverser(JSONTraverseAction action) { super(action, new DotDelimiter()); } public JSONTraverser with(PathDelimiter delim) { super.delim = delim; return this; } } KeysPrintAction.java000066400000000000000000000021161475302255200365720ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import java.util.Map.Entry; /** * @author adoneitan@gmail.com * @since 5/24/16. */ public class KeysPrintAction implements JSONTraverseAction { @Override public boolean start(JSONObject object) { return true; } @Override public boolean traverseEntry(String fullPathToEntry, Entry entry) { // System.out.println(entry.getKey()); return true; } @Override public boolean recurInto(String pathToEntry, JSONObject entryValue) { return true; } @Override public boolean recurInto(String pathToEntry, JSONArray entryValue) { return true; } @Override public void handleLeaf(String pathToEntry, Entry entry) { } @Override public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) { } @Override public boolean removeEntry(String fullPathToEntry, Entry entry) { return false; } @Override public void end() { } @Override public Object result() { return null; } } LocatePathsJsonAction.java000066400000000000000000000044131475302255200377050ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.path.PathDelimiter; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; /** * Searches for paths in a {@link JSONObject} and returns those found *

* A path is not removed from the user-specified list once its processing is over, * because identical objects in the same array are supported by this action. *

* See package-info for more details *

* See unit tests for examples * * @author adoneitan@gmail.com * */ public class LocatePathsJsonAction implements JSONTraverseAction { protected List pathsFound; protected List pathsToFind; protected PathDelimiter delim; /** * * @param pathsToFind * A path to a field in the {@link JSONObject} should be specified in n-gram format where keys are chained: k0[[[.k1].k2]...] * @param delim - */ public LocatePathsJsonAction(List pathsToFind, PathDelimiter delim) { this.pathsToFind = pathsToFind; this.delim = delim; pathsFound = new LinkedList(); } @Override public boolean start(JSONObject object) { return object != null && pathsToFind != null && pathsToFind.size() > 0; } @Override public boolean traverseEntry(String fullPathToEntry, Entry entry) { if (!delim.accept(entry.getKey())) { return false; } locatePath(fullPathToEntry); return true; } @Override public boolean recurInto(String pathToEntry, JSONObject entryValue) { return true; } @Override public boolean recurInto(String pathToEntry, JSONArray entryValue) { return true; } @Override public void handleLeaf(String pathToEntry, Entry entry) { } @Override public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) { } @Override public boolean removeEntry(String fullPathToEntry, Entry entry) { return false; } @Override public void end() { // nothing to do } @Override public Object result() { return pathsFound; } private void locatePath(String pathToEntry) { if (pathsToFind.contains(pathToEntry)) { // reached end of path that is being searched pathsFound.add(pathToEntry); } } } RemoveElementsJsonAction.java000066400000000000000000000036501475302255200404320ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import java.util.Map; import java.util.Map.Entry; /** * Removes key:value elements from a {@link JSONObject}. *

* An element is not removed from the user-specified list once its processing is over, * because it may appear in more than one node. *

* See package-info for more details *

* See unit tests for examples * * @author adoneitan@gmail.com * */ public class RemoveElementsJsonAction implements JSONTraverseAction { protected JSONObject result; protected final Map elementsToRemove; protected final boolean allowDotChar; public RemoveElementsJsonAction(Map elementsToRemove, boolean allowDotChar) { this.elementsToRemove = elementsToRemove; this.allowDotChar = allowDotChar; } public RemoveElementsJsonAction(Map elementsToRemove) { this(elementsToRemove, false); } @Override public boolean start(JSONObject object) { result = object; return object != null && elementsToRemove != null && elementsToRemove.size() > 0; } @Override public boolean removeEntry(String fullPathToEntry, Entry entry) { return elementsToRemove.entrySet().contains(entry); } @Override public boolean traverseEntry(String fullPathToEntry, Entry entry) { // must traverse the whole object return true; } @Override public boolean recurInto(String pathToEntry, JSONObject entryValue) { return true; } @Override public boolean recurInto(String pathToEntry, JSONArray entryValue) { return true; } @Override public void handleLeaf(String pathToEntry, Entry entry) { } @Override public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) { } @Override public void end() { // nothing to do } @Override public Object result() { return result; } } RemovePathsJsonAction.java000066400000000000000000000032721475302255200377350ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import java.util.List; import java.util.Map.Entry; /** * Removes branches from a {@link JSONObject}. *

* A path is not removed from the user-specified list once its processing is over, * because identical objects in the same array are supported by this action. *

* See package-info for more details *

* See unit tests for examples * * @author adoneitan@gmail.com * */ public class RemovePathsJsonAction implements JSONTraverseAction { protected JSONObject result; protected List pathsToRemove; public RemovePathsJsonAction(List pathsToRemove) { this.pathsToRemove = pathsToRemove; } @Override public boolean start(JSONObject object) { result = object; return object != null && pathsToRemove != null && pathsToRemove.size() > 0; } @Override public boolean removeEntry(String fullPathToEntry, Entry entry) { return pathsToRemove.contains(fullPathToEntry); } @Override public boolean traverseEntry(String fullPathToEntry, Entry entry) { // must traverse the whole object return true; } @Override public boolean recurInto(String pathToEntry, JSONObject entryValue) { return true; } @Override public boolean recurInto(String pathToEntry, JSONArray entryValue) { return true; } @Override public void handleLeaf(String pathToEntry, Entry entry) { } @Override public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) { } @Override public void end() { // nothing to do } @Override public Object result() { return result; } } RetainPathsJsonAction.java000066400000000000000000000060321475302255200377170ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.actions.path.PathDelimiter; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; /** * Retain branches or parts of branches matching a specified list of paths. *

* Paths are matched from the root down. If a user-specified path ends at a non-leaf node, * the rest of the branch from that node to the leaf is not retained. *

* A path is not removed from the user-specified list once its processing is over, * because identical objects in the same array are supported by this action. *

* See package-info for more details *

* See unit tests for examples * * @author adoneitan@gmail.com * */ public class RetainPathsJsonAction implements JSONTraverseAction { protected final PathDelimiter delim; protected JSONObject result; protected List pathsToRetain; /** * @param pathsToRetain TODO * @param delim TODO */ public RetainPathsJsonAction(List pathsToRetain, PathDelimiter delim) { this.pathsToRetain = new ArrayList(pathsToRetain); this.delim = delim; } @Override public boolean start(JSONObject object) { if (object == null) { result = null; return false; } if (pathsToRetain == null || pathsToRetain.size() == 0) { result = new JSONObject(); return false; } result = object; return true; } @Override public boolean traverseEntry(String fullPathToEntry, Entry entry) { return true; } @Override public boolean recurInto(String fullPathToSubtree, JSONObject entryValue) { return true; } @Override public boolean recurInto(String fullPathToArrayItem, JSONArray entryValue) { return true; } @Override public void handleLeaf(String pathToEntry, Entry entry) { } @Override public void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem) { } @Override public boolean removeEntry(String fullPathToEntry, Entry entry) { return discardPath(fullPathToEntry, entry); } @Override public void end() { // nothing to do } @Override public Object result() { return result; } /** * if the full path to the entry is not contained in any of the paths to retain - remove it from the object * this step does not remove entries whose full path is contained in a path to retain but are not equal to an * entry to retain * * @param pathToEntry TODO * @param entry TODO * @return TODO */ protected boolean discardPath(String pathToEntry, Entry entry) { if (!foundAsPrefix(pathToEntry) || !delim.accept(entry.getKey())) { //skip traversal of subtree and remove from the traversal iterator return true; } return false; } /** * @param path TODO * @return TODO */ protected boolean foundAsPrefix(String path) { for (String p : pathsToRetain) { if (p == path || (p != null && path != null && p.startsWith(path))) { return true; } } return false; } } TreeTraverseAction.java000066400000000000000000000051611475302255200372600ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * An interface for a processing action on the nodes of a {@link M} tree * while traversing it. The order in which the callbacks are listed * below is the order in which they are called by the {@link TreeTraverser} *

* See package-info for more details * * @author adoneitan@gmail.com */ public interface TreeTraverseAction, L extends List> { /** * called before any traversal of the {@link M} tree starts * @param object TODO * @return true if traversal should start at all */ boolean start(M object); /** * called when a new entry is encountered and before any processing is performed on it * @param fullPathToEntry TODO * @param entry TODO * @return true if the entry should be processed */ boolean traverseEntry(String fullPathToEntry, Entry entry); /** * the last callback for each entry in an {@link M} map. if this method returns true * the {@link TreeTraverser} removes the entry from the map. there is no further * handling of the entry. * * @param fullPathToEntry TODO * @param entry TODO * @return true if the entry and its subtree should be removed from the M tree */ boolean removeEntry(String fullPathToEntry, Entry entry); /** * called when a non-leaf entry is encountered inside an M object * * @param fullPathToSubtree TODO * @param entryValue TODO * @return true if the non-leaf entry should be recursively traversed */ boolean recurInto(String fullPathToSubtree, M entryValue); /** * called when a non-leaf item is encountered inside an L object * @param fullPathToContainingList TODO * @param entryValue TODO * @return true if the non-leaf item should be recursively traversed */ boolean recurInto(String fullPathToContainingList, L entryValue); /** * called for each leaf of an M map is encountered * @param fullPathToEntry TODO * @param entry TODO */ void handleLeaf(String fullPathToEntry, Entry entry); /** * called for each leaf of an L list is encountered * @param fullPathToContainingList - the item * @param listIndex - the ordered location of the item in the list * @param listItem - */ void handleLeaf(String fullPathToContainingList, int listIndex, Object listItem); /** * called after the traversal ends, * and just before the {@link #start} method exits */ void end(); /** * holds the result of the traversal, * as assigned by the action implementing this interface * @return result */ Object result(); } TreeTraverser.java000066400000000000000000000047741475302255200363150ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traversepackage net.minidev.json.actions.traverse; import net.minidev.json.actions.path.PathDelimiter; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * Traverses every node of a tree made up of a combination of {@link Map}s and {@link List}s *

* {@link TreeTraverser} accepts an action and provides callback hooks for it to act * on the traversed nodes at each significant step. See {@link TreeTraverseAction}. *

* See package-info for more details * * @author adoneitan@gmail.com * */ public class TreeTraverser, L extends List> { protected TreeTraverseAction action; protected PathDelimiter delim; protected String pathPrefix = ""; public TreeTraverser(TreeTraverseAction action, PathDelimiter delim) { this.action = action; this.delim = delim; } public TreeTraverser with(String pathPrefix) { this.pathPrefix = pathPrefix; return this; } public void traverse(M map) { if (action.start(map)) { depthFirst(pathPrefix, map); } action.end(); } @SuppressWarnings("unchecked") private void depthFirst(String fullPath, M map) { if (map == null || map.entrySet() == null || !action.recurInto(fullPath, map)) { return; } Iterator> it = map.entrySet().iterator(); while (it.hasNext()) { Entry entry = it.next(); String fullPathToEntry = buildPath(fullPath, entry.getKey()); if (!action.traverseEntry(fullPathToEntry, entry)) { continue; } else if (action.removeEntry(fullPathToEntry, entry)) { it.remove(); continue; } if (entry.getValue() instanceof Map) { depthFirst(fullPathToEntry, (M) entry.getValue()); } else if (entry.getValue() instanceof List) { depthFirst(fullPathToEntry, (L) entry.getValue()); } else { action.handleLeaf(fullPathToEntry, entry); } } } @SuppressWarnings("unchecked") private void depthFirst(String fullPath, L list) { if (!action.recurInto(fullPath, (L) list)) { return; } int listIndex = 0; for (Object listItem : list.toArray()) { if (listItem instanceof Map) { depthFirst(fullPath, (M) listItem); } else if (listItem instanceof List) { depthFirst(fullPath, (L) listItem); } else { action.handleLeaf(fullPath, listIndex, listItem); } listIndex++; } } private String buildPath(String fullPath, String entryKey) { return pathPrefix.equals(fullPath) ? pathPrefix + entryKey : fullPath + delim.str() + entryKey; } } package-info.java000066400000000000000000000023031475302255200360260ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/main/java/net/minidev/json/actions/traverse/** * * Traverse all the nodes in a {@link net.minidev.json.JSONObject} and process them *

* The traversal starts at the root and moves breadth-first down the branches. * The {@link net.minidev.json.actions.traverse.TreeTraverser} accepts a * {@link net.minidev.json.actions.traverse.JSONTraverseAction} and provides callback hooks at each significant * step which the {@link net.minidev.json.actions.traverse.JSONTraverseAction} may use to process * the nodes. *

* The {@link net.minidev.json.actions.traverse.TreeTraverser} assumes that paths in the tree which the * {@link net.minidev.json.JSONObject} represents are specified in the n-gram format - a list of keys from the * root down separated by dots: *

* K0[[[[.K1].K2].K3]...] *

* A key to the right of a dot is a direct child of a key to the left of a dot. * Keys with a dot in their name are not supported. *

* Sample usage: *

 * TraverseAction tAction = new TraverseAction(){...};
 * JSONTraverser jsonTrv = new JSONTraverser(tAction);
 * jsonTrv.traverse(new JSONObject(...));
 * Object result = tAction.result();
 * 
* * @author adoneitan@gmail.com */ package net.minidev.json.actions.traverse;netplex-json-smart-v2-20dff24/json-smart-action/src/test/000077500000000000000000000000001475302255200233455ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/000077500000000000000000000000001475302255200242665ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/000077500000000000000000000000001475302255200250545ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/000077500000000000000000000000001475302255200265075ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/000077500000000000000000000000001475302255200274605ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/000077500000000000000000000000001475302255200304375ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actions/000077500000000000000000000000001475302255200320775ustar00rootroot00000000000000ElementRemoverTest.java000066400000000000000000000046721475302255200364650ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actionspackage net.minidev.json.test.actions; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import net.minidev.json.actions.ElementRemover; import net.minidev.json.parser.ParseException; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; /** * Tests {@link ElementRemover} * * @author adoneitan@gmail.com */ // @RunWith(Parameterized.class) public class ElementRemoverTest { public ElementRemoverTest() { } private static String filter(String test) { if (test == null) return null; return test.replace("'", "\""); } public static Stream params() { return Stream.of( Arguments.of("{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", null, "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}"), Arguments.of("{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", "{}", "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}"), Arguments.of("{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", "{'k0':'v2'}", "{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}"), Arguments.of("{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", "{'k2':'v2'}", "{'k0':{},'k1':{'k3':'v3'}}"), Arguments.of("{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", "{'k0':{'k2':'v2'}}", "{'k1':{'k2':'v2','k3':'v3'}}"), Arguments.of("{'k0':{'k2':'v2'},'k1':{'k2':'v2','k3':'v3'}}", "{'k2':'v2','k3':'v3'}", "{'k0':{},'k1':{}}"), Arguments.of("{'k0':{}}", "{}", "{'k0':{}}") ); }; @ParameterizedTest @MethodSource("params") public void test(String jsonToClean, String elementsToRemove, String expectedJson) throws ParseException { jsonToClean = filter(jsonToClean); elementsToRemove = filter(elementsToRemove); expectedJson = filter(expectedJson); JSONObject objectToClean = jsonToClean != null ? (JSONObject) JSONValue.parseWithException(jsonToClean) : null; JSONObject expectedObject = expectedJson != null ? (JSONObject) JSONValue.parseWithException(expectedJson) : null; JSONObject toRemove = elementsToRemove != null ? (JSONObject) JSONValue.parseWithException(elementsToRemove) : null; ElementRemover er = new ElementRemover(toRemove); er.remove(objectToClean); assertEquals(expectedObject, objectToClean); } } KeysPrintActionTest.java000066400000000000000000000016571475302255200366220ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actionspackage net.minidev.json.test.actions; import org.junit.jupiter.api.Test; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import net.minidev.json.actions.traverse.JSONTraverser; import net.minidev.json.actions.traverse.KeysPrintAction; import net.minidev.json.parser.ParseException; /** * @author adoneitan@gmail.com * @since 30 May 2016 */ public class KeysPrintActionTest { @Test public void test() throws ParseException { KeysPrintAction p = new KeysPrintAction(); JSONTraverser t = new JSONTraverser(p); String data ="{" + "'k0':{" + "'k01':{" + "'k011':'v2'" + "}" + "}," + "'k1':{" + "'k11':{" + "'k111':'v5'" + "}," + "'k12':{" + "'k121':'v5'" + "}" + "}," + "'k3':{" + "'k31':{" + "'k311':'v5'" + "}" + "}" + "}"; JSONObject jo = (JSONObject) JSONValue.parseWithException(data.replace("'", "\"")); t.traverse(jo); } }PathLocatorTest.java000066400000000000000000000223531475302255200357500ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actionspackage net.minidev.json.test.actions; import net.minidev.json.actions.PathLocator; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import net.minidev.json.parser.ParseException; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; /** * @author adoneitan@gmail.com */ // @ExtendWith(Parameterized.class) public class PathLocatorTest { public static Stream params() { return Stream.of( //nulls, bad/empty keys Arguments.of(null, null, new String[]{} ), Arguments.of(null, "", new String[]{} ), Arguments.of(null, "k1", new String[]{} ), Arguments.of(null, new String[]{}, new String[]{} ), Arguments.of(null, new JSONArray(), new String[]{} ), Arguments.of(null, new ArrayList(0), new String[]{} ),//5 //empty json, bad/empty keys Arguments.of("{}", null, new String[]{} ), Arguments.of("{}", "", new String[]{} ), Arguments.of("{}", "k1", new String[]{} ), Arguments.of("{}", new String[]{}, new String[]{} ), Arguments.of("{}", new JSONArray(), new String[]{} ),//10 Arguments.of("{}", new ArrayList(0), new String[]{} ), //simple json, bad/empty keys Arguments.of("{\"k0\":\"v0\"}", null, new String[]{} ), Arguments.of("{\"k0\":\"v0\"}", "", new String[]{} ), Arguments.of("{\"k0\":\"v0\"}", "k1", new String[]{} ), Arguments.of("{\"k0\":\"v0\"}", new String[]{}, new String[]{} ),//15 Arguments.of("{\"k0\":\"v0\"}", new JSONArray(), new String[]{} ), Arguments.of("{\"k0\":\"v0\"}", new ArrayList(0), new String[]{} ), //simple json, valid/invalid keys Arguments.of("{\"k0\":\"v0\"}", "k0", new String[]{"k0"} ), Arguments.of("{\"k0\":\"v0\"}", "v0", new String[]{} ), Arguments.of("{\"k0\":\"v0\"}", "k0.k1", new String[]{} ),//20 Arguments.of("{\"k0\":\"v0\"}", "k1.k0", new String[]{} ), Arguments.of("{\"k0\":null}", "k0", new String[]{"k0"} ), Arguments.of("{\"k0\":null}", null, new String[]{} ), //key with dot char Arguments.of("{\"k0.k1\":\"v0\"}", "k0", new String[]{} ), Arguments.of("{\"k0.k1\":\"v0\"}", "k1", new String[]{} ),//25 Arguments.of("{\"k0.k1\":\"v0\"}", "k0.k1", new String[]{} ), // key with dot ambiguity Arguments.of("{\"k0.k1\":\"withDot\",\"k0\":{\"k1\":null}}", "k0", new String[]{"k0"} ), Arguments.of("{\"k0.k1\":\"withDot\",\"k0\":{\"k1\":null}}", "k1", new String[]{} ), Arguments.of("{\"k0.k1\":\"withDot\",\"k0\":{\"k1\":null}}", "k0.k1", new String[]{"k0.k1"} ), Arguments.of("{\"k0\":{\"k1.k2\":\"dot\",\"k1\":{\"k2\":null}}}", "k0.k1", new String[]{"k0.k1"} ),//30 Arguments.of("{\"k0\":{\"k1.k2\":\"dot\",\"k1\":{\"k2\":null}}}", "k0.k1.k2", new String[]{"k0.k1.k2"} ), Arguments.of("{\"k0\":{\"k1.k2\":\"dot\",\"k1\":{\"k2\":null}}}", "k1.k2", new String[]{} ), Arguments.of("{\"k0\":{\"k1.k2\":\"dot\"},\"k1\":{\"k2\":\"v2\"}}}","k0", new String[]{"k0"} ), Arguments.of("{\"k0\":{\"k1.k2\":\"dot\"},\"k1\":{\"k2\":\"v2\"}}}","k1.k2", new String[]{"k1.k2"} ), //ignore non-existent keys but keep good keys Arguments.of("{\"k0\":\"v0\",\"k1\":\"v1\"}", new String[]{"k0","k2"}, new String[]{"k0"} ),//35 Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k2"}, new String[]{"k0"} ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1.k2"}, new String[]{"k0", "k1.k2"} ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1.k2.k3"}, new String[]{"k0"} ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1.k2","k1"}, new String[]{"k0","k1","k1.k2"} ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1","k0.k2"}, new String[]{"k0","k1"} ),//40 Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1","k2"}, new String[]{"k0","k1"} ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k1.k2"}, new String[]{"k1.k2"} ), //arrays - key inside array treated as child Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0", new String[]{"k0"} ), Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0.k1", new String[]{"k0.k1"} ), Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0.k1.k2", new String[]{"k0.k1.k2"} ),//45 Arguments.of("{\"k0\":{\"k1\":[{\"k2\":\"v2\"},{\"k2\":\"v2\"}]}}", "k0.k1.k2", new String[]{"k0.k1.k2", "k0.k1.k2"} ) ); } @ParameterizedTest @MethodSource("params") public void test(String jsonToSearch, Object keysToFind, String[] expectedFound) throws ParseException { JSONObject objectToSearch = jsonToSearch != null ? (JSONObject) JSONValue.parseWithException(jsonToSearch) : null; PathLocator locator = switchKeyToRemove(keysToFind); List found = locator.locate(objectToSearch); assertEquals(Arrays.asList(expectedFound), found); } @SuppressWarnings("unchecked") private PathLocator switchKeyToRemove(Object keysToFind) { long m = System.currentTimeMillis(); if (keysToFind == null && m % 4 == 0) { // System.out.println("cast to String"); return new PathLocator((String)null); } else if (keysToFind == null && m % 4 == 1) { // System.out.println("cast to String[]"); return new PathLocator((String[])null); } else if (keysToFind == null && m % 4 == 2) { // System.out.println("cast to JSONArray"); return new PathLocator((JSONArray)null); } else if (keysToFind == null && m % 4 == 3) { // System.out.println("cast to List"); return new PathLocator((List)null); } else if (keysToFind instanceof String) { return new PathLocator((String) keysToFind); } else if (keysToFind instanceof String[]) { return new PathLocator((String[]) keysToFind); } else if (keysToFind instanceof JSONArray) { return new PathLocator((JSONArray) keysToFind); } else if (keysToFind instanceof List) { return new PathLocator((List) keysToFind); } else { throw new IllegalArgumentException("bad test setup: wrong type of key to remove"); } } }PathRemoverTest.java000066400000000000000000000164651475302255200357730ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actionspackage net.minidev.json.test.actions; import net.minidev.json.actions.PathRemover; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import net.minidev.json.parser.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; /** * Tests {@link PathRemover} * * @author adoneitan@gmail.com */ // @RunWith(Parameterized.class) public class PathRemoverTest { public static Stream params() { return Stream.of( Arguments.of(null, "key", null ), // null json Arguments.of("{}", "key", "{}" ), // empty json Arguments.of("{\"first\": null}", null, "{\"first\": null}" ), // null key Arguments.of("{\"first\": null}", "", "{\"first\": null}" ), // empty string key Arguments.of("{\"first\": null}", new String[]{}, "{\"first\": null}" ), // empty string array key Arguments.of("{\"first\": null}", new JSONArray(), "{\"first\": null}" ), // empty json array key Arguments.of("{\"first\": null}", new ArrayList(0), "{\"first\": null}" ), // empty list key Arguments.of("{\"first\": null}", "first", "{}" ), // remove root key Arguments.of("{\"first.f1\": null}", "first.f1", "{}" ), // key with dot Arguments.of("{\"first.f1\": \"withDot\", \"first\":{\"f1\": null}}", "first.f1", "{\"first\":{}}" ), //9 key with dot ambiguity Arguments.of("{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\"}}}}", "first.f2.f3.id", "{\"first\":{\"f2\":{\"f3\":{}}}}" ), // nested object remove single leaf Arguments.of("{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\"}}}}", "notfound", "{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\"}}}}" ), // nested object key does not exist Arguments.of("{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\",\"name\":\"me\"}}}}", "first.f2.f3.id", "{\"first\":{\"f2\":{\"f3\":{\"name\":\"me\"}}}}"), // nested object remove first leaf Arguments.of("{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\",\"name\":\"me\"}}}}", "first.f2.f3.name", "{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\"}}}}" ), //13 nested object remove last leaf Arguments.of("{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\",\"name\":\"me\"}}}}", "first.f2.f3", "{\"first\":{\"f2\":{}}}" ), // nested object remove intermediate node Arguments.of("{\"first\":{\"f2\":{\"f3\":{\"id\":\"id1\",\"name\":\"me\"}}}}", "first", "{}" ), // nested object remove root Arguments.of("{\"first\":{\"f2\":[[1,{\"id\":\"id1\"},3],4]}}", "first.f2.id", "{\"first\":{\"f2\":[[1,{},3],4]}}" ), // double nested array remove leaf Arguments.of("{\"first\":{\"f2\":[[1,{\"id\":\"id1\"},3],4]}}", "first.f2", "{\"first\":{}}" ), // double nested array remove array Arguments.of("{\"first\":[[1,{\"id\":\"id1\"},3],4]}", "first", "{}" ), // double nested array remove root //arrays Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0.k1", "{\"k0\":{}}" ), // value is array Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0.k1.k2", "{\"k0\":{\"k1\":[1,{},3,4]}}" ), // full path into array object Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0.k1.3" , "{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}" ), // full path into array primitive Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},{\"k2\":\"v2\"},3,4]}}", "k0.k1.k2", "{\"k0\":{\"k1\":[1,{},{},3,4]}}" ), // full path into array with identical items // composite json remove all roots Arguments.of("{\"first\": {\"f2\":{\"id\":\"id1\"}}, \"second\": [{\"k1\":{\"id\":\"id1\"}}, 4, 5, 6, {\"id\": 123}], \"third\": 789, \"id\": null}", (JSONArray) JSONValue.parse("[\"first\",\"second\",\"third\",\"id\"]"), "{}" ), // composite json remove all leaves Arguments.of("{\"first\": {\"f2\":{\"id\":\"id1\"}}, \"second\": [{\"k1\":{\"id\":\"id1\"}}, 4, 5, 6, {\"id\": 123}], \"third\": 789, \"id\": null}", (List) Arrays.asList("first.f2.id", "second.k1.id", "second.id", "third", "id"), "{\"first\": {\"f2\":{}}, \"second\": [{\"k1\":{}}, 4, 5, 6, {}]}" ) ); } @ParameterizedTest @MethodSource("params") public void test(String jsonToClean, Object keyToRemove, String expectedJson) throws ParseException { JSONObject objectToClean = jsonToClean != null ? (JSONObject) JSONValue.parseWithException(jsonToClean) : null; JSONObject expectedObject = expectedJson != null ? (JSONObject) JSONValue.parseWithException(expectedJson): null; PathRemover cl = switchKeyToRemove(keyToRemove); cl.remove(objectToClean); assertEquals(expectedObject, objectToClean); } @SuppressWarnings("unchecked") private PathRemover switchKeyToRemove(Object keyToRemove) { long m = System.currentTimeMillis(); if (keyToRemove == null && m % 4 == 0) { // System.out.println("cast to String"); return new PathRemover((String)null); } else if (keyToRemove == null && m % 4 == 1) { // System.out.println("cast to String[]"); return new PathRemover((String[])null); } else if (keyToRemove == null && m % 4 == 2) { // System.out.println("cast to JSONArray"); return new PathRemover((JSONArray)null); } else if (keyToRemove == null && m % 4 == 3) { // System.out.println("cast to List"); return new PathRemover((List)null); } else if (keyToRemove instanceof String) { return new PathRemover((String)keyToRemove); } else if (keyToRemove instanceof String[]) { return new PathRemover((String[])keyToRemove); } else if (keyToRemove instanceof JSONArray) { return new PathRemover((JSONArray)keyToRemove); } else if (keyToRemove instanceof List) { return new PathRemover((List)keyToRemove); } else { throw new IllegalArgumentException("bad test setup: wrong type of key to remove"); } } } PathReplicatorTest.java000066400000000000000000000336201475302255200364500ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actionspackage net.minidev.json.test.actions; import net.minidev.json.actions.PathReplicator; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; /** * @author adoneitan@gmail.com */ public class PathReplicatorTest { @SuppressWarnings("unchecked") private static T filter(T obj) { if (obj == null) return null; if (obj instanceof String) return (T)(((String)obj).replace("'", "\"")); return obj; } public static Stream params() { return Stream.of( //nulls, bad/empty keys Arguments.of(null, null, null ), Arguments.of(null, "", null ), Arguments.of(null, "k1", null ), Arguments.of(null, new String[]{}, null ), Arguments.of(null, new JSONArray(), null ), Arguments.of(null, new ArrayList(0), null ),//5 //empty json, bad/empty keys Arguments.of("{}", null, "{}" ), Arguments.of("{}", "", "{}" ), Arguments.of("{}", "k1", "{}" ), Arguments.of("{}", new String[]{}, "{}" ), Arguments.of("{}", new JSONArray(), "{}" ), Arguments.of("{}", new ArrayList(0), "{}" ),//11 //simple json, bad/empty keys Arguments.of("{'k0':'v0'}", null, "{}" ), Arguments.of("{'k0':'v0'}", "", "{}" ), Arguments.of("{'k0':'v0'}", "k1", "{}" ), Arguments.of("{'k0':'v0'}", new String[]{}, "{}" ), Arguments.of("{'k0':'v0'}", new JSONArray(), "{}" ), Arguments.of("{'k0':'v0'}", new ArrayList(0), "{}" ),//17 //simple json, valid/invalid keys Arguments.of("{'k0':'v0'}", "k0", "{'k0':'v0'}" ), Arguments.of("{'k0':'v0'}", "v0", "{}" ), Arguments.of("{'k0':'v0'}", "k0.k1", "{}" ),//20 Arguments.of("{'k0':'v0'}", "k1.k0", "{}" ), Arguments.of("{'k0':null}", "k0", "{'k0':null}" ), Arguments.of("{'k0':null}", "v0", "{}" ), //key with dot char Arguments.of("{'k0.k1':'v0'}", "k0", "{}" ), Arguments.of("{'k0.k1':'v0'}", "k1", "{}" ), Arguments.of("{'k0.k1':'v0'}", "k0.k1", "{}" ), // key with dot ambiguity Arguments.of("{'k0.k1':'withDot','k0':{'k1':null}}", "k0", "{'k0':{}}" ), Arguments.of("{'k0.k1':'withDot','k0':{'k1':null}}", "k1", "{}" ), Arguments.of("{'k0.k1':'withDot','k0':{'k1':null}}", "k0.k1", "{'k0':{'k1':null}}" ), Arguments.of("{'k0':{'k1.k2':'dot','k1':{'k2':null}}}", "k0.k1", "{'k0':{'k1':{}}}" ), Arguments.of("{'k0':{'k1.k2':'dot','k1':{'k2':null}}}", "k0.k1.k2", "{'k0':{'k1':{'k2':null}}}" ), Arguments.of("{'k0':{'k1.k2':'dot','k1':{'k2':null}}}", "k1.k2", "{}" ), Arguments.of("{'k0':{'k1.k2':'dot'},'k1':{'k2':'v2'}}}", "k0", "{'k0':{}}}" ), Arguments.of("{'k0':{'k1.k2':'dot'},'k1':{'k2':'v2'}}}", "k1.k2", "{'k1':{'k2':'v2'}}}" ), Arguments.of("{'k0':{'k1':'v1','k2':{'k3.k4':'dot'}}}", "k0.k2.k3.k4", "{}" ), Arguments.of("{'k0':{'k1':'v1','k2':{'k3.k4':'dot'}}}", "k0.k2.k3", "{}" ), Arguments.of("{'k0':{'k1':'v1','k2':{'k3.k4':'dot'}}}", "k0.k2", "{'k0':{'k2':{}}}" ), Arguments.of("{'k0':{'k1':'v1','k2':{'k3.k4':'dot'}}}", "k0", "{'k0':{}}" ),//38 //ignore non-existent keys but keep good keys Arguments.of("{'k0':'v0','k1':'v1'}", new String[]{"k0","k2"}, "{'k0':'v0'}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k0","k2"}, "{'k0':'v0'}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k0","k1.k2"}, "{'k0':'v0','k1':{'k2':'v2'}}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k0","k0.k2"}, "{'k0':'v0'}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k0","k1.k2","k1"}, "{'k0':'v0','k1':{'k2':'v2'}}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k0","k1"}, "{'k0':'v0','k1':{}}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k0","k1","k2"}, "{'k0':'v0','k1':{}}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k1.k2"}, "{'k1':{'k2':'v2'}}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k1.k2.k3"}, "{}" ), Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k0.k1.k2"}, "{}" ),//48 Arguments.of("{'k0':'v0','k1':{'k2':'v2'}}", new String[]{"k1.k0"}, "{}" ), //arrays - key inside array treated as child Arguments.of("{'k0':{'k1':[1,2,3,4]}}", "k0", "{'k0':{}}" ), Arguments.of("{'k0':{'k1':[1,2,3,4]}}", "k0.k1", "{'k0':{'k1':[1,2,3,4]}}" ), Arguments.of("{'k0':{'k1':[1,{'k2':'v2'},3,4]}}", "k0", "{'k0':{}}" ), Arguments.of("{'k0':{'k1':[1,{'k2':'v2'},3,4]}}", "k0.k1", "{'k0':{'k1':[1,{},3,4]}}" ), Arguments.of("{'k0':{'k1':[1,{'k2':'v2'},3,4]}}", "k0.k1.k2", "{'k0':{'k1':[{'k2':'v2'}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'},{'k2':'v2'}]}}", "k0.k1", "{'k0':{'k1':[{},{}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'},{'k2':'v2'}]}}", "k0.k1.k2", "{'k0':{'k1':[{'k2':'v2'},{'k2':'v2'}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'}],'k3':[{'k4':'v4'}]}}", "k0.k1.k2", "{'k0':{'k1':[{'k2':'v2'}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'}],'k3':[{'k4':'v4'}]}}", "k0.k3.k4", "{'k0':{'k3':[{'k4':'v4'}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'}],'k3':[{'k4':{'k5':'v5'}}]}}", "k0.k1.k2", "{'k0':{'k1':[{'k2':'v2'}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'}],'k3':[{'k4':{'k5':'v5'}}]}}", "k0.k3.k4", "{'k0':{'k3':[{'k4':{}}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'}],'k3':[{'k4':{'k5':'v5'}}]}}", "k0.k3.k4.k5", "{'k0':{'k3':[{'k4':{'k5':'v5'}}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'}],'k3':[{'k4':{'k5':'v5'}}]}}", new String[]{"k0.k1", "k0.k3"}, "{'k0':{'k3':[{}],'k1':[{}]}}" ), Arguments.of("{'k0':{'k1':[{'k2':'v2'}],'k3':[{'k4':{'k5':'v5'}}]}}", new String[]{"k0.k1", "k0.k3.k4.k5"}, "{'k0':{'k3':[{'k4':{'k5':'v5'}}],'k1':[{}]}}" ) ); } @ParameterizedTest @MethodSource("params") public void test(String jsonSource, Object pathsToCopy, Object expected) throws Exception { jsonSource = filter(jsonSource); pathsToCopy = filter(pathsToCopy); expected = filter(expected); JSONObject objectSource = jsonSource != null ? (JSONObject) JSONValue.parseWithException(jsonSource) : null; PathReplicator copier = switchKeyToCopy(pathsToCopy); JSONObject copied = copier.replicate(objectSource); JSONObject expectedObj = expected != null ? (JSONObject) JSONValue.parseWithException((String) expected) : null; assertEquals(expectedObj, copied); } @ParameterizedTest @MethodSource("params") public void test2(String jsonSource, Object pathsToCopy, Object expected) throws Exception { jsonSource = filter(jsonSource); pathsToCopy = filter(pathsToCopy); expected = filter(expected); JSONObject objectSource = jsonSource != null ? (JSONObject) JSONValue.parseWithException(jsonSource) : null; PathReplicator copier = switchKeyToCopy2(pathsToCopy); JSONObject copied = copier.replicate(objectSource); JSONObject expectedObj = expected != null ? (JSONObject) JSONValue.parseWithException((String) expected) : null; assertEquals(expectedObj, copied); } @SuppressWarnings("unchecked") private PathReplicator switchKeyToCopy(Object pathsToCopy) { long m = System.currentTimeMillis(); if (pathsToCopy == null && m % 4 == 0) { // System.out.println("cast to String"); return new PathReplicator((String) null); } else if (pathsToCopy == null && m % 4 == 1) { // System.out.println("cast to String[]"); return new PathReplicator((String[]) null); } else if (pathsToCopy == null && m % 4 == 2) { // System.out.println("cast to JSONArray"); return new PathReplicator((JSONArray) null); } else if (pathsToCopy == null && m % 4 == 3) { // System.out.println("cast to List"); return new PathReplicator((List) null); } else if (pathsToCopy instanceof String) { return new PathReplicator((String) pathsToCopy); } else if (pathsToCopy instanceof String[]) { return new PathReplicator((String[]) pathsToCopy); } else if (pathsToCopy instanceof JSONArray) { return new PathReplicator((JSONArray) pathsToCopy); } else if (pathsToCopy instanceof List) { return new PathReplicator((List) pathsToCopy); } else { throw new IllegalArgumentException("bad test setup: wrong type of key to remove"); } } @SuppressWarnings("unchecked") private PathReplicator switchKeyToCopy2(Object pathsToCopy) { long m = System.currentTimeMillis(); if (pathsToCopy == null && m % 4 == 0) { // System.out.println("cast to String"); return new PathReplicator((String) null); } else if (pathsToCopy == null && m % 4 == 1) { // System.out.println("cast to String[]"); return new PathReplicator((String[]) null); } else if (pathsToCopy == null && m % 4 == 2) { // System.out.println("cast to JSONArray"); return new PathReplicator((JSONArray) null); } else if (pathsToCopy == null && m % 4 == 3) { // System.out.println("cast to List"); return new PathReplicator((List) null); } else if (pathsToCopy instanceof String) { return new PathReplicator((String) pathsToCopy); } else if (pathsToCopy instanceof String[]) { return new PathReplicator((String[]) pathsToCopy); } else if (pathsToCopy instanceof JSONArray) { return new PathReplicator((JSONArray) pathsToCopy); } else if (pathsToCopy instanceof List) { return new PathReplicator((List) pathsToCopy); } else { throw new IllegalArgumentException("bad test setup: wrong type of key to remove"); } } }PathsRetainerTest.java000066400000000000000000000267711475302255200363110ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actionspackage net.minidev.json.test.actions; import net.minidev.json.actions.PathsRetainer; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import net.minidev.json.actions.path.DotDelimiter; import net.minidev.json.parser.ParseException; // import org.junit.runner.RunWith; // import org.junit.runners.Parameterized; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.assertEquals; /** * @author adoneitan@gmail.com */ public class PathsRetainerTest { public static Stream params() { return Stream.of( //nulls, bad/empty keys Arguments.of(null, null, null ), Arguments.of(null, "", null ), Arguments.of(null, "k1", null ), Arguments.of(null, new String[]{}, null ), Arguments.of(null, new JSONArray(), null ), Arguments.of(null, new ArrayList(0), null ),//5 //empty json, bad/empty keys Arguments.of("{}", null, "{}" ), Arguments.of("{}", "", "{}" ), Arguments.of("{}", "k1", "{}" ), Arguments.of("{}", new String[]{}, "{}" ), Arguments.of("{}", new JSONArray(), "{}" ), Arguments.of("{}", new ArrayList(0), "{}" ),//11 //simple json, bad/empty keys Arguments.of("{\"k0\":\"v0\"}", null, "{}" ), Arguments.of("{\"k0\":\"v0\"}", "", "{}" ), Arguments.of("{\"k0\":\"v0\"}", "k1", "{}" ), Arguments.of("{\"k0\":\"v0\"}", new String[]{}, "{}" ), Arguments.of("{\"k0\":\"v0\"}", new JSONArray(), "{}" ), Arguments.of("{\"k0\":\"v0\"}", new ArrayList(0), "{}" ),//17 //simple json, valid/invalid keys Arguments.of("{\"k0\":\"v0\"}", "k0", "{\"k0\":\"v0\"}" ), Arguments.of("{\"k0\":\"v0\"}", "v0", "{}" ), Arguments.of("{\"k0\":\"v0\"}", "k0.k1", "{}" ), Arguments.of("{\"k0\":\"v0\"}", "k1.k0", "{}" ), Arguments.of("{\"k0\":null}", "k0", "{\"k0\":null}" ), Arguments.of("{\"k0\":null}", "v0", "{}" ),//23 //key with dot char Arguments.of("{\"k0.k1\":\"v0\"}", "k0", "{}" ), Arguments.of("{\"k0.k1\":\"v0\"}", "k1", "{}" ), Arguments.of("{\"k0.k1\":\"v0\"}", "k0.k1", "{}" ), // key with dot ambiguity Arguments.of("{\"k0.k1\":\"withDot\",\"k0\":{\"k1\":null}}", "k0", "{\"k0\":{}}" ),//27 Arguments.of("{\"k0.k1\":\"withDot\",\"k0\":{\"k1\":null}}", "k1", "{}" ), Arguments.of("{\"k0.k1\":\"withDot\",\"k0\":{\"k1\":null}}", "k0.k1", "{\"k0\":{\"k1\":null}}" ),//29 Arguments.of("{\"k0\":{\"k1.k2\":\"dot\",\"k1\":{\"k2\":null}}}", "k0.k1", "{\"k0\":{\"k1\":{}}}" ), Arguments.of("{\"k0\":{\"k1.k2\":\"dot\",\"k1\":{\"k2\":null}}}", "k0.k1.k2", "{\"k0\":{\"k1\":{\"k2\":null}}}" ),//31 Arguments.of("{\"k0\":{\"k1.k2\":\"dot\",\"k1\":{\"k2\":null}}}", "k1.k2", "{}" ), Arguments.of("{\"k0\":{\"k1.k2\":\"dot\"},\"k1\":{\"k2\":\"v2\"}}}","k0", "{\"k0\":{}}}" ), Arguments.of("{\"k0\":{\"k1.k2\":\"dot\"},\"k1\":{\"k2\":\"v2\"}}}","k1.k2", "{\"k1\":{\"k2\":\"v2\"}}}" ), Arguments.of("{\"k0\":{\"k1\":\"v1\",\"k2\":{\"k3.k4\":\"dot\"}}}", "k0.k2.k3.k4", "{}" ), Arguments.of("{\"k0\":{\"k1\":\"v1\",\"k2\":{\"k3.k4\":\"dot\"}}}", "k0.k2.k3", "{}" ), Arguments.of("{\"k0\":{\"k1\":\"v1\",\"k2\":{\"k3.k4\":\"dot\"}}}", "k0.k2", "{\"k0\":{\"k2\":{}}}" ), Arguments.of("{\"k0\":{\"k1\":\"v1\",\"k2\":{\"k3.k4\":\"dot\"}}}", "k0", "{\"k0\":{}}" ), //ignore non-existent keys but keep good keys Arguments.of("{\"k0\":\"v0\",\"k1\":\"v1\"}", new String[]{"k0","k2"}, "{\"k0\":\"v0\"}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k2"}, "{\"k0\":\"v0\"}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1.k2"}, "{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k0.k2"}, "{\"k0\":\"v0\"}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1.k2","k1"}, "{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1"}, "{\"k0\":\"v0\",\"k1\":{}}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0","k1","k2"}, "{\"k0\":\"v0\",\"k1\":{}}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k1.k2"}, "{\"k1\":{\"k2\":\"v2\"}}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k1.k2.k3"}, "{}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k0.k1.k2"}, "{}" ), Arguments.of("{\"k0\":\"v0\",\"k1\":{\"k2\":\"v2\"}}", new String[]{"k1.k0"}, "{}" ), //arrays - key inside array treated as child Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0", "{\"k0\":{}}" ), Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0.k1", "{\"k0\":{\"k1\":[1,{},3,4]}}" ), Arguments.of("{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}", "k0.k1.k2", "{\"k0\":{\"k1\":[1,{\"k2\":\"v2\"},3,4]}}" ), Arguments.of("{\"k0\":{\"k1\":[{\"k2\":\"v2\"},{\"k2\":\"v2\"}]}}", "k0.k1", "{\"k0\":{\"k1\":[{},{}]}}" ), Arguments.of("{\"k0\":{\"k1\":[{\"k2\":\"v2\"},{\"k2\":\"v2\"}]}}", "k0.k1.k2", "{\"k0\":{\"k1\":[{\"k2\":\"v2\"},{\"k2\":\"v2\"}]}}" ) ); } @ParameterizedTest @MethodSource("params") public void test(String jsonToReduce, Object keyToKeep, String expectedReducedJson) throws ParseException { JSONObject objectToReduce = jsonToReduce != null ? (JSONObject) JSONValue.parseWithException(jsonToReduce) : null; JSONObject expectedReducedObj = expectedReducedJson != null ? (JSONObject) JSONValue.parseWithException(expectedReducedJson) : null; PathsRetainer retainer = switchKeyToRemove(keyToKeep).with(new DotDelimiter().withAcceptDelimiterInNodeName(false)); JSONObject reducedObj = retainer.retain(objectToReduce); assertEquals(expectedReducedObj, reducedObj); } @SuppressWarnings("unchecked") private PathsRetainer switchKeyToRemove(Object keyToKeep) { long m = System.currentTimeMillis(); if (keyToKeep == null && m % 4 == 0) { // System.out.println("cast to String"); return new PathsRetainer((String) null); } else if (keyToKeep == null && m % 4 == 1) { // System.out.println("cast to String[]"); return new PathsRetainer((String[]) null); } else if (keyToKeep == null && m % 4 == 2) { // System.out.println("cast to JSONArray"); return new PathsRetainer((JSONArray) null); } else if (keyToKeep == null && m % 4 == 3) { // System.out.println("cast to List"); return new PathsRetainer((List) null); } else if (keyToKeep instanceof String) { return new PathsRetainer((String) keyToKeep); } else if (keyToKeep instanceof String[]) { return new PathsRetainer((String[]) keyToKeep); } else if (keyToKeep instanceof JSONArray) { return new PathsRetainer((JSONArray) keyToKeep); } else if (keyToKeep instanceof List) { return new PathsRetainer((List) keyToKeep); } else { throw new IllegalArgumentException("bad test setup: wrong type of key to remove"); } } }TreePathTest.java000066400000000000000000000047771475302255200352560ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart-action/src/test/java/net/minidev/json/test/actionspackage net.minidev.json.test.actions; import net.minidev.json.actions.path.DotDelimiter; import net.minidev.json.actions.path.TreePath; import net.minidev.json.actions.path.PathDelimiter; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; /** * @author adoneitan@gmail.com */ public class TreePathTest { private static final PathDelimiter delim = new DotDelimiter().withAcceptDelimiterInNodeName(true); @Test public void testIterator() { TreePath jp = new TreePath("a.b.c", delim); assertTrue(jp.nextIndex() == 0); assertTrue(jp.prevIndex() == -1); assertTrue("".equals(jp.curr())); assertTrue("".equals(jp.origin())); assertTrue("a.b.c".equals(jp.remainder())); assertTrue(jp.hasNext()); assertFalse(jp.hasPrev()); jp.next(); assertTrue("a".equals(jp.curr())); assertTrue("a".equals(jp.origin())); assertTrue("b.c".equals(jp.remainder())); assertTrue(jp.hasNext()); assertTrue(jp.hasPrev()); jp.next(); assertTrue("b".equals(jp.curr())); assertTrue("a.b".equals(jp.origin())); assertTrue("c".equals(jp.remainder())); assertTrue(jp.hasNext()); assertTrue(jp.hasPrev()); jp.next(); assertTrue("c".equals(jp.curr())); assertTrue("a.b.c".equals(jp.origin())); assertTrue("".equals(jp.remainder())); assertFalse(jp.hasNext()); assertTrue(jp.hasPrev()); /** the first prev() after a next only changes direction. see {@link ListIterator} for details */ jp.prev(); assertTrue("c".equals(jp.curr())); assertTrue("a.b.c".equals(jp.origin())); assertTrue("".equals(jp.remainder())); assertTrue(jp.hasNext()); assertTrue(jp.hasPrev()); jp.prev(); assertTrue("b".equals(jp.curr())); assertTrue("a.b".equals(jp.origin())); assertTrue("c".equals(jp.remainder())); assertTrue(jp.hasNext()); assertTrue(jp.hasPrev()); jp.prev(); assertTrue("a".equals(jp.curr())); assertTrue("a".equals(jp.origin())); assertTrue("b.c".equals(jp.remainder())); assertTrue(jp.hasNext()); assertFalse(jp.hasPrev()); } @Test public void testSubPath() { TreePath jp = new TreePath("a.b.c", delim); assertTrue(jp.subPath(1, 2).equals("b.c")); } @Test public void testClone() throws CloneNotSupportedException { TreePath jp1 = new TreePath("a.b.c", delim); TreePath jp2 = jp1.clone(); assertTrue(jp1.equals(jp2)); jp1.next(); TreePath jp3 = jp1.clone(); assertTrue(jp1.equals(jp3)); jp1.prev(); TreePath jp4 = jp1.clone(); assertTrue(jp1.equals(jp4)); } }netplex-json-smart-v2-20dff24/json-smart/000077500000000000000000000000001475302255200203245ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/ChangeLog.txt000066400000000000000000000003261475302255200227150ustar00rootroot00000000000000Version 1.0.4 (2011/05/02) * First Public version Version 1.0.4-1 (2011/05/03) * Performance Improvement Version 1.0.4-2 (2011/05/06) * add support for non protected string starting with digits. * add Junit tests netplex-json-smart-v2-20dff24/json-smart/LICENSE.txt000066400000000000000000000261351475302255200221560ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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 http://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.netplex-json-smart-v2-20dff24/json-smart/pom.xml000066400000000000000000000237061475302255200216510ustar00rootroot00000000000000 4.0.0 net.minidev json-smart 2.5.2 JSON Small and Fast Parser JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language. bundle https://urielch.github.io/ Chemouni Uriel https://urielch.github.io/ uriel Uriel Chemouni uchemouni@gmail.com GMT+1 erav Eitan Raviv adoneitan@gmail.com GMT+2 hezhangjian Zhangjian He hezhangjian97gmail.com GMT+8 The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo All files under Apache 2 UTF-8 10 1.8 1.8 5.11.4 scm:git:https://github.com/netplex/json-smart-v2.git scm:git:https://github.com/netplex/json-smart-v2.git https://github.com/netplex/json-smart-v2 ossrh https://s01.oss.sonatype.org/content/repositories/snapshots ossrh https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ release-sign-artifacts performRelease true 53BE126D org.apache.maven.plugins maven-gpg-plugin 3.2.7 sign-artifacts verify sign org.apache.maven.plugins maven-javadoc-plugin 3.11.2 8 attach-javadocs jar org.apache.maven.plugins maven-release-plugin 3.1.1 forked-path -Psonatype-oss-release false false release deploy include-sources / true src/main/java **/*.java org.apache.maven.plugins maven-source-plugin 3.3.1 bind-sources jar-no-fork org.apache.maven.plugins maven-compiler-plugin 3.13.0 UTF-8 ${maven.compiler.source} ${maven.compiler.target} org.apache.maven.plugins maven-resources-plugin 3.3.1 UTF-8 org.apache.maven.plugins maven-jar-plugin 3.4.2 org.apache.maven.plugins maven-javadoc-plugin 3.11.2 8 false attach-javadocs jar org.apache.felix maven-bundle-plugin 5.1.9 true ${project.groupId}.${project.artifactId} ${project.artifactId} ${project.version} net.minidev.json, net.minidev.json.annotate, net.minidev.json.parser, net.minidev.json.reader, net.minidev.json.writer net.minidev.asm;version="1.0", * org.junit.jupiter junit-jupiter-api ${junit.version} test org.junit.jupiter junit-jupiter-params ${junit.version} test net.minidev accessors-smart 2.5.2 netplex-json-smart-v2-20dff24/json-smart/readme.txt000066400000000000000000000000521475302255200223170ustar00rootroot00000000000000@see: http://code.google.com/p/json-smart/netplex-json-smart-v2-20dff24/json-smart/src/000077500000000000000000000000001475302255200211135ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/000077500000000000000000000000001475302255200220375ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/000077500000000000000000000000001475302255200227605ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/000077500000000000000000000000001475302255200235465ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/000077500000000000000000000000001475302255200252015ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/000077500000000000000000000000001475302255200261525ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONArray.java000066400000000000000000000074131475302255200305720ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; import java.util.ArrayList; import java.util.List; import net.minidev.json.reader.JsonWriter; /** * A JSON array. JSONObject supports java.util.List interface. * * @author FangYidong <fangyidong@yahoo.com.cn> * @author Uriel Chemouni <uchemouni@gmail.com> */ public class JSONArray extends ArrayList implements List, JSONAwareEx, JSONStreamAwareEx { private static final long serialVersionUID = 9106884089231309568L; public JSONArray() { } public JSONArray(int initialCapacity) { super(initialCapacity); } public static String toJSONString(List list) { return toJSONString(list, JSONValue.COMPRESSION); } /** * Convert a list to JSON text. The result is a JSON array. If this list is * also a JSONAware, JSONAware specific behaviours will be omitted at this * top level. * * @see net.minidev.json.JSONValue#toJSONString(Object) * * @param list * @param compression * Indicate compression level * @return JSON text, or "null" if list is null. */ public static String toJSONString(List list, JSONStyle compression) { StringBuilder sb = new StringBuilder(); try { writeJSONString(list, sb, compression); } catch (IOException e) { // Can not append on a string builder } return sb.toString(); } /** * Encode a list into JSON text and write it to out. If this list is also a * JSONStreamAware or a JSONAware, JSONStreamAware and JSONAware specific * behaviours will be ignored at this top level. * * @see JSONValue#writeJSONString(Object, Appendable) * * @param list * @param out */ public static void writeJSONString(Iterable list, Appendable out, JSONStyle compression) throws IOException { if (list == null) { out.append("null"); return; } JsonWriter.JSONIterableWriter.writeJSONString(list, out, compression); } public static void writeJSONString(List list, Appendable out) throws IOException { writeJSONString(list, out, JSONValue.COMPRESSION); } /** * Appends the specified element and returns this. * Handy alternative to add(E e) method. * * @param element element to be appended to this array. * @return this */ public JSONArray appendElement(Object element) { add(element); return this; } public void merge(Object o2) { JSONObject.merge(this, o2); } /** * Explicitly Serialize Object as JSon String */ public String toJSONString() { return toJSONString(this, JSONValue.COMPRESSION); } public String toJSONString(JSONStyle compression) { return toJSONString(this, compression); } /** * Override native toString() */ public String toString() { return toJSONString(); } /** * JSONAwareEx interface * * @param compression * compression param */ public String toString(JSONStyle compression) { return toJSONString(compression); } public void writeJSONString(Appendable out) throws IOException { writeJSONString(this, out, JSONValue.COMPRESSION); } public void writeJSONString(Appendable out, JSONStyle compression) throws IOException { writeJSONString(this, out, compression); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONAware.java000066400000000000000000000015521475302255200305510ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ /** * Beans that support customized output of JSON text shall implement this * interface. * * @author FangYidong <fangyidong@yahoo.com.cn> */ public interface JSONAware { /** * @return JSON text */ String toJSONString(); } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONAwareEx.java000066400000000000000000000017011475302255200310420ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ /** * Beans that support advanced output of JSON text shall implement this interface. * * Adding compressions and formating features * * @author Uriel Chemouni <uchemouni@gmail.com> */ public interface JSONAwareEx extends JSONAware { /** * @return JSON text */ String toJSONString(JSONStyle compression); } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONNavi.java000066400000000000000000000402761475302255200304150ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Stack; import net.minidev.json.writer.JsonReaderI; /** * A JQuery like Json editor, accessor. * * @since 1.0.9 * * @author Uriel Chemouni <uchemouni@gmail.com> */ public class JSONNavi { private JsonReaderI mapper; private T root; private Stack stack = new Stack(); private Stack path = new Stack(); private Object current; private boolean failure = false; private String failureMessage; private boolean readonly = false; private Object missingKey = null; public static JSONNavi newInstance() { return new JSONNavi(JSONValue.defaultReader.DEFAULT_ORDERED); } public static JSONNavi newInstanceObject() { JSONNavi o = new JSONNavi(JSONValue.defaultReader.getMapper(JSONObject.class)); o.object(); return o; } public static JSONNavi newInstanceArray() { JSONNavi o = new JSONNavi(JSONValue.defaultReader.getMapper(JSONArray.class)); o.array(); return o; } public JSONNavi(JsonReaderI mapper) { this.mapper = mapper; } @SuppressWarnings("unchecked") public JSONNavi(String json) { this.root = (T) JSONValue.parse(json); this.current = this.root; readonly = true; } public JSONNavi(String json, JsonReaderI mapper) { this.root = JSONValue.parse(json, mapper); this.mapper = mapper; this.current = this.root; readonly = true; } public JSONNavi(String json, Class mapTo) { this.root = JSONValue.parse(json, mapTo); this.mapper = JSONValue.defaultReader.getMapper(mapTo); this.current = this.root; readonly = true; } /** * return to root node * * @return the root node */ public JSONNavi root() { this.current = this.root; this.stack.clear(); this.path.clear(); this.failure = false; this.missingKey = null; this.failureMessage = null; return this; } public boolean hasFailure() { return failure; } public Object getCurrentObject() { return current; } @SuppressWarnings({ "unchecked", "rawtypes" }) public Collection getKeys() { if (current instanceof Map) return ((Map) current).keySet(); return null; } public int getSize() { if (current == null) return 0; if (isArray()) return ((List) current).size(); if (isObject()) return ((Map) current).size(); return 1; } public String getString(String key) { String v = null; if (!hasKey(key)) return v; at(key); v = asString(); up(); return v; } public int getInt(String key) { int v = 0; if (!hasKey(key)) return v; at(key); v = asInt(); up(); return v; } public Integer getInteger(String key) { Integer v = null; if (!hasKey(key)) return v; at(key); v = asIntegerObj(); up(); return v; } public double getDouble(String key) { double v = 0; if (!hasKey(key)) return v; at(key); v = asDouble(); up(); return v; } public boolean hasKey(String key) { if (!isObject()) return false; return o(current).containsKey(key); } public JSONNavi at(String key) { if (failure) return this; if (!isObject()) object(); if (!(current instanceof Map)) return failure("current node is not an Object", key); if (!o(current).containsKey(key)) { if (readonly) return failure("current Object have no key named " + key, key); stack.add(current); path.add(key); current = null; missingKey = key; return this; } Object next = o(current).get(key); stack.add(current); path.add(key); current = next; return this; } public Object get(String key) { if (failure) return this; if (!isObject()) object(); if (!(current instanceof Map)) return failure("current node is not an Object", key); return o(current).get(key); } public Object get(int index) { if (failure) return this; if (!isArray()) array(); if (!(current instanceof List)) return failure("current node is not an List", index); return a(current).get(index); } public JSONNavi set(String key, String value) { object(); if (failure) return this; o(current).put(key, value); return this; } public JSONNavi set(String key, Number value) { object(); if (failure) return this; o(current).put(key, value); return this; } /** * write an value in the current object * * @param key * key to access * @param value * new value * @return this */ public JSONNavi set(String key, long value) { return set(key, Long.valueOf(value)); } /** * write an value in the current object * * @param key * key to access * @param value * new value * @return this */ public JSONNavi set(String key, int value) { return set(key, Integer.valueOf(value)); } /** * write an value in the current object * * @param key * key to access * @param value * new value * @return this */ public JSONNavi set(String key, double value) { return set(key, Double.valueOf(value)); } /** * write an value in the current object * * @param key * key to access * @param value * new value * @return this */ public JSONNavi set(String key, float value) { return set(key, Float.valueOf(value)); } /** * add value to the current arrays * * @param values * to add * @return this */ public JSONNavi add(Object... values) { array(); if (failure) return this; List list = a(current); for (Object o : values) list.add(o); return this; } /** * get the current object value as String if the current Object is null * return null. * * @return value as string */ public String asString() { if (current == null) return null; if (current instanceof String) return (String) current; return current.toString(); } /** * get the current value as double if the current Object is null return * Double.NaN * * @return value as double */ public double asDouble() { if (current instanceof Number) return ((Number) current).doubleValue(); return Double.NaN; } /** * get the current object value as Double if the current Double can not be * cast as Integer return null. * * @return value as Double */ public Double asDoubleObj() { if (current == null) return null; if (current instanceof Number) { if (current instanceof Double) return (Double) current; return Double.valueOf(((Number) current).doubleValue()); } return Double.NaN; } /** * get the current value as float if the current Object is null return * Float.NaN * * @return value as float */ public float asFloat() { if (current instanceof Number) return ((Number) current).floatValue(); return Float.NaN; } /** * get the current object value as Float if the current Float can not be * cast as Integer return null. */ public Float asFloatObj() { if (current == null) return null; if (current instanceof Number) { if (current instanceof Float) return (Float) current; return Float.valueOf(((Number) current).floatValue()); } return Float.NaN; } /** * get the current value as int if the current Object is null return 0 * * @return value as Int */ public int asInt() { if (current instanceof Number) return ((Number) current).intValue(); return 0; } /** * get the current object value as Integer if the current Object can not be * cast as Integer return null. * @return the current node value as an Integer */ public Integer asIntegerObj() { if (current == null) return null; if (current instanceof Number) { if (current instanceof Integer) return (Integer) current; if (current instanceof Long) { Long l = (Long) current; if (l.longValue() == l.intValue()) { return Integer.valueOf(l.intValue()); } } return null; } return null; } /** * get the current value as long if the current Object is null return 0 * * @return value as long */ public long asLong() { if (current instanceof Number) return ((Number) current).longValue(); return 0L; } /** * get the current object value as Long if the current Object can not be * cast as Long return null. * * @return value as Long */ public Long asLongObj() { if (current == null) return null; if (current instanceof Number) { if (current instanceof Long) return (Long) current; if (current instanceof Integer) return Long.valueOf(((Number) current).longValue()); return null; } return null; } /** * get the current value as boolean if the current Object is null or is not * a boolean return false * * @return boolean */ public boolean asBoolean() { if (current instanceof Boolean) return ((Boolean) current).booleanValue(); return false; } /** * get the current object value as Boolean if the current Object is not a * Boolean return null. * * @return Boolean object */ public Boolean asBooleanObj() { if (current == null) return null; if (current instanceof Boolean) return (Boolean) current; return null; } /** * Set current value as Json Object You can also skip this call, Objects can * be create automatically. * @return the current node as an object */ @SuppressWarnings("unchecked") public JSONNavi object() { if (failure) return this; if (current == null && readonly) failure("Can not create Object child in readonly", null); if (current != null) { if (isObject()) return this; if (isArray()) failure("can not use Object feature on Array.", null); failure("Can not use current position as Object", null); } else { current = mapper.createObject(); } if (root == null) root = (T) current; else store(); return this; } /** * Set current value as Json Array You can also skip this call Arrays can be * create automatically. * * @return the current node as an array */ @SuppressWarnings("unchecked") public JSONNavi array() { if (failure) return this; if (current == null && readonly) failure("Can not create Array child in readonly", null); if (current != null) { if (isArray()) return this; if (isObject()) failure("can not use Object feature on Array.", null); failure("Can not use current position as Object", null); } else { current = mapper.createArray(); } if (root == null) root = (T) current; else store(); return this; } /** * set current value as Number * @param num new value for the current node * @return this for code chaining */ public JSONNavi set(Number num) { if (failure) return this; current = num; store(); return this; } /** * set current value as Boolean * @param bool new value for the current node * * @return this for code chaining */ public JSONNavi set(Boolean bool) { if (failure) return this; current = bool; store(); return this; } /** * set current value as String * @param text text value * * @return this for code chaining */ public JSONNavi set(String text) { if (failure) return this; current = text; store(); return this; } public T getRoot() { return root; } /** * internal store current Object in current non existing localization */ private void store() { Object parent = stack.peek(); if (isObject(parent)) o(parent).put((String) missingKey, current); else if (isArray(parent)) { int index = ((Number) missingKey).intValue(); List lst = a(parent); while (lst.size() <= index) lst.add(null); lst.set(index, current); } } /** * is the current node is an array * * @return true if the current node is an array */ public boolean isArray() { return isArray(current); } /** * is the current node is an object * * @return true if the current node is an object */ public boolean isObject() { return isObject(current); } /** * check if Object is an Array * * @return true if the object is an array */ private boolean isArray(Object obj) { if (obj == null) return false; return (obj instanceof List); } /** * check if Object is an Map * @return true if the object node is an object */ private boolean isObject(Object obj) { if (obj == null) return false; return (obj instanceof Map); } /** * internal cast to List * @return casted object */ @SuppressWarnings("unchecked") private List a(Object obj) { return (List) obj; } /** * internal cast to Map */ @SuppressWarnings("unchecked") private Map o(Object obj) { return (Map) obj; } /** * Access to the index position. * * If index is less than 0 access element index from the end like in python. * * @param index * 0 based desired position in Array */ public JSONNavi at(int index) { if (failure) return this; if (!(current instanceof List)) return failure("current node is not an Array", index); @SuppressWarnings("unchecked") List lst = ((List) current); if (index < 0) { index = lst.size() + index; if (index < 0) index = 0; } if (index >= lst.size()) if (readonly) return failure("Out of bound exception for index", index); else { stack.add(current); path.add(index); current = null; missingKey = index; return this; } Object next = lst.get(index); stack.add(current); path.add(index); current = next; return this; } /** * Access to last + 1 the index position. * * this method can only be used in writing mode. */ public JSONNavi atNext() { if (failure) return this; if (!(current instanceof List)) return failure("current node is not an Array", null); @SuppressWarnings("unchecked") List lst = ((List) current); return at(lst.size()); } /** * call up() level times. * * @param level * number of parent move. */ public JSONNavi up(int level) { while (level-- > 0) { if (stack.size() > 0) { current = stack.pop(); path.pop(); } else break; } return this; } /** * Move one level up in Json tree. if no more level up is available the * statement had no effect. */ public JSONNavi up() { if (stack.size() > 0) { current = stack.pop(); path.pop(); } return this; } private final static JSONStyle ERROR_COMPRESS = new JSONStyle(JSONStyle.FLAG_PROTECT_4WEB); /** * return the Object as a Json String */ public String toString() { if (failure) return JSONValue.toJSONString(failureMessage, ERROR_COMPRESS); return JSONValue.toJSONString(root); } /** * return the Object as a Json String * * @param compression */ public String toString(JSONStyle compression) { if (failure) return JSONValue.toJSONString(failureMessage, compression); return JSONValue.toJSONString(root, compression); } /** * Internally log errors. */ private JSONNavi failure(String err, Object jPathPostfix) { failure = true; StringBuilder sb = new StringBuilder(); sb.append("Error: "); sb.append(err); sb.append(" at "); sb.append(getJPath()); if (jPathPostfix != null) if (jPathPostfix instanceof Integer) sb.append('[').append(jPathPostfix).append(']'); else sb.append('/').append(jPathPostfix); this.failureMessage = sb.toString(); return this; } /** * @return JPath to the current position */ public String getJPath() { StringBuilder sb = new StringBuilder(); for (Object o : path) { if (o instanceof String) sb.append('/').append(o.toString()); else sb.append('[').append(o.toString()).append(']'); } return sb.toString(); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONObject.java000066400000000000000000000163341475302255200307240ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; import java.util.HashMap; import java.util.Map; import net.minidev.json.reader.JsonWriter; /** * A JSON object. Key value pairs are unordered. JSONObject supports * java.util.Map interface. * * @author FangYidong <fangyidong@yahoo.com.cn> * @author Uriel Chemouni <uchemouni@gmail.com> */ public class JSONObject extends HashMap implements JSONAwareEx, JSONStreamAwareEx { private static final long serialVersionUID = -503443796854799292L; public JSONObject() { super(); } public JSONObject(int initialCapacity) { super(initialCapacity); } /** * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters * (U+0000 through U+001F). It's the same as JSONValue.escape() only for * compatibility here. * * @see JSONValue#escape(String) */ public static String escape(String s) { return JSONValue.escape(s); } public static String toJSONString(Map map) { return toJSONString(map, JSONValue.COMPRESSION); } /** * Convert a map to JSON text. The result is a JSON object. If this map is * also a JSONAware, JSONAware specific behaviours will be omitted at this * top level. * * @see net.minidev.json.JSONValue#toJSONString(Object) * * @param map * @return JSON text, or "null" if map is null. */ public static String toJSONString(Map map, JSONStyle compression) { StringBuilder sb = new StringBuilder(); try { writeJSON(map, sb, compression); } catch (IOException e) { // can not append on a StringBuilder } return sb.toString(); } /** * Write a Key : value entry to a stream */ public static void writeJSONKV(String key, Object value, Appendable out, JSONStyle compression) throws IOException { if (key == null) out.append("null"); else if (!compression.mustProtectKey(key)) out.append(key); else { out.append('"'); JSONValue.escape(key, out, compression); out.append('"'); } out.append(':'); if (value instanceof String) compression.writeString(out, (String) value); else JSONValue.writeJSONString(value, out, compression); } /** * Puts value to object and returns this. * Handy alternative to put(String key, Object value) method. * * @param fieldName key with which the specified value is to be associated * @param fieldValue value to be associated with the specified key * @return this */ public JSONObject appendField(String fieldName, Object fieldValue) { put(fieldName, fieldValue); return this; } /** * A Simple Helper object to String * * @return a value.toString() or null */ public String getAsString(String key) { Object obj = this.get(key); if (obj == null) return null; return obj.toString(); } /** * A Simple Helper cast an Object to an Number * * @return a Number or null */ public Number getAsNumber(String key) { Object obj = this.get(key); if (obj == null) return null; if (obj instanceof Number) return (Number)obj; return Long.valueOf(obj.toString()); } // /** // * return a Key:value entry as stream // */ // public static String toString(String key, Object value) { // return toString(key, value, JSONValue.COMPRESSION); // } // /** // * return a Key:value entry as stream // */ // public static String toString(String key, Object value, JSONStyle // compression) { // StringBuilder sb = new StringBuilder(); // try { // writeJSONKV(key, value, sb, compression); // } catch (IOException e) { // // can not append on a StringBuilder // } // return sb.toString(); // } /** * Allows creation of a JSONObject from a Map. After that, both the * generated JSONObject and the Map can be modified independently. */ public JSONObject(Map map) { super(map); } public static void writeJSON(Map map, Appendable out) throws IOException { writeJSON(map, out, JSONValue.COMPRESSION); } /** * Encode a map into JSON text and write it to out. If this map is also a * JSONAware or JSONStreamAware, JSONAware or JSONStreamAware specific * behaviours will be ignored at this top level. * * @see JSONValue#writeJSONString(Object, Appendable) */ public static void writeJSON(Map map, Appendable out, JSONStyle compression) throws IOException { if (map == null) { out.append("null"); return; } JsonWriter.JSONMapWriter.writeJSONString(map, out, compression); } /** * serialize Object as json to an stream */ public void writeJSONString(Appendable out) throws IOException { writeJSON(this, out, JSONValue.COMPRESSION); } /** * serialize Object as json to an stream */ public void writeJSONString(Appendable out, JSONStyle compression) throws IOException { writeJSON(this, out, compression); } public void merge(Object o2) { merge(this, o2); } protected static JSONObject merge(JSONObject o1, Object o2) { if (o2 == null) return o1; if (o2 instanceof JSONObject) return merge(o1, (JSONObject) o2); throw new RuntimeException("JSON merge can not merge JSONObject with " + o2.getClass()); } private static JSONObject merge(JSONObject o1, JSONObject o2) { if (o2 == null) return o1; for (String key : o1.keySet()) { Object value1 = o1.get(key); Object value2 = o2.get(key); if (value2 == null) continue; if (value1 instanceof JSONArray) { o1.put(key, merge((JSONArray) value1, value2)); continue; } if (value1 instanceof JSONObject) { o1.put(key, merge((JSONObject) value1, value2)); continue; } if (value1.equals(value2)) continue; if (value1.getClass() .equals(value2.getClass())) throw new RuntimeException("JSON merge can not merge two " + value1.getClass().getName() + " Object together"); throw new RuntimeException("JSON merge can not merge " + value1.getClass().getName() + " with " + value2.getClass().getName()); } for (String key : o2.keySet()) { if (o1.containsKey(key)) continue; o1.put(key, o2.get(key)); } return o1; } protected static JSONArray merge(JSONArray o1, Object o2) { if (o2 == null) return o1; if (o1 instanceof JSONArray) return merge(o1, (JSONArray) o2); o1.add(o2); return o1; } private static JSONArray merge(JSONArray o1, JSONArray o2) { o1.addAll(o2); return o1; } public String toJSONString() { return toJSONString(this, JSONValue.COMPRESSION); } public String toJSONString(JSONStyle compression) { return toJSONString(this, compression); } public String toString(JSONStyle compression) { return toJSONString(this, compression); } public String toString() { return toJSONString(this, JSONValue.COMPRESSION); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONStreamAware.java000066400000000000000000000017031475302255200317230ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; /** * Beans that support customized output of JSON text to a writer shall implement * this interface. * * @author FangYidong <fangyidong@yahoo.com.cn> */ public interface JSONStreamAware { /** * write JSON string to out. */ void writeJSONString(Appendable out) throws IOException; } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONStreamAwareEx.java000066400000000000000000000017641475302255200322270ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; /** * Beans that support customized output of JSON text to a writer shall implement * this interface. * * @author FangYidong <fangyidong@yahoo.com.cn> */ public interface JSONStreamAwareEx extends JSONStreamAware { /** * write JSON string to out. */ void writeJSONString(Appendable out, JSONStyle compression) throws IOException; } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONStyle.java000066400000000000000000000107361475302255200306160ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; import net.minidev.json.JStylerObj.MustProtect; import net.minidev.json.JStylerObj.StringProtector; /** * JSONStyle object configure JSonSerializer reducing output size * * @author Uriel Chemouni <uchemouni@gmail.com> */ public class JSONStyle { /** * for advanced usage sample see * * #see net.minidev.json.test.TestCompressorFlags */ public final static int FLAG_PROTECT_KEYS = 1; public final static int FLAG_PROTECT_4WEB = 2; public final static int FLAG_PROTECT_VALUES = 4; /** * AGRESSIVE have no effect without PROTECT_KEYS or PROTECT_VALUE * * AGRESSIVE mode allows Json-smart to not protect String containing * special chars */ public final static int FLAG_AGRESSIVE = 8; /** * @since 2.1 */ public final static int FLAG_IGNORE_NULL = 16; public final static JSONStyle NO_COMPRESS = new JSONStyle(0); public final static JSONStyle MAX_COMPRESS = new JSONStyle(-1); /** * @since 1.0.9.1 */ public final static JSONStyle LT_COMPRESS = new JSONStyle(FLAG_PROTECT_4WEB); private boolean _protectKeys; private boolean _protect4Web; private boolean _protectValues; private boolean _ignore_null; private MustProtect mpKey; private MustProtect mpValue; private StringProtector esc; public JSONStyle(int FLAG) { _protectKeys = (FLAG & FLAG_PROTECT_KEYS) == 0; _protectValues = (FLAG & FLAG_PROTECT_VALUES) == 0; _protect4Web = (FLAG & FLAG_PROTECT_4WEB) == 0; _ignore_null = (FLAG & FLAG_IGNORE_NULL) > 0; MustProtect mp; if ((FLAG & FLAG_AGRESSIVE) > 0) mp = JStylerObj.MP_AGGRESIVE; else mp = JStylerObj.MP_SIMPLE; if (_protectValues) mpValue = JStylerObj.MP_TRUE; else mpValue = mp; if (_protectKeys) mpKey = JStylerObj.MP_TRUE; else mpKey = mp; if (_protect4Web) esc = JStylerObj.ESCAPE4Web; else esc = JStylerObj.ESCAPE_LT; } public JSONStyle() { this(0); } public boolean protectKeys() { return _protectKeys; } public boolean protectValues() { return _protectValues; } public boolean protect4Web() { return _protect4Web; } public boolean ignoreNull() { return _ignore_null; } public boolean indent() { return false; } public boolean mustProtectKey(String s) { return mpKey.mustBeProtect(s); } public boolean mustProtectValue(String s) { return mpValue.mustBeProtect(s); } public void writeString(Appendable out, String value) throws IOException { if (!this.mustProtectValue(value)) out.append(value); else { out.append('"'); JSONValue.escape(value, out, this); out.append('"'); } } public void escape(String s, Appendable out) { esc.escape(s, out); } /** * begin Object */ public void objectStart(Appendable out) throws IOException { out.append('{'); } /** * terminate Object */ public void objectStop(Appendable out) throws IOException { out.append('}'); } /** * Start the first Object element */ public void objectFirstStart(Appendable out) throws IOException { } /** * Start a new Object element */ public void objectNext(Appendable out) throws IOException { out.append(','); } /** * End Of Object element */ public void objectElmStop(Appendable out) throws IOException { } /** * end of Key in json Object */ public void objectEndOfKey(Appendable out) throws IOException { out.append(':'); } /** * Array start */ public void arrayStart(Appendable out) throws IOException { out.append('['); } /** * Array Done */ public void arrayStop(Appendable out) throws IOException { out.append(']'); } /** * Start the first Array element */ public void arrayfirstObject(Appendable out) throws IOException { } /** * Start a new Array element */ public void arrayNextElm(Appendable out) throws IOException { out.append(','); } /** * End of an Array element */ public void arrayObjectEnd(Appendable out) throws IOException { } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONUtil.java000066400000000000000000000171441475302255200304330ustar00rootroot00000000000000package net.minidev.json; import java.lang.reflect.Field; import java.lang.reflect.Method; import net.minidev.asm.FieldFilter; import net.minidev.json.annotate.JsonIgnore; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ public class JSONUtil { @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object convertToStrict(Object obj, Class dest) { if (obj == null) return null; if (dest.isAssignableFrom(obj.getClass())) return obj; if (dest.isPrimitive()) { if (dest == int.class) if (obj instanceof Number) return ((Number) obj).intValue(); else return Integer.valueOf(obj.toString()); else if (dest == short.class) if (obj instanceof Number) return ((Number) obj).shortValue(); else return Short.valueOf(obj.toString()); else if (dest == long.class) if (obj instanceof Number) return ((Number) obj).longValue(); else return Long.valueOf(obj.toString()); else if (dest == byte.class) if (obj instanceof Number) return ((Number) obj).byteValue(); else return Byte.valueOf(obj.toString()); else if (dest == float.class) if (obj instanceof Number) return ((Number) obj).floatValue(); else return Float.valueOf(obj.toString()); else if (dest == double.class) if (obj instanceof Number) return ((Number) obj).doubleValue(); else return Double.valueOf(obj.toString()); else if (dest == char.class) { String asString = dest.toString(); if (asString.length() > 0) return Character.valueOf(asString.charAt(0)); } else if (dest == boolean.class) { return (Boolean) obj; } throw new RuntimeException("Primitive: Can not convert " + obj.getClass().getName() + " to " + dest.getName()); } else { if (dest.isEnum()) return Enum.valueOf((Class) dest, obj.toString()); if (dest == Integer.class) if (obj instanceof Number) return Integer.valueOf(((Number) obj).intValue()); else return Integer.valueOf(obj.toString()); if (dest == Long.class) if (obj instanceof Number) return Long.valueOf(((Number) obj).longValue()); else return Long.valueOf(obj.toString()); if (dest == Short.class) if (obj instanceof Number) return Short.valueOf(((Number) obj).shortValue()); else return Short.valueOf(obj.toString()); if (dest == Byte.class) if (obj instanceof Number) return Byte.valueOf(((Number) obj).byteValue()); else return Byte.valueOf(obj.toString()); if (dest == Float.class) if (obj instanceof Number) return Float.valueOf(((Number) obj).floatValue()); else return Float.valueOf(obj.toString()); if (dest == Double.class) if (obj instanceof Number) return Double.valueOf(((Number) obj).doubleValue()); else return Double.valueOf(obj.toString()); if (dest == Character.class) { String asString = dest.toString(); if (asString.length() > 0) return Character.valueOf(asString.charAt(0)); } throw new RuntimeException("Object: Can not Convert " + obj.getClass().getName() + " to " + dest.getName()); } } @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object convertToX(Object obj, Class dest) { if (obj == null) return null; if (dest.isAssignableFrom(obj.getClass())) return obj; if (dest.isPrimitive()) { if (obj instanceof Number) return obj; if (dest == int.class) return Integer.valueOf(obj.toString()); else if (dest == short.class) return Short.valueOf(obj.toString()); else if (dest == long.class) return Long.valueOf(obj.toString()); else if (dest == byte.class) return Byte.valueOf(obj.toString()); else if (dest == float.class) return Float.valueOf(obj.toString()); else if (dest == double.class) return Double.valueOf(obj.toString()); else if (dest == char.class) { String asString = dest.toString(); if (asString.length() > 0) return Character.valueOf(asString.charAt(0)); } else if (dest == boolean.class) { return (Boolean) obj; } throw new RuntimeException("Primitive: Can not convert " + obj.getClass().getName() + " to " + dest.getName()); } else { if (dest.isEnum()) return Enum.valueOf((Class) dest, obj.toString()); if (dest == Integer.class) if (obj instanceof Number) return Integer.valueOf(((Number) obj).intValue()); else return Integer.valueOf(obj.toString()); if (dest == Long.class) if (obj instanceof Number) return Long.valueOf(((Number) obj).longValue()); else return Long.valueOf(obj.toString()); if (dest == Short.class) if (obj instanceof Number) return Short.valueOf(((Number) obj).shortValue()); else return Short.valueOf(obj.toString()); if (dest == Byte.class) if (obj instanceof Number) return Byte.valueOf(((Number) obj).byteValue()); else return Byte.valueOf(obj.toString()); if (dest == Float.class) if (obj instanceof Number) return Float.valueOf(((Number) obj).floatValue()); else return Float.valueOf(obj.toString()); if (dest == Double.class) if (obj instanceof Number) return Double.valueOf(((Number) obj).doubleValue()); else return Double.valueOf(obj.toString()); if (dest == Character.class) { String asString = dest.toString(); if (asString.length() > 0) return Character.valueOf(asString.charAt(0)); } throw new RuntimeException("Object: Can not Convert " + obj.getClass().getName() + " to " + dest.getName()); } } public final static JsonSmartFieldFilter JSON_SMART_FIELD_FILTER = new JsonSmartFieldFilter(); public static class JsonSmartFieldFilter implements FieldFilter { public boolean canUse(Field field) { JsonIgnore ignore = field.getAnnotation(JsonIgnore.class); if (ignore != null && ignore.value()) return false; return true; } public boolean canUse(Field field, Method method) { JsonIgnore ignore = method.getAnnotation(JsonIgnore.class); if (ignore != null && ignore.value()) return false; return true; } public boolean canRead(Field field) { return true; } public boolean canWrite(Field field) { return true; } } public static String getSetterName(String key) { int len = key.length(); char[] b = new char[len + 3]; b[0] = 's'; b[1] = 'e'; b[2] = 't'; char c = key.charAt(0); if (c >= 'a' && c <= 'z') c += 'A' - 'a'; b[3] = c; for (int i = 1; i < len; i++) { b[i + 3] = key.charAt(i); } return new String(b); } public static String getGetterName(String key) { int len = key.length(); char[] b = new char[len + 3]; b[0] = 'g'; b[1] = 'e'; b[2] = 't'; char c = key.charAt(0); if (c >= 'a' && c <= 'z') c += 'A' - 'a'; b[3] = c; for (int i = 1; i < len; i++) { b[i + 3] = key.charAt(i); } return new String(b); } public static String getIsName(String key) { int len = key.length(); char[] b = new char[len + 2]; b[0] = 'i'; b[1] = 's'; char c = key.charAt(0); if (c >= 'a' && c <= 'z') c += 'A' - 'a'; b[2] = c; for (int i = 1; i < len; i++) { b[i + 2] = key.charAt(i); } return new String(b); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JSONValue.java000066400000000000000000000425271475302255200305750ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE; import static net.minidev.json.parser.JSONParser.MODE_RFC4627; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.List; import java.util.Map; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import net.minidev.json.reader.JsonWriter; import net.minidev.json.reader.JsonWriterI; import net.minidev.json.writer.CompessorMapper; import net.minidev.json.writer.FakeMapper; import net.minidev.json.writer.JsonReader; import net.minidev.json.writer.JsonReaderI; import net.minidev.json.writer.UpdaterMapper; /** * JSONValue is the helper class In most of case you should use those static * method to user JSON-smart * * * The most commonly use method are {@link #parse(String)} * {@link #toJSONString(Object)} * * @author Uriel Chemouni <uchemouni@gmail.com> */ public class JSONValue { /** * Global default compression type */ public static JSONStyle COMPRESSION = JSONStyle.NO_COMPRESS; /** * Parse JSON text into java object from the input source. Please use * parseWithException() if you don't want to ignore the exception. if you * want strict input check use parseStrict() * * @see JSONParser#parse(Reader) * @see #parseWithException(Reader) * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null * */ public static Object parse(InputStream in) { try { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in); } catch (Exception e) { return null; } } /** * Parse JSON text into java object from the input source. Please use * parseWithException() if you don't want to ignore the exception. if you * want strict input check use parseStrict() * * @see JSONParser#parse(Reader) * @see #parseWithException(Reader) * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null * */ public static Object parse(byte[] in) { try { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * mapTo can be a bean * * @since 2.0 */ public static T parse(InputStream in, Class mapTo) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, defaultReader.getMapper(mapTo)); } catch (Exception e) { return null; } } /** * Parse JSON text into java object from the input source. Please use * parseWithException() if you don't want to ignore the exception. if you * want strict input check use parseStrict() * * @see JSONParser#parse(Reader) * @see #parseWithException(Reader) * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null * */ public static Object parse(Reader in) { try { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * mapTo can be a bean * * @since 2.0 */ public static T parse(byte[] in, Class mapTo) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, defaultReader.getMapper(mapTo)); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * mapTo can be a bean * * @since 2.0 */ public static T parse(Reader in, Class mapTo) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, defaultReader.getMapper(mapTo)); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * mapTo can be a bean * * @since 2.0 */ public static T parse(Reader in, T toUpdate) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, new UpdaterMapper(defaultReader, toUpdate)); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * @since 2.0 */ protected static T parse(Reader in, JsonReaderI mapper) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, mapper); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * mapTo can be a bean * * @since 2.0 */ public static T parse(String in, Class mapTo) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, defaultReader.getMapper(mapTo)); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * mapTo can be a bean * * @since 2.0 */ public static T parse(InputStream in, T toUpdate) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, new UpdaterMapper(defaultReader, toUpdate)); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * mapTo can be a bean * * @since 2.0 */ public static T parse(String in, T toUpdate) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, new UpdaterMapper(defaultReader, toUpdate)); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * @since 2.0 */ protected static T parse(byte[] in, JsonReaderI mapper) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, mapper); } catch (Exception e) { return null; } } /** * Parse input json as a mapTo class * * @since 2.0 */ protected static T parse(String in, JsonReaderI mapper) { try { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, mapper); } catch (Exception e) { return null; } } /** * Parse JSON text into java object from the input source. Please use * parseWithException() if you don't want to ignore the exception. if you * want strict input check use parseStrict() * * @see JSONParser#parse(String) * @see #parseWithException(String) * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null * */ public static Object parse(String s) { try { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(s); } catch (Exception e) { return null; } } /** * Parse Json input to a java Object keeping element order * * @param in json source * * @return a OrderedMap preserving field order. * * @since 1.0.6.1 */ public static Object parseKeepingOrder(Reader in) { try { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in, defaultReader.DEFAULT_ORDERED); } catch (Exception e) { return null; } } /** * Parse Json input to a java Object keeping element order * * @param in json source * * @return a OrderedMap preserving field order.\ * * @since 1.0.6.1 */ public static Object parseKeepingOrder(String in) { try { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in, defaultReader.DEFAULT_ORDERED); } catch (Exception e) { return null; } } /** * Reformat Json input keeping element order * * @param input text to parse * @param style parse options * * @since 1.0.6.2 * * @return json string */ public static String compress(String input, JSONStyle style) { try { StringBuilder sb = new StringBuilder(); new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(input, new CompessorMapper(defaultReader, sb, style)); return sb.toString(); } catch (Exception e) { return input; } } /** * Compress Json input keeping element order * * @param input text to parse * * @since 1.0.6.1 * * need to be rewrite in 2.0 */ public static String compress(String input) { return compress(input, JSONStyle.MAX_COMPRESS); } /** * Compress Json input keeping element order * @param input text to parse * * @since 1.0.6.1 */ public static String uncompress(String input) { return compress(input, JSONStyle.NO_COMPRESS); } /** * Parse JSON text into java object from the input source. * * @param in source to parse * * @see JSONParser * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null */ public static Object parseWithException(byte[] in) throws IOException, ParseException { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in, defaultReader.DEFAULT); } /** * Parse JSON text into java object from the input source. * * @param in source to parse * @see JSONParser * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null */ public static Object parseWithException(InputStream in) throws IOException, ParseException { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in, defaultReader.DEFAULT); } /** * Parse JSON text into java object from the input source. * * @param in source to parse * * @see JSONParser * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null */ public static Object parseWithException(Reader in) throws IOException, ParseException { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in, defaultReader.DEFAULT); } /** * Parse JSON text into java object from the input source. * * @param input string to parse * @see JSONParser * * @throws ParseException if input in invalid * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null */ public static Object parseWithException(String input) throws ParseException { return new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(input, defaultReader.DEFAULT); } /** * Parse input json as a mapTo class * * @param in source to parse * @param mapTo destination type, mapTo can be a javabean * * @since 2.0 * * @return unserialized object of type mapTo */ public static T parseWithException(String in, Class mapTo) throws ParseException { JSONParser p = new JSONParser(DEFAULT_PERMISSIVE_MODE); return p.parse(in, defaultReader.getMapper(mapTo)); } /** * Parse valid RFC4627 JSON text into java object from the input source. * * @param in source to parse * @see JSONParser * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null */ public static Object parseStrict(Reader in) throws IOException, ParseException { return new JSONParser(MODE_RFC4627).parse(in, defaultReader.DEFAULT); } /** * Parse valid RFC4627 JSON text into java object from the input source. * * @param s source to parse * @see JSONParser * * @return Instance of the following: JSONObject, JSONArray, String, * java.lang.Number, java.lang.Boolean, null */ public static Object parseStrict(String s) throws ParseException { return new JSONParser(MODE_RFC4627).parse(s, defaultReader.DEFAULT); } /** * Check RFC4627 Json Syntax from input Reader * * @return if the input is valid */ public static boolean isValidJsonStrict(Reader in) throws IOException { try { new JSONParser(MODE_RFC4627).parse(in, FakeMapper.DEFAULT); return true; } catch (ParseException e) { return false; } } /** * check RFC4627 Json Syntax from input String * * @return if the input is valid */ public static boolean isValidJsonStrict(String s) { try { new JSONParser(MODE_RFC4627).parse(s, FakeMapper.DEFAULT); return true; } catch (ParseException e) { return false; } } /** * Check Json Syntax from input Reader * * @return if the input is valid */ public static boolean isValidJson(Reader in) throws IOException { try { new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(in, FakeMapper.DEFAULT); return true; } catch (ParseException e) { return false; } } /** * Check Json Syntax from input String * * @return if the input is valid */ public static boolean isValidJson(String s) { try { new JSONParser(DEFAULT_PERMISSIVE_MODE).parse(s, FakeMapper.DEFAULT); return true; } catch (ParseException e) { return false; } } /** * Encode an object into JSON text and write it to out. *

* If this object is a Map or a List, and it's also a JSONStreamAware or a * JSONAware, JSONStreamAware or JSONAware will be considered firstly. *

* * @see JSONObject#writeJSON(Map, Appendable) * @see JSONArray#writeJSONString(List, Appendable) */ public static void writeJSONString(Object value, Appendable out) throws IOException { writeJSONString(value, out, COMPRESSION); } /** * Serialisation class Data */ public final static JsonWriter defaultWriter = new JsonWriter(); /** * deserialisation class Data */ public final static JsonReader defaultReader = new JsonReader(); /** * Remap field from java to json, useful to avoid protected keyword in java class. * * @since 2.1.1 * @param type type to alter * @param jsonFieldName field name in json * @param javaFieldName field name in java */ public static void remapField(Class type, String jsonFieldName, String javaFieldName) { defaultReader.remapField(type, jsonFieldName, javaFieldName); defaultWriter.remapField(type, javaFieldName, jsonFieldName); } /** * Register a serializer for a class. */ public static void registerWriter(Class cls, JsonWriterI writer) { defaultWriter.registerWriter(writer, cls); } /** * register a deserializer for a class. */ public static void registerReader(Class type, JsonReaderI mapper) { defaultReader.registerReader(type, mapper); } /** * Encode an object into JSON text and write it to out. *

* If this object is a Map or a List, and it's also a JSONStreamAware or a * JSONAware, JSONStreamAware or JSONAware will be considered firstly. *

* * @see JSONObject#writeJSON(Map, Appendable) * @see JSONArray#writeJSONString(List, Appendable) */ @SuppressWarnings("unchecked") public static void writeJSONString(Object value, Appendable out, JSONStyle compression) throws IOException { if (value == null) { out.append("null"); return; } Class clz = value.getClass(); @SuppressWarnings("rawtypes") JsonWriterI w = defaultWriter.getWrite(clz); if (w == null) { if (clz.isArray()) w = JsonWriter.arrayWriter; else { w = defaultWriter.getWriterByInterface(value.getClass()); if (w == null) w = JsonWriter.beansWriterASM; // w = JsonWriter.beansWriter; } defaultWriter.registerWriter(w, clz); } w.writeJSONString(value, out, compression); } /** * Encode an object into JSON text and write it to out. *

* If this object is a Map or a List, and it's also a JSONStreamAware or a * JSONAware, JSONStreamAware or JSONAware will be considered firstly. *

* * @param value object to serialize * * @return json string * * @see JSONObject#writeJSON(Map, Appendable) * @see JSONArray#writeJSONString(List, Appendable) */ public static String toJSONString(Object value) { return toJSONString(value, COMPRESSION); } /** * Convert an object to JSON text. *

* If this object is a Map or a List, and it's also a JSONAware, JSONAware * will be considered firstly. *

* DO NOT call this method from toJSONString() of a class that implements * both JSONAware and Map or List with "this" as the parameter, use * JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead. * * @param value to serialize * @param compression serialisation options * * @see JSONObject#toJSONString(Map) * @see JSONArray#toJSONString(List) * * @return JSON text, or "null" if value is null or it's an NaN or an INF * number. */ public static String toJSONString(Object value, JSONStyle compression) { StringBuilder sb = new StringBuilder(); try { writeJSONString(value, sb, compression); } catch (IOException e) { // can not append on a StringBuilder } return sb.toString(); } public static String escape(String s) { return escape(s, COMPRESSION); } /** * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters * (U+0000 through U+001F). * * @param s string to escape * @param compression compression options * * @return escaped string */ public static String escape(String s, JSONStyle compression) { if (s == null) return null; StringBuilder sb = new StringBuilder(); compression.escape(s, sb); return sb.toString(); } public static void escape(String s, Appendable ap) { escape(s, ap, COMPRESSION); } public static void escape(String s, Appendable ap, JSONStyle compression) { if (s == null) return; compression.escape(s, ap); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/JStylerObj.java000066400000000000000000000172761475302255200310610ustar00rootroot00000000000000package net.minidev.json; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; /** * protected class used to stored Internal methods * * @author Uriel Chemouni <uchemouni@gmail.com> */ class JStylerObj { public final static MPSimple MP_SIMPLE = new MPSimple(); public final static MPTrue MP_TRUE = new MPTrue(); public final static MPAgressive MP_AGGRESIVE = new MPAgressive(); public final static EscapeLT ESCAPE_LT = new EscapeLT(); public final static Escape4Web ESCAPE4Web = new Escape4Web(); public static interface MustProtect { public boolean mustBeProtect(String s); } private static class MPTrue implements MustProtect { public boolean mustBeProtect(String s) { return true; } } private static class MPSimple implements MustProtect { /** * can a String can be store without enclosing quotes. ie: should not * contain any special json char * * @param s * @return */ public boolean mustBeProtect(final String s) { if (s == null) return false; int len = s.length(); if (len == 0) return true; if (s.trim() != s) return true; char ch = s.charAt(0); if (ch >= '0' && ch <= '9' || ch == '-') return true; for (int i = 0; i < len; i++) { ch = s.charAt(i); if (isSpace(ch)) return true; if (isSpecial(ch)) return true; if (isSpecialChar(ch)) return true; if (isUnicode(ch)) return true; } // keyword check if (isKeyword(s)) return true; return false; } } private static class MPAgressive implements MustProtect { public boolean mustBeProtect(final String s) { if (s == null) return false; int len = s.length(); // protect empty String if (len == 0) return true; // protect trimable String if (s.trim() != s) return true; // json special char char ch = s.charAt(0); if (isSpecial(ch) || isUnicode(ch)) return true; for (int i = 1; i < len; i++) { ch = s.charAt(i); if (isSpecialClose(ch) || isUnicode(ch)) return true; } // keyWord must be protect if (isKeyword(s)) return true; // Digit like text must be protect ch = s.charAt(0); // only test String if First Ch is a digit if (ch >= '0' && ch <= '9' || ch == '-') { int p = 1; // skip first digits for (; p < len; p++) { ch = s.charAt(p); if (ch < '0' || ch > '9') break; } // int/long if (p == len) return true; // Floating point if (ch == '.') { p++; } // Skip digits for (; p < len; p++) { ch = s.charAt(p); if (ch < '0' || ch > '9') break; } if (p == len) return true; // can be read as an floating number // Double if (ch == 'E' || ch == 'e') { p++; if (p == len) // no power data not a digits return false; ch = s.charAt(p); if (ch == '+' || ch == '-') { p++; ch = s.charAt(p); } } if (p == len) // no power data => not a digit return false; for (; p < len; p++) { ch = s.charAt(p); if (ch < '0' || ch > '9') break; } // floating point With power of data. if (p == len) return true; return false; } return false; } } public static boolean isSpace(char c) { return (c == '\r' || c == '\n' || c == '\t' || c == ' '); } public static boolean isSpecialChar(char c) { return (c == '\b' || c == '\f' || c == '\n'); } public static boolean isSpecialOpen(char c) { return (c == '{' || c == '[' || c == ',' || c == ':'); } public static boolean isSpecialClose(char c) { return (c == '}' || c == ']' || c == ',' || c == ':'); } public static boolean isSpecial(char c) { return (c == '{' || c == '[' || c == ',' || c == '}' || c == ']' || c == ':' || c == '\'' || c == '"'); } public static boolean isUnicode(char c) { // ANSI control char return ((c >= '\u0000' && c <= '\u001F') || // DEL or unicode ctrl (c >= '\u007F' && c <= '\u009F') || // '\u00A0' No-breakable space ? // En Quad .. more (c >= '\u2000' && c <= '\u20FF')); } public static boolean isKeyword(String s) { if (s.length() < 3) return false; char c = s.charAt(0); if (c == 'n') return s.equals("null"); if (c == 't') return s.equals("true"); if (c == 'f') return s.equals("false"); if (c == 'N') return s.equals("NaN"); return false; } public static interface StringProtector { public void escape(String s, Appendable out); } private static class EscapeLT implements StringProtector { /** * Escape special chars form String except / * * @param s * - Must not be null. * @param out */ public void escape(String s, Appendable out) { try { int len = s.length(); for (int i = 0; i < len; i++) { char ch = s.charAt(i); switch (ch) { case '"': out.append("\\\""); break; case '\\': out.append("\\\\"); break; case '\b': out.append("\\b"); break; case '\f': out.append("\\f"); break; case '\n': out.append("\\n"); break; case '\r': out.append("\\r"); break; case '\t': out.append("\\t"); break; default: // Reference: // http://www.unicode.org/versions/Unicode5.1.0/ if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) { out.append("\\u"); String hex = "0123456789ABCDEF"; out.append(hex.charAt(ch >> 12 & 0x000F)); out.append(hex.charAt(ch >> 8 & 0x000F)); out.append(hex.charAt(ch >> 4 & 0x000F)); out.append(hex.charAt(ch >> 0 & 0x000F)); } else { out.append(ch); } } } } catch (IOException e) { throw new RuntimeException("Impossible Exception"); } } } private static class Escape4Web implements StringProtector { /** * Escape special chars form String including / * * @param s * - Must not be null. * @param sb */ public void escape(String s, Appendable sb) { try { int len = s.length(); for (int i = 0; i < len; i++) { char ch = s.charAt(i); switch (ch) { case '"': sb.append("\\\""); break; case '\\': sb.append("\\\\"); break; case '\b': sb.append("\\b"); break; case '\f': sb.append("\\f"); break; case '\n': sb.append("\\n"); break; case '\r': sb.append("\\r"); break; case '\t': sb.append("\\t"); break; case '/': sb.append("\\/"); break; default: // Reference: // http://www.unicode.org/versions/Unicode5.1.0/ if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) { sb.append("\\u"); String hex = "0123456789ABCDEF"; sb.append(hex.charAt(ch >> 12 & 0x0F)); sb.append(hex.charAt(ch >> 8 & 0x0F)); sb.append(hex.charAt(ch >> 4 & 0x0F)); sb.append(hex.charAt(ch >> 0 & 0x0F)); } else { sb.append(ch); } } } } catch (IOException e) { throw new RuntimeException("Impossible Error"); } } } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/annotate/000077500000000000000000000000001475302255200277635ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/annotate/JsonIgnore.java000066400000000000000000000014621475302255200327060ustar00rootroot00000000000000package net.minidev.json.annotate; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * block access to a field or to a getter or to a setter. * * If field and getter are annotate with @JsonIgnore the field will be Writable * only * * * If field and setter are annotate with @JsonIgnore the field will be Readable * only * * * If getter and setter are annotate with @JsonIgnore the field will be * Read/Write using field if the field is public (default ) * * * @author uriel * */ @Target({ ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) @JsonSmartAnnotation public @interface JsonIgnore { boolean value() default true; } JsonSmartAnnotation.java000066400000000000000000000005721475302255200345260ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/annotatepackage net.minidev.json.annotate; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Jackson Annotation like * * @author uriel * */ @Target({ ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface JsonSmartAnnotation { } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/000077500000000000000000000000001475302255200274465ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/JSONParser.java000066400000000000000000000175061475302255200322500ustar00rootroot00000000000000package net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.InputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; import net.minidev.json.JSONValue; import net.minidev.json.writer.JsonReaderI; public class JSONParser { /** * allow simple quote as String quoting char */ public final static int ACCEPT_SIMPLE_QUOTE = 1; /** * allow non quoted test */ public final static int ACCEPT_NON_QUOTE = 2; /** * Parse NaN as Float.NaN */ public final static int ACCEPT_NAN = 4; /** * Ignore control char in input text. */ public final static int IGNORE_CONTROL_CHAR = 8; /** * Use int datatype to store number when it's possible. * * @since 1.0.7 */ public final static int USE_INTEGER_STORAGE = 16; /** * Throws exception on excessive 0 leading in digits * * @since 1.0.7 */ public final static int ACCEPT_LEADING_ZERO = 32; /** * Throws exception on useless comma in object and array * * @since 1.0.8 */ public final static int ACCEPT_USELESS_COMMA = 64; /** * Allow Json-smart to use Double or BigDecimal to store floating point * value * * You may need to disable HI_PRECISION_FLOAT feature on 32bit to improve * parsing performances. * * @since 1.0.9 */ public final static int USE_HI_PRECISION_FLOAT = 128; /** * If enabled json-smart will throws exception if datas are present after * the end of the Json data. * * @since 1.0.9-2 */ public final static int ACCEPT_TAILLING_DATA = 256; /** * smart mode, fastest parsing mode. accept lots of non standard json syntax * * @since 2.0.1 */ public final static int ACCEPT_TAILLING_SPACE = 512; /** * smart mode, fastest parsing mode. accept lots of non standard json syntax * * @since 2.2.2 */ public final static int REJECT_127_CHAR = 1024; /** * Use double if possible for big digits, if no precision lost is observed * * @since 2.4 */ public final static int BIG_DIGIT_UNRESTRICTED = 2048; /** * If limit the max depth of json size * * @since 2.5 */ public static final int LIMIT_JSON_DEPTH = 4096; /** * smart mode, fastest parsing mode. accept lots of non standard json syntax * * @since 1.0.6 */ public final static int MODE_PERMISSIVE = -1; /** * strict RFC4627 mode. * * slower than PERMISSIVE MODE. * * @since 1.0.6 */ public final static int MODE_RFC4627 = USE_INTEGER_STORAGE | USE_HI_PRECISION_FLOAT | ACCEPT_TAILLING_SPACE | LIMIT_JSON_DEPTH; /** * Parse Object like json-simple * * Best for an iso-bug json-simple API port. * * @since 1.0.7 */ public final static int MODE_JSON_SIMPLE = ACCEPT_USELESS_COMMA | USE_HI_PRECISION_FLOAT | ACCEPT_TAILLING_DATA | ACCEPT_TAILLING_SPACE | REJECT_127_CHAR | BIG_DIGIT_UNRESTRICTED | LIMIT_JSON_DEPTH; /** * Strictest parsing mode * * @since 2.0.1 */ public final static int MODE_STRICTEST = USE_INTEGER_STORAGE | USE_HI_PRECISION_FLOAT | REJECT_127_CHAR | LIMIT_JSON_DEPTH; /** * Default json-smart processing mode */ public static int DEFAULT_PERMISSIVE_MODE = (System.getProperty("JSON_SMART_SIMPLE") != null) ? MODE_JSON_SIMPLE : MODE_PERMISSIVE; /* * internal fields */ private final int mode; private JSONParserInputStream pBinStream; private JSONParserByteArray pBytes; private JSONParserReader pStream; private JSONParserString pString; private JSONParserReader getPStream() { if (pStream == null) pStream = new JSONParserReader(mode); return pStream; } /** * cached constructor * * @return instance of JSONParserInputStream */ private JSONParserInputStream getPBinStream() { if (pBinStream == null) pBinStream = new JSONParserInputStream(mode); return pBinStream; } /** * cached constructor * * @return instance of JSONParserString */ private JSONParserString getPString() { if (pString == null) pString = new JSONParserString(mode); return pString; } /** * cached constructor * * @return instance of JSONParserByteArray */ private JSONParserByteArray getPBytes() { if (pBytes == null) pBytes = new JSONParserByteArray(mode); return pBytes; } /** * @deprecated prefer usage of new JSONParser(JSONParser.MODE_*) */ public JSONParser() { this.mode = DEFAULT_PERMISSIVE_MODE; } public JSONParser(int permissifMode) { this.mode = permissifMode; } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public Object parse(byte[] in) throws ParseException { return getPBytes().parse(in); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(byte[] in, JsonReaderI mapper) throws ParseException { return getPBytes().parse(in, mapper); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(byte[] in, Class mapTo) throws ParseException { return getPBytes().parse(in, JSONValue.defaultReader.getMapper(mapTo)); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory * @throws UnsupportedEncodingException */ public Object parse(InputStream in) throws ParseException, UnsupportedEncodingException { return getPBinStream().parse(in); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(InputStream in, JsonReaderI mapper) throws ParseException, UnsupportedEncodingException { return getPBinStream().parse(in, mapper); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(InputStream in, Class mapTo) throws ParseException, UnsupportedEncodingException { return getPBinStream().parse(in, JSONValue.defaultReader.getMapper(mapTo)); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public Object parse(Reader in) throws ParseException { return getPStream().parse(in); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(Reader in, JsonReaderI mapper) throws ParseException { return getPStream().parse(in, mapper); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(Reader in, Class mapTo) throws ParseException { return getPStream().parse(in, JSONValue.defaultReader.getMapper(mapTo)); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public Object parse(String in) throws ParseException { return getPString().parse(in); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(String in, JsonReaderI mapper) throws ParseException { return getPString().parse(in, mapper); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(String in, Class mapTo) throws ParseException { return getPString().parse(in, JSONValue.defaultReader.getMapper(mapTo)); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/JSONParserBase.java000066400000000000000000000516101475302255200330350ustar00rootroot00000000000000package net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_CHAR; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_LEADING_0; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_TOKEN; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_UNICODE; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_JSON_DEPTH; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import net.minidev.json.writer.JsonReader; import net.minidev.json.writer.JsonReaderI; /** * JSONParserBase is the common code between {@link JSONParserString} and * {@link JSONParserReader} * * @see JSONParserMemory * @see JSONParserStream * * @author Uriel Chemouni <uchemouni@gmail.com> */ abstract class JSONParserBase { protected char c; /** * hard coded maximal depth for JSON parsing */ public final static int MAX_DEPTH = 400; protected int depth = 0; JsonReader base; public final static byte EOI = 0x1A; protected static final char MAX_STOP = 126; // '}' -> 125 private String lastKey; protected static boolean[] stopAll = new boolean[MAX_STOP]; protected static boolean[] stopArray = new boolean[MAX_STOP]; protected static boolean[] stopKey = new boolean[MAX_STOP]; protected static boolean[] stopValue = new boolean[MAX_STOP]; protected static boolean[] stopX = new boolean[MAX_STOP]; static { stopKey[':'] = stopKey[EOI] = true; stopValue[','] = stopValue['}'] = stopValue[EOI] = true; stopArray[','] = stopArray[']'] = stopArray[EOI] = true; stopX[EOI] = true; stopAll[','] = stopAll[':'] = true; stopAll[']'] = stopAll['}'] = stopAll[EOI] = true; } /* * End of static declaration */ // // protected final MSB sb = new MSB(15); protected Object xo; protected String xs; protected int pos; /* * Parsing flags */ protected final boolean acceptLeadinZero; protected final boolean acceptNaN; protected final boolean acceptNonQuote; protected final boolean acceptSimpleQuote; protected final boolean acceptUselessComma; protected final boolean checkTaillingData; protected final boolean checkTaillingSpace; protected final boolean ignoreControlChar; protected final boolean useHiPrecisionFloat; protected final boolean useIntegerStorage; protected final boolean reject127; protected final boolean unrestictBigDigit; protected final boolean limitJsonDepth; public JSONParserBase(int permissiveMode) { this.acceptNaN = (permissiveMode & JSONParser.ACCEPT_NAN) > 0; this.acceptNonQuote = (permissiveMode & JSONParser.ACCEPT_NON_QUOTE) > 0; this.acceptSimpleQuote = (permissiveMode & JSONParser.ACCEPT_SIMPLE_QUOTE) > 0; this.ignoreControlChar = (permissiveMode & JSONParser.IGNORE_CONTROL_CHAR) > 0; this.useIntegerStorage = (permissiveMode & JSONParser.USE_INTEGER_STORAGE) > 0; this.acceptLeadinZero = (permissiveMode & JSONParser.ACCEPT_LEADING_ZERO) > 0; this.acceptUselessComma = (permissiveMode & JSONParser.ACCEPT_USELESS_COMMA) > 0; this.useHiPrecisionFloat = (permissiveMode & JSONParser.USE_HI_PRECISION_FLOAT) > 0; this.checkTaillingData = (permissiveMode & (JSONParser.ACCEPT_TAILLING_DATA | JSONParser.ACCEPT_TAILLING_SPACE)) != (JSONParser.ACCEPT_TAILLING_DATA | JSONParser.ACCEPT_TAILLING_SPACE); this.checkTaillingSpace = (permissiveMode & JSONParser.ACCEPT_TAILLING_SPACE) == 0; this.reject127 = (permissiveMode & JSONParser.REJECT_127_CHAR) > 0; this.unrestictBigDigit = (permissiveMode & JSONParser.BIG_DIGIT_UNRESTRICTED) > 0; this.limitJsonDepth = (permissiveMode & JSONParser.LIMIT_JSON_DEPTH) > 0; } public void checkControleChar() throws ParseException { if (ignoreControlChar) return; int l = xs.length(); for (int i = 0; i < l; i++) { char c = xs.charAt(i); if (c < 0) continue; if (c <= 31) throw new ParseException(pos + i, ParseException.ERROR_UNEXPECTED_CHAR, c); if (c == 127) { if (reject127) throw new ParseException(pos + i, ParseException.ERROR_UNEXPECTED_CHAR, c); } } } public void checkLeadinZero() throws ParseException { int len = xs.length(); if (len == 1) return; if (len == 2) { if (xs.equals("00")) throw new ParseException(pos, ERROR_UNEXPECTED_LEADING_0, xs); return; } char c1 = xs.charAt(0); char c2 = xs.charAt(1); if (c1 == '-') { char c3 = xs.charAt(2); if (c2 == '0' && c3 >= '0' && c3 <= '9') throw new ParseException(pos, ERROR_UNEXPECTED_LEADING_0, xs); return; } if (c1 == '0' && c2 >= '0' && c2 <= '9') throw new ParseException(pos, ERROR_UNEXPECTED_LEADING_0, xs); } protected Number extractFloat() throws ParseException { if (!acceptLeadinZero) checkLeadinZero(); try { if (!useHiPrecisionFloat) return Float.parseFloat(xs); // follow JSonIJ parsing method if (xs.length() > 18) { // use extra CPU to check if the result can be return as double without // precision lost if (!unrestictBigDigit) { double asDouble = Double.parseDouble(xs); final String doubleStr = String.valueOf(asDouble); // we need a compare `e` `E` `e+` `E+` if (compareDoublePrecision(doubleStr, xs)) { return asDouble; } } return new BigDecimal(xs); } return Double.parseDouble(xs); } catch (NumberFormatException e) { throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); } } private boolean compareDoublePrecision(String convert, String origin) { final char[] charArray = convert.toCharArray(); final char[] originArray = origin.toCharArray(); if (charArray.length > originArray.length) { return false; } int j = 0; for (int i = 0; i < charArray.length; i++) { if (charArray[i] < '0' || charArray[i] > '9') { if (originArray[j] >= '0' && originArray[j] <= '9') { return false; } else { j++; if (originArray[j] == '+') { j++; } continue; } } if (charArray[i] != originArray[j]) { return false; } j++; } return j == originArray.length; } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray generated * by a ContainerFactory */ protected T parse(JsonReaderI mapper) throws ParseException { this.pos = -1; T result; try { read(); result = readFirst(mapper); if (checkTaillingData) { if (!checkTaillingSpace) skipSpace(); if (c != EOI) throw new ParseException(pos - 1, ERROR_UNEXPECTED_TOKEN, c); } } catch (IOException e) { throw new ParseException(pos, e); } xs = null; xo = null; return result; } protected Number parseNumber(String s) throws ParseException { // position int p = 0; // length int l = s.length(); // max position long base 10 length int max = 19; boolean neg; if (s.charAt(0) == '-') { p++; max++; neg = true; if (!acceptLeadinZero && l >= 3 && s.charAt(1) == '0') throw new ParseException(pos, ERROR_UNEXPECTED_LEADING_0, s); } else { neg = false; if (!acceptLeadinZero && l >= 2 && s.charAt(0) == '0') throw new ParseException(pos, ERROR_UNEXPECTED_LEADING_0, s); } boolean mustCheck; if (l < max) { max = l; mustCheck = false; } else if (l > max) { return new BigInteger(s, 10); } else { max = l - 1; mustCheck = true; } long r = 0; while (p < max) { r = (r * 10L) + ('0' - s.charAt(p++)); } if (mustCheck) { boolean isBig; if (r > -922337203685477580L) { isBig = false; } else if (r < -922337203685477580L) { isBig = true; } else { if (neg) isBig = (s.charAt(p) > '8'); else isBig = (s.charAt(p) > '7'); } if (isBig) return new BigInteger(s, 10); r = r * 10L + ('0' - s.charAt(p)); } if (neg) { if (this.useIntegerStorage && r >= Integer.MIN_VALUE) return (int) r; return r; } r = -r; if (this.useIntegerStorage && r <= Integer.MAX_VALUE) return (int) r; return r; } abstract protected void read() throws IOException; protected T readArray(JsonReaderI mapper) throws ParseException, IOException { if (c != '[') throw new RuntimeException("Internal Error"); if (limitJsonDepth && ++this.depth > MAX_DEPTH) { throw new ParseException(pos, ERROR_UNEXPECTED_JSON_DEPTH, c); } Object current = mapper.createArray(); read(); boolean needData = false; // special case needData is false and can close is true if (c == ',' && !acceptUselessComma) throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, (char) c); for (;;) { switch (c) { case ' ': case '\r': case '\n': case '\t': read(); continue; case ']': if (needData && !acceptUselessComma) throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, (char) c); this.depth--; read(); /* unstack */ // return mapper.convert(current); case ':': case '}': throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, (char) c); case ',': if (needData && !acceptUselessComma) throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, (char) c); read(); needData = true; continue; case EOI: throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF"); default: mapper.addValue(current, readMain(mapper, stopArray)); needData = false; continue; } } } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray generated * by a ContainerFactory */ protected T readFirst(JsonReaderI mapper) throws ParseException, IOException { for (;;) { switch (c) { // skip spaces case ' ': case '\r': case '\n': case '\t': read(); continue; // invalid state case ':': case '}': case ']': throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); // start object case '{': return readObject(mapper); // start Array case '[': return readArray(mapper); // start string case '"': case '\'': readString(); // return mapper.convert(xs); // string or null case 'n': readNQString(stopX); if ("null".equals(xs)) { // return null; } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return mapper.convert(xs); // string or false case 'f': readNQString(stopX); if ("false".equals(xs)) { // return mapper.convert(Boolean.FALSE); } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return mapper.convert(xs); // string or true case 't': readNQString(stopX); if ("true".equals(xs)) { // return mapper.convert(Boolean.TRUE); } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return mapper.convert(xs); // string or NaN case 'N': readNQString(stopX); if (!acceptNaN) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); if ("NaN".equals(xs)) { // return mapper.convert(Float.valueOf(Float.NaN)); } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return mapper.convert(xs); // digits case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': xo = readNumber(stopX); // return mapper.convert(xo); default: readNQString(stopX); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return mapper.convert(xs); } } } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray generated * by a ContainerFactory */ protected Object readMain(JsonReaderI mapper, boolean stop[]) throws ParseException, IOException { for (;;) { switch (c) { // skip spaces case ' ': case '\r': case '\n': case '\t': read(); continue; // invalid state case ':': case '}': case ']': throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); // start object case '{': return readObject(mapper.startObject(lastKey)); // start Array case '[': return readArray(mapper.startArray(lastKey)); // start string case '"': case '\'': readString(); // return xs; // string or null case 'n': readNQString(stop); if ("null".equals(xs)) { // return null; } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return xs; // string or false case 'f': readNQString(stop); if ("false".equals(xs)) { // return Boolean.FALSE; } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return xs; // string or true case 't': readNQString(stop); if ("true".equals(xs)) { // return Boolean.TRUE; } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return xs; // string or NaN case 'N': readNQString(stop); if (!acceptNaN) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); if ("NaN".equals(xs)) { // return Float.valueOf(Float.NaN); } if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return xs; // digits case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': // // return readNumber(stop); default: readNQString(stop); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); // return xs; } } } abstract protected void readNoEnd() throws ParseException, IOException; abstract protected void readNQString(boolean[] stop) throws IOException; abstract protected Object readNumber(boolean[] stop) throws ParseException, IOException; protected T readObject(JsonReaderI mapper) throws ParseException, IOException { // if (c != '{') throw new RuntimeException("Internal Error"); if (limitJsonDepth && ++this.depth > MAX_DEPTH) { throw new ParseException(pos, ERROR_UNEXPECTED_JSON_DEPTH, c); } Object current = mapper.createObject(); boolean needData = false; boolean acceptData = true; for (;;) { read(); switch (c) { case ' ': case '\r': case '\t': case '\n': continue; case ':': case ']': case '[': case '{': throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); case '}': if (needData && !acceptUselessComma) throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, (char) c); this.depth--; read(); /* unstack */ // return mapper.convert(current); case ',': if (needData && !acceptUselessComma) throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, (char) c); acceptData = needData = true; continue; case '"': case '\'': default: // int keyStart = pos; if (c == '\"' || c == '\'') { readString(); } else { readNQString(stopKey); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); } String key = xs; if (!acceptData) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, key); // Skip spaces skipSpace(); if (c != ':') { if (c == EOI) throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, null); throw new ParseException(pos - 1, ERROR_UNEXPECTED_CHAR, c); } readNoEnd(); /* skip : */ lastKey = key; Object value = readMain(mapper, stopValue); mapper.setValue(current, key, value); lastKey = null; // Object duplicate = obj.put(key, readMain(stopValue)); // if (duplicate != null) // throw new ParseException(keyStart, ERROR_UNEXPECTED_DUPLICATE_KEY, key); // handler.endObjectEntry(); // should loop skipping read step skipSpace(); if (c == '}') { this.depth--; read(); /* unstack */ // return mapper.convert(current); } if (c == EOI) // Fixed on 18/10/2011 reported by vladimir throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, null); // if c==, continue if (c == ',') acceptData = needData = true; else throw new ParseException(pos - 1, ERROR_UNEXPECTED_TOKEN, c); // acceptData = needData = false; } } } /** * store and read */ abstract void readS() throws IOException; abstract protected void readString() throws ParseException, IOException; protected void readString2() throws ParseException, IOException { /* assert (c == '\"' || c == '\'') */ char sep = c; for (;;) { read(); switch (c) { case EOI: throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, null); case '"': case '\'': if (sep == c) { read(); xs = sb.toString(); return; } sb.append(c); break; case '\\': read(); switch (c) { case 't': sb.append('\t'); break; case 'n': sb.append('\n'); break; case 'r': sb.append('\r'); break; case 'f': sb.append('\f'); break; case 'b': sb.append('\b'); break; case '\\': sb.append('\\'); break; case '/': sb.append('/'); break; case '\'': sb.append('\''); break; case '"': sb.append('"'); break; case 'u': sb.append(readUnicode(4)); break; case 'x': sb.append(readUnicode(2)); break; default: break; } break; case '\0': // end of string case (char) 1: // Start of heading case (char) 2: // Start of text case (char) 3: // End of text case (char) 4: // End of transmission case (char) 5: // Enquiry case (char) 6: // Acknowledge case (char) 7: // Bell case '\b': // 8: backSpase case '\t': // 9: horizontal tab case '\n': // 10: new line case (char) 11: // Vertical tab case '\f': // 12: form feed case '\r': // 13: return carriage case (char) 14: // Shift Out, alternate character set case (char) 15: // Shift In, resume defaultn character set case (char) 16: // Data link escape case (char) 17: // XON, with XOFF to pause listings; case (char) 18: // Device control 2, block-mode flow control case (char) 19: // XOFF, with XON is TERM=18 flow control case (char) 20: // Device control 4 case (char) 21: // Negative acknowledge case (char) 22: // Synchronous idle case (char) 23: // End transmission block, not the same as EOT case (char) 24: // Cancel line, MPE echoes !!! case (char) 25: // End of medium, Control-Y interrupt // case (char) 26: // Substitute == EOI case (char) 27: // escape case (char) 28: // File Separator case (char) 29: // Group Separator case (char) 30: // Record Separator case (char) 31: // Unit Separator if (ignoreControlChar) continue; throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); case (char) 127: // del if (ignoreControlChar) continue; if (reject127) throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); default: sb.append(c); } } } protected char readUnicode(int totalChars) throws ParseException, IOException { int value = 0; for (int i = 0; i < totalChars; i++) { value = value * 16; read(); if (c <= '9' && c >= '0') value += c - '0'; else if (c <= 'F' && c >= 'A') value += (c - 'A') + 10; else if (c >= 'a' && c <= 'f') value += (c - 'a') + 10; else if (c == EOI) throw new ParseException(pos, ERROR_UNEXPECTED_EOF, "EOF"); else throw new ParseException(pos, ERROR_UNEXPECTED_UNICODE, c); } return (char) value; } protected void skipDigits() throws IOException { for (;;) { if (c < '0' || c > '9') return; readS(); } } protected void skipNQString(boolean[] stop) throws IOException { for (;;) { if ((c == EOI) || (c >= 0 && c < MAX_STOP && stop[c])) return; readS(); } } protected void skipSpace() throws IOException { for (;;) { if (c > ' ' || c == EOI) return; readS(); } } public static class MSB { char b[]; int p; public MSB(int size) { b = new char[size]; p = -1; } public void append(char c) { p++; if (b.length <= p) { char[] t = new char[b.length * 2 + 1]; System.arraycopy(b, 0, t, 0, b.length); b = t; } b[p] = c; } public void append(int c) { p++; if (b.length <= p) { char[] t = new char[b.length * 2 + 1]; System.arraycopy(b, 0, t, 0, b.length); b = t; } b[p] = (char) c; } public String toString() { return new String(b, 0, p + 1); } public void clear() { p = -1; } } } JSONParserByteArray.java000066400000000000000000000053201475302255200340030ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parserpackage net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; import net.minidev.json.JSONValue; import net.minidev.json.writer.JsonReaderI; import java.nio.charset.StandardCharsets; /** * Parser for JSON text. Please note that JSONParser is NOT thread-safe. * * @author Uriel Chemouni <uchemouni@gmail.com> */ class JSONParserByteArray extends JSONParserMemory { private byte[] in; public JSONParserByteArray(int permissiveMode) { super(permissiveMode); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public Object parse(byte[] in) throws ParseException { return parse(in, JSONValue.defaultReader.DEFAULT); } // // // // // // // /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(byte[] in, JsonReaderI mapper) throws ParseException { this.base = mapper.base; this.in = in; this.len = in.length; return parse(mapper); } protected void extractString(int beginIndex, int endIndex) { xs = new String(in, beginIndex, endIndex - beginIndex, StandardCharsets.UTF_8); } protected void extractStringTrim(int start, int stop) { byte[] val = this.in; /* avoid getfield opcode */ while ((start < stop) && (val[start] <= ' ')) { start++; } while ((start < stop) && (val[stop - 1] <= ' ')) { stop--; } xs = new String(in, start, stop - start, StandardCharsets.UTF_8); } protected int indexOf(char c, int pos) { for (int i = pos; i < len; i++) if (in[i] == (byte) c) return i; return -1; } protected void read() { if (++pos >= len) this.c = EOI; else this.c = (char) in[pos]; } /** * Same as read() in memory parsing */ protected void readS() { if (++pos >= len) this.c = EOI; else this.c = (char) in[pos]; } /** * read data can not be EOI */ protected void readNoEnd() throws ParseException { if (++pos >= len) { this.c = EOI; throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF"); } else this.c = (char) in[pos]; } } JSONParserInputStream.java000066400000000000000000000033721475302255200343610ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parserpackage net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import net.minidev.json.writer.JsonReaderI; /** * Parser for JSON text. Please note that JSONParser is NOT thread-safe. * * @author Uriel Chemouni <uchemouni@gmail.com> */ class JSONParserInputStream extends JSONParserReader { // len public JSONParserInputStream(int permissiveMode) { super(permissiveMode); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory * @throws UnsupportedEncodingException */ public Object parse(InputStream in) throws ParseException, UnsupportedEncodingException { InputStreamReader i2 = new InputStreamReader(in, "utf8"); return super.parse(i2); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(InputStream in, JsonReaderI mapper) throws ParseException, UnsupportedEncodingException { InputStreamReader i2 = new InputStreamReader(in, "utf8"); // return super.parse(i2, mapper); } // // // // // // // // } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/JSONParserMemory.java000066400000000000000000000074301475302255200334340ustar00rootroot00000000000000package net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_CHAR; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_TOKEN; import java.io.IOException; /** * Parser for JSON text. Please note that JSONParser is NOT thread-safe. * * @author Uriel Chemouni <uchemouni@gmail.com> * @see JSONParserString * @see JSONParserByteArray */ abstract class JSONParserMemory extends JSONParserBase { protected int len; public JSONParserMemory(int permissiveMode) { super(permissiveMode); } protected void readNQString(boolean[] stop) throws IOException { int start = pos; skipNQString(stop); extractStringTrim(start, pos); } protected Object readNumber(boolean[] stop) throws ParseException, IOException { int start = pos; // accept first char digit or - read(); skipDigits(); // Integer digit if (c != '.' && c != 'E' && c != 'e') { skipSpace(); if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { // convert string skipNQString(stop); extractStringTrim(start, pos); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); return xs; } extractStringTrim(start, pos); return parseNumber(xs); } // floating point if (c == '.') { // read(); skipDigits(); } if (c != 'E' && c != 'e') { skipSpace(); if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { // convert string skipNQString(stop); extractStringTrim(start, pos); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); return xs; } extractStringTrim(start, pos); return extractFloat(); } sb.append('E'); read(); if (c == '+' || c == '-' || c >= '0' && c <= '9') { sb.append(c); read(); // skip first char skipDigits(); skipSpace(); if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { // convert string skipNQString(stop); extractStringTrim(start, pos); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); return xs; } extractStringTrim(start, pos); return extractFloat(); } else { skipNQString(stop); extractStringTrim(start, pos); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); if (!acceptLeadinZero) checkLeadinZero(); return xs; } // throw new ParseException(pos - 1, ERROR_UNEXPECTED_CHAR, null); } protected void readString() throws ParseException, IOException { if (!acceptSimpleQuote && c == '\'') { if (acceptNonQuote) { readNQString(stopAll); return; } throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); } int tmpP = indexOf(c, pos + 1); if (tmpP == -1) throw new ParseException(len, ERROR_UNEXPECTED_EOF, null); extractString(pos + 1, tmpP); if (xs.indexOf('\\') == -1) { checkControleChar(); pos = tmpP; read(); // handler.primitive(tmp); return; } sb.clear(); readString2(); } abstract protected void extractString(int start, int stop); abstract protected int indexOf(char c, int pos); abstract protected void extractStringTrim(int start, int stop); } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/JSONParserReader.java000066400000000000000000000041531475302255200333650ustar00rootroot00000000000000package net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; import java.io.IOException; import java.io.Reader; import net.minidev.json.JSONValue; import net.minidev.json.writer.JsonReaderI; /** * Parser for JSON text. Please note that JSONParser is NOT thread-safe. * * @author Uriel Chemouni <uchemouni@gmail.com> */ class JSONParserReader extends JSONParserStream { private Reader in; // len public JSONParserReader(int permissiveMode) { super(permissiveMode); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public Object parse(Reader in) throws ParseException { return parse(in, JSONValue.defaultReader.DEFAULT); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(Reader in, JsonReaderI mapper) throws ParseException { this.base = mapper.base; // this.in = in; return super.parse(mapper); } // // // // // // // protected void read() throws IOException { int i = in.read(); c = (i == -1) ? (char) EOI : (char) i; pos++; // } protected void readS() throws IOException { sb.append(c); int i = in.read(); if (i == -1) { c = EOI; } else { c = (char) i; pos++; } } protected void readNoEnd() throws ParseException, IOException { int i = in.read(); if (i == -1) throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF"); c = (char) i; // } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/JSONParserStream.java000066400000000000000000000065531475302255200334240ustar00rootroot00000000000000package net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_CHAR; import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_TOKEN; import java.io.IOException; /** * Parser for JSON text. Please note that JSONParser is NOT thread-safe. * * @author Uriel Chemouni <uchemouni@gmail.com> * @see JSONParserInputStream * @see JSONParserReader */ abstract class JSONParserStream extends JSONParserBase { // len // public JSONParserStream(int permissiveMode) { super(permissiveMode); } protected void readNQString(boolean[] stop) throws IOException { sb.clear(); skipNQString(stop); xs = sb.toString().trim(); } protected Object readNumber(boolean[] stop) throws ParseException, IOException { sb.clear(); sb.append(c);// accept first char digit or - read(); skipDigits(); // Integer digit if (c != '.' && c != 'E' && c != 'e') { skipSpace(); if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { // convert string skipNQString(stop); xs = sb.toString().trim(); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); return xs; } xs = sb.toString().trim(); return parseNumber(xs); } // floating point if (c == '.') { sb.append(c); read(); skipDigits(); } if (c != 'E' && c != 'e') { skipSpace(); if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { // convert string skipNQString(stop); xs = sb.toString().trim(); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); return xs; } xs = sb.toString().trim(); return extractFloat(); } sb.append('E'); read(); if (c == '+' || c == '-' || c >= '0' && c <= '9') { sb.append(c); read(); // skip first char skipDigits(); skipSpace(); if (c >= 0 && c < MAX_STOP && !stop[c] && c != EOI) { // convert string skipNQString(stop); xs = sb.toString().trim(); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); return xs; } xs = sb.toString().trim(); return extractFloat(); } else { skipNQString(stop); xs = sb.toString().trim(); if (!acceptNonQuote) throw new ParseException(pos, ERROR_UNEXPECTED_TOKEN, xs); if (!acceptLeadinZero) checkLeadinZero(); return xs; } // throw new ParseException(pos - 1, ERROR_UNEXPECTED_CHAR, null); } protected void readString() throws ParseException, IOException { if (!acceptSimpleQuote && c == '\'') { if (acceptNonQuote) { readNQString(stopAll); return; } throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c); } sb.clear(); // // // // // // // // // // /* assert (c == '\"' || c == '\'') */ readString2(); } // // // // // // // // } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/JSONParserString.java000066400000000000000000000050711475302255200334310ustar00rootroot00000000000000package net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import static net.minidev.json.parser.ParseException.ERROR_UNEXPECTED_EOF; import net.minidev.json.JSONValue; import net.minidev.json.writer.JsonReaderI; /** * Parser for JSON text. Please note that JSONParser is NOT thread-safe. * * @author Uriel Chemouni <uchemouni@gmail.com> */ class JSONParserString extends JSONParserMemory { private String in; public JSONParserString(int permissiveMode) { super(permissiveMode); } /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public Object parse(String in) throws ParseException { return parse(in, JSONValue.defaultReader.DEFAULT); } // // // // // // // /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory */ public T parse(String in, JsonReaderI mapper) throws ParseException { this.base = mapper.base; this.in = in; this.len = in.length(); return parse(mapper); } protected void extractString(int beginIndex, int endIndex) { xs = in.substring(beginIndex, endIndex); } protected void extractStringTrim(int start, int stop) { while (start < stop-1 && Character.isWhitespace(in.charAt(start))) { start++; } while (stop-1 > start && Character.isWhitespace(in.charAt(stop-1))) { stop--; } extractString(start, stop); } protected int indexOf(char c, int pos) { return in.indexOf(c, pos); } /** * Read next char or END OF INPUT */ protected void read() { if (++pos >= len) this.c = EOI; else this.c = in.charAt(pos); } /** * Same as read() in memory parsing */ protected void readS() { if (++pos >= len) this.c = EOI; else this.c = in.charAt(pos); } /** * read data can not be EOI */ protected void readNoEnd() throws ParseException { if (++pos >= len) { this.c = EOI; throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF"); } else this.c = in.charAt(pos); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/parser/ParseException.java000066400000000000000000000103471475302255200332470ustar00rootroot00000000000000package net.minidev.json.parser; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ /** * ParseException explains why and where the error occurs in source JSON text. * * @author Uriel Chemouni <uchemouni@gmail.com> */ public class ParseException extends Exception { private static final long serialVersionUID = 8879024178584091857L; public static final int ERROR_UNEXPECTED_CHAR = 0; public static final int ERROR_UNEXPECTED_TOKEN = 1; public static final int ERROR_UNEXPECTED_EXCEPTION = 2; public static final int ERROR_UNEXPECTED_EOF = 3; public static final int ERROR_UNEXPECTED_UNICODE = 4; public static final int ERROR_UNEXPECTED_DUPLICATE_KEY = 5; public static final int ERROR_UNEXPECTED_LEADING_0 = 6; public static final int ERROR_UNEXPECTED_JSON_DEPTH = 7; private int errorType; private Object unexpectedObject; private int position; public ParseException(int position, int errorType, Object unexpectedObject) { super(toMessage(position, errorType, unexpectedObject)); this.position = position; this.errorType = errorType; this.unexpectedObject = unexpectedObject; } public ParseException(int position, Throwable cause) { super(toMessage(position, ERROR_UNEXPECTED_EXCEPTION, cause), cause); this.position = position; this.errorType = ERROR_UNEXPECTED_EXCEPTION; this.unexpectedObject = cause; } public int getErrorType() { return errorType; } /** * @return The character position (starting with 0) of the input where the * error occurs. */ public int getPosition() { return position; } /** * @return One of the following base on the value of errorType: * ERROR_UNEXPECTED_CHAR java.lang.Character ERROR_UNEXPECTED_TOKEN * ERROR_UNEXPECTED_EXCEPTION java.lang.Exception */ public Object getUnexpectedObject() { return unexpectedObject; } private static String toMessage(int position, int errorType, Object unexpectedObject) { StringBuilder sb = new StringBuilder(); if (errorType == ERROR_UNEXPECTED_CHAR) { sb.append("Unexpected character ("); sb.append(unexpectedObject); sb.append(") at position "); sb.append(position); sb.append("."); } else if (errorType == ERROR_UNEXPECTED_TOKEN) { sb.append("Unexpected token "); sb.append(unexpectedObject); sb.append(" at position "); sb.append(position); sb.append("."); } else if (errorType == ERROR_UNEXPECTED_EXCEPTION) { sb.append("Unexpected exception "); sb.append(unexpectedObject); sb.append(" occur at position "); sb.append(position); sb.append("."); } else if (errorType == ERROR_UNEXPECTED_EOF) { sb.append("Unexpected End Of File position "); sb.append(position); sb.append(": "); sb.append(unexpectedObject); } else if (errorType == ERROR_UNEXPECTED_UNICODE) { sb.append("Unexpected unicode escape sequence "); sb.append(unexpectedObject); sb.append(" at position "); sb.append(position); sb.append("."); } else if (errorType == ERROR_UNEXPECTED_DUPLICATE_KEY) { sb.append("Unexpected duplicate key:"); sb.append(unexpectedObject); sb.append(" at position "); sb.append(position); sb.append("."); } else if (errorType == ERROR_UNEXPECTED_LEADING_0) { sb.append("Unexpected leading 0 in digit for token:"); sb.append(unexpectedObject); sb.append(" at position "); sb.append(position); sb.append("."); } else if (errorType == ERROR_UNEXPECTED_JSON_DEPTH) { sb.append("Malicious payload, having non natural depths, parsing stoped on "); sb.append(unexpectedObject); sb.append(" at position "); sb.append(position); sb.append("."); } else { sb.append("Unkown error at position "); sb.append(position); sb.append("."); } return sb.toString(); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/reader/000077500000000000000000000000001475302255200274145ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/reader/ArrayWriter.java000066400000000000000000000010571475302255200325350ustar00rootroot00000000000000package net.minidev.json.reader; import java.io.IOException; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; public class ArrayWriter implements JsonWriterI { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { compression.arrayStart(out); boolean needSep = false; for (Object o : ((Object[]) value)) { if (needSep) compression.objectNext(out); else needSep = true; JSONValue.writeJSONString(o, out, compression); } compression.arrayStop(out); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/reader/BeansWriter.java000066400000000000000000000033621475302255200325100ustar00rootroot00000000000000package net.minidev.json.reader; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import net.minidev.json.JSONStyle; import net.minidev.json.JSONUtil; public class BeansWriter implements JsonWriterI { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { try { Class nextClass = value.getClass(); boolean needSep = false; compression.objectStart(out); while (nextClass != Object.class) { Field[] fields = nextClass.getDeclaredFields(); for (Field field : fields) { int m = field.getModifiers(); if ((m & (Modifier.STATIC | Modifier.TRANSIENT | Modifier.FINAL)) > 0) continue; Object v = null; if ((m & Modifier.PUBLIC) > 0) { v = field.get(value); } else { String g = JSONUtil.getGetterName(field.getName()); Method mtd = null; try { mtd = nextClass.getDeclaredMethod(g); } catch (Exception e) { } if (mtd == null) { Class c2 = field.getType(); if (c2 == Boolean.TYPE || c2 == Boolean.class) { g = JSONUtil.getIsName(field.getName()); mtd = nextClass.getDeclaredMethod(g); } } if (mtd == null) continue; v = mtd.invoke(value); } if (v == null && compression.ignoreNull()) continue; if (needSep) compression.objectNext(out); else needSep = true; String key = field.getName(); JsonWriter.writeJSONKV(key, v, out, compression); // compression.objectElmStop(out); } nextClass = nextClass.getSuperclass(); } compression.objectStop(out); } catch (Exception e) { throw new RuntimeException(e); } } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/reader/BeansWriterASM.java000066400000000000000000000020141475302255200330420ustar00rootroot00000000000000package net.minidev.json.reader; import java.io.IOException; import net.minidev.asm.Accessor; import net.minidev.asm.BeansAccess; import net.minidev.json.JSONObject; import net.minidev.json.JSONStyle; import net.minidev.json.JSONUtil; public class BeansWriterASM implements JsonWriterI { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { try { Class cls = value.getClass(); boolean needSep = false; @SuppressWarnings("rawtypes") BeansAccess fields = BeansAccess.get(cls, JSONUtil.JSON_SMART_FIELD_FILTER); out.append('{'); for (Accessor field : fields.getAccessors()) { @SuppressWarnings("unchecked") Object v = fields.get(value, field.getIndex()); if (v == null && compression.ignoreNull()) continue; if (needSep) out.append(','); else needSep = true; String key = field.getName(); JSONObject.writeJSONKV(key, v, out, compression); } out.append('}'); } catch (IOException e) { throw e; } } } BeansWriterASMRemap.java000066400000000000000000000025541475302255200337610ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/readerpackage net.minidev.json.reader; import java.io.IOException; import java.util.HashMap; import java.util.Map; import net.minidev.asm.Accessor; import net.minidev.asm.BeansAccess; import net.minidev.json.JSONObject; import net.minidev.json.JSONStyle; import net.minidev.json.JSONUtil; public class BeansWriterASMRemap implements JsonWriterI { private Map rename = new HashMap(); public void renameField(String source, String dest) { rename.put(source, dest); } private String rename(String key) { String k2 = rename.get(key); if (k2 != null) return k2; return key; } public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { try { Class cls = value.getClass(); boolean needSep = false; @SuppressWarnings("rawtypes") BeansAccess fields = BeansAccess.get(cls, JSONUtil.JSON_SMART_FIELD_FILTER); out.append('{'); for (Accessor field : fields.getAccessors()) { @SuppressWarnings("unchecked") Object v = fields.get(value, field.getIndex()); if (v == null && compression.ignoreNull()) continue; if (needSep) out.append(','); else needSep = true; String key = field.getName(); key = rename(key); JSONObject.writeJSONKV(key, v, out, compression); } out.append('}'); } catch (IOException e) { throw e; } } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/reader/JsonWriter.java000066400000000000000000000300721475302255200323670ustar00rootroot00000000000000package net.minidev.json.reader; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Date; import java.util.LinkedList; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.minidev.json.JSONAware; import net.minidev.json.JSONAwareEx; import net.minidev.json.JSONStreamAware; import net.minidev.json.JSONStreamAwareEx; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; public class JsonWriter { private ConcurrentHashMap, JsonWriterI> data; private LinkedList writerInterfaces; public JsonWriter() { data = new ConcurrentHashMap, JsonWriterI>(); writerInterfaces = new LinkedList(); init(); } /** * remap field name in custom classes * * @param fromJava * field name in java * @param toJson * field name in json * @since 2.1.1 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public void remapField(Class type, String fromJava, String toJson) { JsonWriterI map = this.getWrite(type); if (!(map instanceof BeansWriterASMRemap)) { map = new BeansWriterASMRemap(); registerWriter(map, type); } ((BeansWriterASMRemap) map).renameField(fromJava, toJson); } static class WriterByInterface { public Class _interface; public JsonWriterI _writer; public WriterByInterface(Class _interface, JsonWriterI _writer) { this._interface = _interface; this._writer = _writer; } } /** * try to find a Writer by Checking implemented interface * @param clazz class to serialize * @return a Writer or null */ @SuppressWarnings("rawtypes") public JsonWriterI getWriterByInterface(Class clazz) { for (WriterByInterface w : writerInterfaces) { if (w._interface.isAssignableFrom(clazz)) return w._writer; } return null; } @SuppressWarnings("rawtypes") public JsonWriterI getWrite(Class cls) { return data.get(cls); } final static public JsonWriterI JSONStreamAwareWriter = new JsonWriterI() { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { value.writeJSONString(out); } }; final static public JsonWriterI JSONStreamAwareExWriter = new JsonWriterI() { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { value.writeJSONString(out, compression); } }; final static public JsonWriterI JSONJSONAwareExWriter = new JsonWriterI() { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { out.append(value.toJSONString(compression)); } }; final static public JsonWriterI JSONJSONAwareWriter = new JsonWriterI() { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { out.append(value.toJSONString()); } }; final static public JsonWriterI> JSONIterableWriter = new JsonWriterI>() { public > void writeJSONString(E list, Appendable out, JSONStyle compression) throws IOException { boolean first = true; compression.arrayStart(out); for (Object value : list) { if (first) { first = false; compression.arrayfirstObject(out); } else { compression.arrayNextElm(out); } if (value == null) out.append("null"); else JSONValue.writeJSONString(value, out, compression); compression.arrayObjectEnd(out); } compression.arrayStop(out); } }; final static public JsonWriterI> EnumWriter = new JsonWriterI>() { public > void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException { @SuppressWarnings("rawtypes") String s = ((Enum) value).name(); compression.writeString(out, s); } }; final static public JsonWriterI> JSONMapWriter = new JsonWriterI>() { public > void writeJSONString(E map, Appendable out, JSONStyle compression) throws IOException { boolean first = true; compression.objectStart(out); /** * do not use to handle non String key maps */ for (Map.Entry entry : map.entrySet()) { Object v = entry.getValue(); if (v == null && compression.ignoreNull()) continue; if (first) { compression.objectFirstStart(out); first = false; } else { compression.objectNext(out); } JsonWriter.writeJSONKV(entry.getKey().toString(), v, out, compression); // compression.objectElmStop(out); } compression.objectStop(out); } }; /** * Json-Smart V2 Beans serialiser * * Based on ASM */ final static public JsonWriterI beansWriterASM = new BeansWriterASM(); /** * Json-Smart V1 Beans serialiser */ final static public JsonWriterI beansWriter = new BeansWriter(); /** * Json-Smart ArrayWriterClass */ final static public JsonWriterI arrayWriter = new ArrayWriter(); /** * ToString Writer */ final static public JsonWriterI toStringWriter = new JsonWriterI() { public void writeJSONString(Object value, Appendable out, JSONStyle compression) throws IOException { out.append(value.toString()); } }; public void init() { registerWriter(new JsonWriterI() { public void writeJSONString(String value, Appendable out, JSONStyle compression) throws IOException { compression.writeString(out, (String) value); } }, String.class); registerWriter(new JsonWriterI() { public void writeJSONString(Double value, Appendable out, JSONStyle compression) throws IOException { if (value.isInfinite()) out.append("null"); else out.append(value.toString()); } }, Double.class); registerWriter(new JsonWriterI() { public void writeJSONString(Date value, Appendable out, JSONStyle compression) throws IOException { out.append('"'); JSONValue.escape(value.toString(), out, compression); out.append('"'); } }, Date.class); registerWriter(new JsonWriterI() { public void writeJSONString(Float value, Appendable out, JSONStyle compression) throws IOException { if (value.isInfinite()) out.append("null"); else out.append(value.toString()); } }, Float.class); registerWriter(toStringWriter, Integer.class, Long.class, Byte.class, Short.class, BigInteger.class, BigDecimal.class); registerWriter(toStringWriter, Boolean.class); /** * Array */ registerWriter(new JsonWriterI() { public void writeJSONString(int[] value, Appendable out, JSONStyle compression) throws IOException { boolean needSep = false; compression.arrayStart(out); for (int b : value) { if (needSep) compression.objectNext(out); else needSep = true; out.append(Integer.toString(b)); } compression.arrayStop(out); } }, int[].class); registerWriter(new JsonWriterI() { public void writeJSONString(short[] value, Appendable out, JSONStyle compression) throws IOException { boolean needSep = false; compression.arrayStart(out); for (short b : value) { if (needSep) compression.objectNext(out); else needSep = true; out.append(Short.toString(b)); } compression.arrayStop(out); } }, short[].class); registerWriter(new JsonWriterI() { public void writeJSONString(long[] value, Appendable out, JSONStyle compression) throws IOException { boolean needSep = false; compression.arrayStart(out); for (long b : value) { if (needSep) compression.objectNext(out); else needSep = true; out.append(Long.toString(b)); } compression.arrayStop(out); } }, long[].class); registerWriter(new JsonWriterI() { public void writeJSONString(float[] value, Appendable out, JSONStyle compression) throws IOException { boolean needSep = false; compression.arrayStart(out); for (float b : value) { if (needSep) compression.objectNext(out); else needSep = true; out.append(Float.toString(b)); } compression.arrayStop(out); } }, float[].class); registerWriter(new JsonWriterI() { public void writeJSONString(double[] value, Appendable out, JSONStyle compression) throws IOException { boolean needSep = false; compression.arrayStart(out); for (double b : value) { if (needSep) compression.objectNext(out); else needSep = true; out.append(Double.toString(b)); } compression.arrayStop(out); } }, double[].class); registerWriter(new JsonWriterI() { public void writeJSONString(boolean[] value, Appendable out, JSONStyle compression) throws IOException { boolean needSep = false; compression.arrayStart(out); for (boolean b : value) { if (needSep) compression.objectNext(out); else needSep = true; out.append(Boolean.toString(b)); } compression.arrayStop(out); } }, boolean[].class); registerWriterInterface(JSONStreamAwareEx.class, JsonWriter.JSONStreamAwareExWriter); registerWriterInterface(JSONStreamAware.class, JsonWriter.JSONStreamAwareWriter); registerWriterInterface(JSONAwareEx.class, JsonWriter.JSONJSONAwareExWriter); registerWriterInterface(JSONAware.class, JsonWriter.JSONJSONAwareWriter); registerWriterInterface(Map.class, JsonWriter.JSONMapWriter); registerWriterInterface(Iterable.class, JsonWriter.JSONIterableWriter); registerWriterInterface(Enum.class, JsonWriter.EnumWriter); registerWriterInterface(Number.class, JsonWriter.toStringWriter); } /** * associate an Writer to a interface With Hi priority * @param interFace interface to map * @param writer writer Object * @deprecated use registerWriterInterfaceFirst */ public void addInterfaceWriterFirst(Class interFace, JsonWriterI writer) { registerWriterInterfaceFirst(interFace, writer); } /** * associate an Writer to a interface With Low priority * @param interFace interface to map * @param writer writer Object * @deprecated use registerWriterInterfaceLast */ public void addInterfaceWriterLast(Class interFace, JsonWriterI writer) { registerWriterInterfaceLast(interFace, writer); } /** * associate an Writer to a interface With Low priority * @param interFace interface to map * @param writer writer Object */ public void registerWriterInterfaceLast(Class interFace, JsonWriterI writer) { writerInterfaces.addLast(new WriterByInterface(interFace, writer)); } /** * associate an Writer to a interface With Hi priority * @param interFace interface to map * @param writer writer Object */ public void registerWriterInterfaceFirst(Class interFace, JsonWriterI writer) { writerInterfaces.addFirst(new WriterByInterface(interFace, writer)); } /** * an alias for registerWriterInterfaceLast * @param interFace interface to map * @param writer writer Object */ public void registerWriterInterface(Class interFace, JsonWriterI writer) { registerWriterInterfaceLast(interFace, writer); } /** * associate an Writer to a Class * @param writer * @param cls */ public void registerWriter(JsonWriterI writer, Class... cls) { for (Class c : cls) data.put(c, writer); } /** * Write a Key : value entry to a stream */ public static void writeJSONKV(String key, Object value, Appendable out, JSONStyle compression) throws IOException { if (key == null) out.append("null"); else if (!compression.mustProtectKey(key)) out.append(key); else { out.append('"'); JSONValue.escape(key, out, compression); out.append('"'); } compression.objectEndOfKey(out); if (value instanceof String) { compression.writeString(out, (String) value); } else JSONValue.writeJSONString(value, out, compression); compression.objectElmStop(out); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/reader/JsonWriterI.java000066400000000000000000000003661475302255200325030ustar00rootroot00000000000000package net.minidev.json.reader; import java.io.IOException; import net.minidev.json.JSONStyle; public interface JsonWriterI { public void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException; } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/000077500000000000000000000000001475302255200274665ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/ArraysMapper.java000066400000000000000000000174271475302255200327520ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; public class ArraysMapper extends JsonReaderI { public ArraysMapper(JsonReader base) { super(base); } @Override public Object createArray() { return new ArrayList(); } @SuppressWarnings("unchecked") @Override public void addValue(Object current, Object value) { ((List) current).add(value); } @SuppressWarnings("unchecked") @Override public T convert(Object current) { return (T) current; } public static class GenericMapper extends ArraysMapper { final Class componentType; JsonReaderI subMapper; public GenericMapper(JsonReader base, Class type) { super(base); this.componentType = type.getComponentType(); } @SuppressWarnings("unchecked") @Override public T convert(Object current) { int p = 0; Object[] r = (Object[]) Array.newInstance(componentType, ((List) current).size()); for (Object e : ((List) current)) r[p++] = e; return (T) r; } @Override public JsonReaderI startArray(String key) { if (subMapper == null) subMapper = base.getMapper(componentType); return subMapper; } @Override public JsonReaderI startObject(String key) { if (subMapper == null) subMapper = base.getMapper(componentType); return subMapper; } }; public static JsonReaderI MAPPER_PRIM_INT = new ArraysMapper(null) { @Override public int[] convert(Object current) { int p = 0; int[] r = new int[((List) current).size()]; for (Object e : ((List) current)) r[p++] = ((Number) e).intValue(); return r; } }; public static JsonReaderI MAPPER_INT = new ArraysMapper(null) { @Override public Integer[] convert(Object current) { int p = 0; Integer[] r = new Integer[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; if (e instanceof Integer) r[p] = (Integer) e; else r[p] = ((Number) e).intValue(); p++; } return r; } }; public static JsonReaderI MAPPER_PRIM_SHORT = new ArraysMapper(null) { @Override public short[] convert(Object current) { int p = 0; short[] r = new short[((List) current).size()]; for (Object e : ((List) current)) r[p++] = ((Number) e).shortValue(); return r; } }; public static JsonReaderI MAPPER_SHORT = new ArraysMapper(null) { @Override public Short[] convert(Object current) { int p = 0; Short[] r = new Short[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; if (e instanceof Short) r[p] = (Short) e; else r[p] = ((Number) e).shortValue(); p++; } return r; } }; public static JsonReaderI MAPPER_PRIM_BYTE = new ArraysMapper(null) { @Override public byte[] convert(Object current) { int p = 0; byte[] r = new byte[((List) current).size()]; for (Object e : ((List) current)) r[p++] = ((Number) e).byteValue(); return r; } }; public static JsonReaderI MAPPER_BYTE = new ArraysMapper(null) { @Override public Byte[] convert(Object current) { int p = 0; Byte[] r = new Byte[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; if (e instanceof Byte) r[p] = (Byte) e; else r[p] = ((Number) e).byteValue(); p++; } return r; } }; public static JsonReaderI MAPPER_PRIM_CHAR = new ArraysMapper(null) { @Override public char[] convert(Object current) { int p = 0; char[] r = new char[((List) current).size()]; for (Object e : ((List) current)) r[p++] = e.toString().charAt(0); return r; } }; public static JsonReaderI MAPPER_CHAR = new ArraysMapper(null) { @Override public Character[] convert(Object current) { int p = 0; Character[] r = new Character[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; r[p] = e.toString().charAt(0); p++; } return r; } }; public static JsonReaderI MAPPER_PRIM_LONG = new ArraysMapper(null) { @Override public long[] convert(Object current) { int p = 0; long[] r = new long[((List) current).size()]; for (Object e : ((List) current)) r[p++] = ((Number) e).intValue(); return r; } }; public static JsonReaderI MAPPER_LONG = new ArraysMapper(null) { @Override public Long[] convert(Object current) { int p = 0; Long[] r = new Long[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; if (e instanceof Float) r[p] = ((Long) e); else r[p] = ((Number) e).longValue(); p++; } return r; } }; public static JsonReaderI MAPPER_PRIM_FLOAT = new ArraysMapper(null) { @Override public float[] convert(Object current) { int p = 0; float[] r = new float[((List) current).size()]; for (Object e : ((List) current)) r[p++] = ((Number) e).floatValue(); return r; } }; public static JsonReaderI MAPPER_FLOAT = new ArraysMapper(null) { @Override public Float[] convert(Object current) { int p = 0; Float[] r = new Float[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; if (e instanceof Float) r[p] = ((Float) e); else r[p] = ((Number) e).floatValue(); p++; } return r; } }; public static JsonReaderI MAPPER_PRIM_DOUBLE = new ArraysMapper(null) { @Override public double[] convert(Object current) { int p = 0; double[] r = new double[((List) current).size()]; for (Object e : ((List) current)) r[p++] = ((Number) e).doubleValue(); return r; } }; public static JsonReaderI MAPPER_DOUBLE = new ArraysMapper(null) { @Override public Double[] convert(Object current) { int p = 0; Double[] r = new Double[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; if (e instanceof Double) r[p] = ((Double) e); else r[p] = ((Number) e).doubleValue(); p++; } return r; } }; public static JsonReaderI MAPPER_PRIM_BOOL = new ArraysMapper(null) { @Override public boolean[] convert(Object current) { int p = 0; boolean[] r = new boolean[((List) current).size()]; for (Object e : ((List) current)) r[p++] = ((Boolean) e).booleanValue(); return r; } }; public static JsonReaderI MAPPER_BOOL = new ArraysMapper(null) { @Override public Boolean[] convert(Object current) { int p = 0; Boolean[] r = new Boolean[((List) current).size()]; for (Object e : ((List) current)) { if (e == null) continue; if (e instanceof Boolean) r[p] = ((Boolean) e).booleanValue(); else if (e instanceof Number) r[p] = ((Number) e).intValue() != 0; else throw new RuntimeException("can not convert " + e + " toBoolean"); p++; } return r; } }; } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/BeansMapper.java000066400000000000000000000101401475302255200325220ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.lang.reflect.Type; import java.util.Date; import java.util.HashMap; import net.minidev.asm.Accessor; import net.minidev.asm.BeansAccess; import net.minidev.asm.ConvertDate; import net.minidev.json.JSONUtil; @SuppressWarnings("unchecked") public abstract class BeansMapper extends JsonReaderI { public BeansMapper(JsonReader base) { super(base); } public abstract Object getValue(Object current, String key); public static class Bean extends JsonReaderI { final Class clz; final BeansAccess ba; final HashMap index; public Bean(JsonReader base, Class clz) { super(base); this.clz = clz; this.ba = BeansAccess.get(clz, JSONUtil.JSON_SMART_FIELD_FILTER); this.index = ba.getMap(); } @Override public void setValue(Object current, String key, Object value) { ba.set((T) current, key, value); // Accessor nfo = index.get(key); // if (nfo == null) // throw new RuntimeException("Can not set " + key + " field in " + // clz); // value = JSONUtil.convertTo(value, nfo.getType()); // ba.set((T) current, nfo.getIndex(), value); } public Object getValue(Object current, String key) { return ba.get((T) current, key); // Accessor nfo = index.get(key); // if (nfo == null) // throw new RuntimeException("Can not set " + key + " field in " + // clz); // return ba.get((T) current, nfo.getIndex()); } @Override public Type getType(String key) { Accessor nfo = index.get(key); return nfo.getGenericType(); } @Override public JsonReaderI startArray(String key) { Accessor nfo = index.get(key); if (nfo == null) throw new RuntimeException("Can not find Array '" + key + "' field in " + clz); return base.getMapper(nfo.getGenericType()); } @Override public JsonReaderI startObject(String key) { Accessor f = index.get(key); if (f == null) throw new RuntimeException("Can not find Object '" + key + "' field in " + clz); return base.getMapper(f.getGenericType()); } @Override public Object createObject() { return ba.newInstance(); } } public static class BeanNoConv extends JsonReaderI { final Class clz; final BeansAccess ba; final HashMap index; public BeanNoConv(JsonReader base, Class clz) { super(base); this.clz = clz; this.ba = BeansAccess.get(clz, JSONUtil.JSON_SMART_FIELD_FILTER); this.index = ba.getMap(); } @Override public void setValue(Object current, String key, Object value) { ba.set((T) current, key, value); } public Object getValue(Object current, String key) { return ba.get((T) current, key); } @Override public Type getType(String key) { Accessor nfo = index.get(key); return nfo.getGenericType(); } @Override public JsonReaderI startArray(String key) { Accessor nfo = index.get(key); if (nfo == null) throw new RuntimeException("Can not set " + key + " field in " + clz); return base.getMapper(nfo.getGenericType()); } @Override public JsonReaderI startObject(String key) { Accessor f = index.get(key); if (f == null) throw new RuntimeException("Can not set " + key + " field in " + clz); return base.getMapper(f.getGenericType()); } @Override public Object createObject() { return ba.newInstance(); } } public static JsonReaderI MAPPER_DATE = new ArraysMapper(null) { @Override public Date convert(Object current) { return ConvertDate.convertToDate(current); } }; } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/CollectionMapper.java000066400000000000000000000143441475302255200335770ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; import net.minidev.asm.BeansAccess; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONUtil; public class CollectionMapper { public static class MapType extends JsonReaderI { final ParameterizedType type; final Class rawClass; final Class instance; final BeansAccess ba; final Type keyType; final Type valueType; final Class keyClass; final Class valueClass; JsonReaderI subMapper; public MapType(JsonReader base, ParameterizedType type) { super(base); this.type = type; this.rawClass = (Class) type.getRawType(); if (rawClass.isInterface()) instance = JSONObject.class; else instance = rawClass; ba = BeansAccess.get(instance, JSONUtil.JSON_SMART_FIELD_FILTER); keyType = type.getActualTypeArguments()[0]; valueType = type.getActualTypeArguments()[1]; if (keyType instanceof Class) keyClass = (Class) keyType; else keyClass = (Class) ((ParameterizedType) keyType).getRawType(); if (valueType instanceof Class) valueClass = (Class) valueType; else valueClass = (Class) ((ParameterizedType) valueType).getRawType(); } @Override public Object createObject() { try { return instance.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } @Override public JsonReaderI startArray(String key) { if (subMapper == null) subMapper = base.getMapper(valueType); return subMapper; } @Override public JsonReaderI startObject(String key) { if (subMapper == null) subMapper = base.getMapper(valueType); return subMapper; } @SuppressWarnings("unchecked") @Override public void setValue(Object current, String key, Object value) { ((Map) current).put(JSONUtil.convertToX(key, keyClass), JSONUtil.convertToX(value, valueClass)); } @SuppressWarnings("unchecked") @Override public Object getValue(Object current, String key) { return ((Map) current).get(JSONUtil.convertToX(key, keyClass)); } @Override public Type getType(String key) { return type; } }; public static class MapClass extends JsonReaderI { final Class type; final Class instance; final BeansAccess ba; JsonReaderI subMapper; public MapClass(JsonReader base, Class type) { super(base); this.type = type; if (type.isInterface()) this.instance = JSONObject.class; else this.instance = type; this.ba = BeansAccess.get(instance, JSONUtil.JSON_SMART_FIELD_FILTER); } @Override public Object createObject() { return ba.newInstance(); } @Override public JsonReaderI startArray(String key) { return base.DEFAULT ; // _ARRAY } @Override public JsonReaderI startObject(String key) { return base.DEFAULT; // _MAP } @SuppressWarnings("unchecked") @Override public void setValue(Object current, String key, Object value) { ((Map) current).put(key, value); } @SuppressWarnings("unchecked") @Override public Object getValue(Object current, String key) { return ((Map) current).get(key); } @Override public Type getType(String key) { return type; } }; public static class ListType extends JsonReaderI { final ParameterizedType type; final Class rawClass; final Class instance; final BeansAccess ba; final Type valueType; final Class valueClass; JsonReaderI subMapper; public ListType(JsonReader base, ParameterizedType type) { super(base); this.type = type; this.rawClass = (Class) type.getRawType(); if (rawClass.isInterface()) instance = JSONArray.class; else instance = rawClass; ba = BeansAccess.get(instance, JSONUtil.JSON_SMART_FIELD_FILTER); // NEW valueType = type.getActualTypeArguments()[0]; if (valueType instanceof Class) valueClass = (Class) valueType; else valueClass = (Class) ((ParameterizedType) valueType).getRawType(); } @Override public Object createArray() { return ba.newInstance(); } @Override public JsonReaderI startArray(String key) { if (subMapper == null) subMapper = base.getMapper(type.getActualTypeArguments()[0]); return subMapper; } @Override public JsonReaderI startObject(String key) { if (subMapper == null) subMapper = base.getMapper(type.getActualTypeArguments()[0]); return subMapper; } @SuppressWarnings("unchecked") @Override public void addValue(Object current, Object value) { ((List) current).add(JSONUtil.convertToX(value, valueClass)); } }; public static class ListClass extends JsonReaderI { final Class type; final Class instance; final BeansAccess ba; JsonReaderI subMapper; public ListClass(JsonReader base, Class clazz) { super(base); this.type = clazz; if (clazz.isInterface()) instance = JSONArray.class; else instance = clazz; ba = BeansAccess.get(instance, JSONUtil.JSON_SMART_FIELD_FILTER); } @Override public Object createArray() { return ba.newInstance(); } @Override public JsonReaderI startArray(String key) { return base.DEFAULT;// _ARRAY; } @Override public JsonReaderI startObject(String key) { return base.DEFAULT;// _MAP; } @SuppressWarnings("unchecked") @Override public void addValue(Object current, Object value) { ((List) current).add(value); } }; } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/CompessorMapper.java000066400000000000000000000121531475302255200334520ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; public class CompessorMapper extends JsonReaderI { private Appendable out; private JSONStyle compression; private Boolean _isObj; private boolean needSep = false; private boolean isOpen = false; private boolean isClosed = false; // private boolean isRoot = false; private boolean isArray() { return _isObj == Boolean.FALSE; } private boolean isObject() { return _isObj == Boolean.TRUE; } private boolean isCompressor(Object obj) { return obj instanceof CompessorMapper; } public CompessorMapper(JsonReader base, Appendable out, JSONStyle compression) { this(base, out, compression, null); // isRoot = true; } public CompessorMapper(JsonReader base, Appendable out, JSONStyle compression, Boolean isObj) { super(base); this.out = out; this.compression = compression; this._isObj = isObj; // System.out.println("new CompressorMapper isObj:" + isObj); } @Override public JsonReaderI startObject(String key) throws IOException { open(this); startKey(key); // System.out.println("startObject " + key); CompessorMapper r = new CompessorMapper(base, out, compression, true); open(r); return r; } @Override public JsonReaderI startArray(String key) throws IOException { open(this); startKey(key); // System.out.println("startArray " + key); CompessorMapper r = new CompessorMapper(base, out, compression, false); open(r); return r; } private void startKey(String key) throws IOException { addComma(); // if (key == null) // return; if (isArray()) return; if (!compression.mustProtectKey(key)) out.append(key); else { out.append('"'); JSONValue.escape(key, out, compression); out.append('"'); } out.append(':'); } @Override public void setValue(Object current, String key, Object value) throws IOException { // System.out.println("setValue(" + key + "," + value + ")"); // if compressor => data already be written if (isCompressor(value)) { addComma(); return; } startKey(key); writeValue(value); } @Override public void addValue(Object current, Object value) throws IOException { // System.out.println("add value" + value); // if (!isCompressor(value)) addComma(); writeValue(value); } private void addComma() throws IOException { if (needSep) { out.append(','); // needSep = false; } else { needSep = true; } } private void writeValue(Object value) throws IOException { if (value instanceof String) { compression.writeString(out, (String) value); // // if (!compression.mustProtectValue((String) value)) // out.append((String) value); // else { // out.append('"'); // JSONValue.escape((String) value, out, compression); // out.append('"'); // } // needSep = true; } else { if (isCompressor(value)) { close(value); // needSep = true; } else { JSONValue.writeJSONString(value, out, compression); // needSep = true; } } } @Override public Object createObject() { // System.out.println("createObject"); this._isObj = true; try { open(this); } catch (Exception e) { } // if (this.isUnknow() && isRoot) { // && isRoot // this._isObj = true; // try { // out.append('{'); // 1 // } catch (Exception e) { // } // } return this; } @Override public Object createArray() { // System.out.println("createArray"); this._isObj = false; try { open(this); } catch (Exception e) { } return this; } public CompessorMapper convert(Object current) { try { close(current); return this; } catch (Exception e) { return this; } } private void close(Object obj) throws IOException { if (!isCompressor(obj)) return; if (((CompessorMapper) obj).isClosed) return; ((CompessorMapper) obj).isClosed = true; if (((CompessorMapper) obj).isObject()) { // System.out.println("convert }"); out.append('}'); needSep = true; } else if (((CompessorMapper) obj).isArray()) { // System.out.println("convert ]"); out.append(']'); needSep = true; } } private void open(Object obj) throws IOException { if (!isCompressor(obj)) return; if (((CompessorMapper) obj).isOpen) return; ((CompessorMapper) obj).isOpen = true; if (((CompessorMapper) obj).isObject()) { // System.out.println("open {"); out.append('{'); needSep = false; } else if (((CompessorMapper) obj).isArray()) { // System.out.println("open ["); out.append('['); needSep = false; } } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/DefaultMapper.java000066400000000000000000000027601475302255200330670ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2014 JSON-SMART 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 * * http://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. */ import net.minidev.json.JSONArray; import net.minidev.json.JSONAwareEx; import net.minidev.json.JSONObject; /** * Simple Reader Class for generic Map * * @author uriel * * @param */ public class DefaultMapper extends JsonReaderI { protected DefaultMapper(JsonReader base) { super(base); } @Override public JsonReaderI startObject(String key) { return base.DEFAULT; } @Override public JsonReaderI startArray(String key) { return base.DEFAULT; } @Override public Object createObject() { return new JSONObject(); } @Override public Object createArray() { return new JSONArray(); } @Override public void setValue(Object current, String key, Object value) { ((JSONObject) current).put(key, value); } @Override public void addValue(Object current, Object value) { ((JSONArray) current).add(value); } } DefaultMapperCollection.java000066400000000000000000000034541475302255200350250ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writerpackage net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.lang.reflect.Constructor; import java.util.List; import java.util.Map; public class DefaultMapperCollection extends JsonReaderI { Class clz; //? extends Collection public DefaultMapperCollection(JsonReader base, Class clz) { super(base); this.clz = clz; } // public static AMapper DEFAULT = new // DefaultMapperCollection(); @Override public JsonReaderI startObject(String key) { return this; } @Override public JsonReaderI startArray(String key) { return this; } @Override public Object createObject() { try { Constructor c = clz.getConstructor(); return c.newInstance(); } catch (Exception e) { return null; } } @Override public Object createArray() { try { Constructor c = clz.getConstructor(); return c.newInstance(); } catch (Exception e) { return null; } } @SuppressWarnings({ "unchecked"}) @Override public void setValue(Object current, String key, Object value) { ((Map) current).put(key, value); } @SuppressWarnings("unchecked") @Override public void addValue(Object current, Object value) { ((List) current).add(value); } } DefaultMapperOrdered.java000066400000000000000000000030051475302255200343060ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writerpackage net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.util.LinkedHashMap; import java.util.Map; import net.minidev.json.JSONArray; import net.minidev.json.JSONAwareEx; public class DefaultMapperOrdered extends JsonReaderI { protected DefaultMapperOrdered(JsonReader base) { super(base); }; @Override public JsonReaderI startObject(String key) { return base.DEFAULT_ORDERED; } @Override public JsonReaderI startArray(String key) { return base.DEFAULT_ORDERED; } @SuppressWarnings("unchecked") public void setValue(Object current, String key, Object value) { ((Map) current).put(key, value); } @Override public Object createObject() { return new LinkedHashMap(); } @Override public void addValue(Object current, Object value) { ((JSONArray) current).add(value); } @Override public Object createArray() { return new JSONArray(); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/FakeMapper.java000066400000000000000000000023221475302255200323430ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ public class FakeMapper extends JsonReaderI { private FakeMapper() { super(null); } public static JsonReaderI DEFAULT = new FakeMapper(); @Override public JsonReaderI startObject(String key) { return this; } @Override public JsonReaderI startArray(String key) { return this; } @Override public void setValue(Object current, String key, Object value) { } @Override public void addValue(Object current, Object value) { } @Override public Object createObject() { return null; } @Override public Object createArray() { return null; } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/JsonReader.java000066400000000000000000000113461475302255200323720ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.minidev.json.JSONArray; import net.minidev.json.JSONAware; import net.minidev.json.JSONAwareEx; import net.minidev.json.JSONObject; public class JsonReader { private final ConcurrentHashMap> cache; public JsonReaderI DEFAULT; public JsonReaderI DEFAULT_ORDERED; public JsonReader() { cache = new ConcurrentHashMap>(100); cache.put(Date.class, BeansMapper.MAPPER_DATE); cache.put(int[].class, ArraysMapper.MAPPER_PRIM_INT); cache.put(Integer[].class, ArraysMapper.MAPPER_INT); cache.put(short[].class, ArraysMapper.MAPPER_PRIM_INT); cache.put(Short[].class, ArraysMapper.MAPPER_INT); cache.put(long[].class, ArraysMapper.MAPPER_PRIM_LONG); cache.put(Long[].class, ArraysMapper.MAPPER_LONG); cache.put(byte[].class, ArraysMapper.MAPPER_PRIM_BYTE); cache.put(Byte[].class, ArraysMapper.MAPPER_BYTE); cache.put(char[].class, ArraysMapper.MAPPER_PRIM_CHAR); cache.put(Character[].class, ArraysMapper.MAPPER_CHAR); cache.put(float[].class, ArraysMapper.MAPPER_PRIM_FLOAT); cache.put(Float[].class, ArraysMapper.MAPPER_FLOAT); cache.put(double[].class, ArraysMapper.MAPPER_PRIM_DOUBLE); cache.put(Double[].class, ArraysMapper.MAPPER_DOUBLE); cache.put(boolean[].class, ArraysMapper.MAPPER_PRIM_BOOL); cache.put(Boolean[].class, ArraysMapper.MAPPER_BOOL); this.DEFAULT = new DefaultMapper(this); this.DEFAULT_ORDERED = new DefaultMapperOrdered(this); cache.put(JSONAwareEx.class, this.DEFAULT); cache.put(JSONAware.class, this.DEFAULT); cache.put(JSONArray.class, this.DEFAULT); cache.put(JSONObject.class, this.DEFAULT); } /** * remap field name in custom classes * * @param fromJson * field name in json * @param toJava * field name in Java * @since 2.1.1 */ public void remapField(Class type, String fromJson, String toJava) { JsonReaderI map = this.getMapper(type); if (!(map instanceof MapperRemapped)) { map = new MapperRemapped(map); registerReader(type, map); } ((MapperRemapped) map).renameField(fromJson, toJava); } public void registerReader(Class type, JsonReaderI mapper) { cache.put(type, mapper); } @SuppressWarnings("unchecked") public JsonReaderI getMapper(Type type) { if (type instanceof ParameterizedType) return getMapper((ParameterizedType) type); return getMapper((Class) type); } /** * Get the corresponding mapper Class, or create it on first call * * @param type * to be map */ public JsonReaderI getMapper(Class type) { // look for cached Mapper @SuppressWarnings("unchecked") JsonReaderI map = (JsonReaderI) cache.get(type); if (map != null) return map; /* * Special handle */ if (type instanceof Class) { if (Map.class.isAssignableFrom(type)) map = new DefaultMapperCollection(this, type); else if (List.class.isAssignableFrom(type)) map = new DefaultMapperCollection(this, type); if (map != null) { cache.put(type, map); return map; } } if (type.isArray()) map = new ArraysMapper.GenericMapper(this, type); else if (List.class.isAssignableFrom(type)) map = new CollectionMapper.ListClass(this, type); else if (Map.class.isAssignableFrom(type)) map = new CollectionMapper.MapClass(this, type); else // use bean class map = new BeansMapper.Bean(this, type); cache.putIfAbsent(type, map); return map; } @SuppressWarnings("unchecked") public JsonReaderI getMapper(ParameterizedType type) { JsonReaderI map = (JsonReaderI) cache.get(type); if (map != null) return map; Class clz = (Class) type.getRawType(); if (List.class.isAssignableFrom(clz)) map = new CollectionMapper.ListType(this, type); else if (Map.class.isAssignableFrom(clz)) map = new CollectionMapper.MapType(this, type); cache.putIfAbsent(type, map); return map; } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/JsonReaderI.java000066400000000000000000000062561475302255200325070ustar00rootroot00000000000000package net.minidev.json.writer; /* * Copyright 2011-2024 JSON-SMART 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 * * http://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. */ import java.io.IOException; import java.lang.reflect.Type; import net.minidev.json.parser.ParseException; /** * Default datatype mapper use by Json-smart ton store data. * * @author uriel Chemouni * * @param result type */ public abstract class JsonReaderI { public final JsonReader base; /** * Reader can be link to the JsonReader Base * * @param base parent reader */ public JsonReaderI(JsonReader base) { this.base = base; } private static String ERR_MSG = "Invalid or non Implemented status"; /** * called when json-smart parser meet an object key * @param key key name */ public JsonReaderI startObject(String key) throws ParseException, IOException { throw new RuntimeException(ERR_MSG + " startObject(String key) in " + this.getClass() + " key=" + key); } /** * called when json-smart parser start an array. * * @param key the destination key name, or null. */ public JsonReaderI startArray(String key) throws ParseException, IOException { throw new RuntimeException(ERR_MSG + " startArray in " + this.getClass() + " key=" + key); } /** * called when json-smart done parsing a value */ public void setValue(Object current, String key, Object value) throws ParseException, IOException { throw new RuntimeException(ERR_MSG + " setValue in " + this.getClass() + " key=" + key); } /** * ------------- */ public Object getValue(Object current, String key) { throw new RuntimeException(ERR_MSG + " getValue(Object current, String key) in " + this.getClass() + " key=" + key); } // Object current, public Type getType(String key) { throw new RuntimeException(ERR_MSG + " getType(String key) in " + this.getClass() + " key=" + key); } /** * add a value in an array json object. */ public void addValue(Object current, Object value) throws ParseException, IOException { throw new RuntimeException(ERR_MSG + " addValue(Object current, Object value) in " + this.getClass()); } /** * use to instantiate a new object that will be used as an object */ public Object createObject() { throw new RuntimeException(ERR_MSG + " createObject() in " + this.getClass()); } /** * use to instantiate a new object that will be used as an array */ public Object createArray() { throw new RuntimeException(ERR_MSG + " createArray() in " + this.getClass()); } /** * Allow a mapper to convert a temporary structure to the final data format. * * example: convert an List<Integer> to an int[] */ @SuppressWarnings("unchecked") public T convert(Object current) { return (T) current; } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/MapperRemapped.java000066400000000000000000000030141475302255200332310ustar00rootroot00000000000000package net.minidev.json.writer; import java.io.IOException; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import net.minidev.json.parser.ParseException; /** * Simple solution to support on read field renaming * * @author uriel * * @param */ public class MapperRemapped extends JsonReaderI { private Map rename; private JsonReaderI parent; public MapperRemapped(JsonReaderI parent) { super(parent.base); this.parent = parent; this.rename = new HashMap(); } public void renameField(String source, String dest) { rename.put(source, dest); } private String rename(String key) { String k2 = rename.get(key); if (k2 != null) return k2; return key; } @Override public void setValue(Object current, String key, Object value) throws ParseException, IOException { key = rename(key); parent.setValue(current, key, value); } public Object getValue(Object current, String key) { key = rename(key); return parent.getValue(current, key); } @Override public Type getType(String key) { key = rename(key); return parent.getType(key); } @Override public JsonReaderI startArray(String key) throws ParseException, IOException { key = rename(key); return parent.startArray(key); } @Override public JsonReaderI startObject(String key) throws ParseException, IOException { key = rename(key); return parent.startObject(key); } @Override public Object createObject() { return parent.createObject(); } } netplex-json-smart-v2-20dff24/json-smart/src/main/java/net/minidev/json/writer/UpdaterMapper.java000066400000000000000000000045101475302255200331020ustar00rootroot00000000000000package net.minidev.json.writer; import java.io.IOException; import java.lang.reflect.Type; import net.minidev.json.parser.ParseException; public class UpdaterMapper extends JsonReaderI { final T obj; final JsonReaderI mapper; public UpdaterMapper(JsonReader base, T obj) { super(base); if (obj == null) throw new NullPointerException("can not update null Object"); this.obj = obj; this.mapper = (JsonReaderI) base.getMapper(obj.getClass()); } public UpdaterMapper(JsonReader base, T obj, Type type) { super(base); if (obj == null) throw new NullPointerException("can not update null Object"); this.obj = obj; this.mapper = (JsonReaderI) base.getMapper(type); } /** * called when json-smart parser meet an object key */ public JsonReaderI startObject(String key) throws ParseException, IOException { Object bean = mapper.getValue(obj, key); if (bean == null) return mapper.startObject(key); return new UpdaterMapper(base, bean, mapper.getType(key)); } /** * called when json-smart parser start an array. * * @param key * the destination key name, or null. */ public JsonReaderI startArray(String key) throws ParseException, IOException { // if (obj != null) return mapper.startArray(key); } /** * called when json-smart done parsing a value */ public void setValue(Object current, String key, Object value) throws ParseException, IOException { // if (obj != null) mapper.setValue(current, key, value); } /** * add a value in an array json object. */ public void addValue(Object current, Object value) throws ParseException, IOException { // if (obj != null) mapper.addValue(current, value); } /** * use to instantiate a new object that will be used as an object */ public Object createObject() { if (obj != null) return obj; return mapper.createObject(); } /** * use to instantiate a new object that will be used as an array */ public Object createArray() { if (obj != null) return obj; return mapper.createArray(); } /** * Allow a mapper to convert a temporary structure to the final data format. * * example: convert an List<Integer> to an int[] */ @SuppressWarnings("unchecked") public T convert(Object current) { if (obj != null) return obj; return (T) mapper.convert(current); } } netplex-json-smart-v2-20dff24/json-smart/src/test/000077500000000000000000000000001475302255200220725ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/000077500000000000000000000000001475302255200230135ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/000077500000000000000000000000001475302255200236015ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/000077500000000000000000000000001475302255200252345ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/000077500000000000000000000000001475302255200262055ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/000077500000000000000000000000001475302255200271645ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/JSONSimpleTest.java000066400000000000000000000013141475302255200326110ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONArray; import net.minidev.json.parser.JSONParser; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class JSONSimpleTest { @Test public void testLong() throws Exception { String s = "[1]"; JSONParser p = new JSONParser(JSONParser.MODE_JSON_SIMPLE); JSONArray array = (JSONArray) p.parse(s); assertEquals(Long.valueOf(1), (Long) array.get(0)); } @Test public void testDefault() throws Exception { String s = "[1]"; JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); JSONArray array = (JSONArray) p.parse(s); assertEquals(Integer.valueOf(1), (Integer) array.get(0)); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/MustThrows.java000066400000000000000000000024261475302255200321720ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.api.Test; public class MustThrows { @Test public static void testStrictInvalidJson(String json, int execptionType) throws Exception { testStrictInvalidJson(json, execptionType, null); } @Test public static void testStrictInvalidJson(String json, int execptionType, Class cls) throws Exception { testInvalidJson(json, JSONParser.MODE_RFC4627, execptionType, cls); } @Test public static void testInvalidJson(String json, int permissifMode, int execptionType) throws Exception { testInvalidJson(json, permissifMode, execptionType, null); } public static void testInvalidJson(String json, int permissifMode, int execptionType, Class cls) throws Exception { JSONParser p = new JSONParser(permissifMode); try { if (cls == null) p.parse(json); else p.parse(json, cls); assertFalse(true, "Exception Should Occure parsing:" + json); } catch (ParseException e) { if (execptionType == -1) execptionType = e.getErrorType(); assertEquals(execptionType, e.getErrorType()); } } } SerializeReadonlyField.java000066400000000000000000000025201475302255200343400ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testpackage net.minidev.json.test; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.junit.jupiter.api.Test; public class SerializeReadonlyField { /** * https://github.com/netplex/json-smart-v2/issues/49 */ @Test public static void main(String[] args) { MyData data = new MyData("a"); Map m = new HashMap<>(); m.put("data", data); String a = new JSONObject(m).toString(); assertEquals("{\"data\":{\"someField\":\"a\"}}", a.toString()); } public static class MyData { private String someField; public MyData(String someField) { this.someField = someField; } public String getSomeField() { return someField; } // Remove comment to make serialization to work /* * public void setSomeField(String someField) { this.someField = someField; } */ } /** * https://github.com/netplex/json-smart-v2/issues/59 */ @Test public void test() { // should not crash Map cachedTable1 = new LinkedHashMap<>(); Iterable path = Paths.get("/"); cachedTable1.put("1", path); JSONValue.toJSONString(cachedTable1); } } TestBigDigitUnrestricted.java000066400000000000000000000022221475302255200346640ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testpackage net.minidev.json.test; import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigDecimal; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; import org.junit.jupiter.api.Test; public class TestBigDigitUnrestricted { public static String[] VALID_DOUBLE_JSON = new String[] {"{\"v\":0.12345678912345678}", "\"v\":\"1.7976931348623157E308\"", "\"v\":\"1.7976931348623157E+308\"", "\"v\":\"1.7976931348623157e+308\""}; @Test public void testRestrictedBigDigit() throws Exception { JSONParser p = new JSONParser(JSONParser.MODE_RFC4627); String json = VALID_DOUBLE_JSON[0]; JSONObject obj = (JSONObject) p.parse(json); Object value = obj.get("v"); assertEquals(Double.class, value.getClass(), "Should not Store this big number as a double"); } @Test public void testUnrestrictedBigDigit() throws Exception { JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); String json = VALID_DOUBLE_JSON[0]; JSONObject obj = (JSONObject) p.parse(json); Object value = obj.get("v"); assertEquals(BigDecimal.class, value.getClass(), "Should not Store this big number as a double"); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestBigValue.java000066400000000000000000000025641475302255200323740ustar00rootroot00000000000000package net.minidev.json.test; import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import org.junit.jupiter.api.Test; public class TestBigValue { String bigStr = "12345678901234567890123456789"; /** * test BigDecimal serialization */ @Test public void testBigDecimal() { HashMap map = new HashMap(); BigDecimal bigDec = new BigDecimal(bigStr + "." + bigStr); map.put("big", bigDec); String test = JSONValue.toJSONString(map); String result = "{\"big\":" + bigStr + "." +bigStr + "}"; assertEquals(result, test); JSONObject obj = (JSONObject)JSONValue.parse(test); assertEquals(bigDec, obj.get("big")); assertEquals(bigDec.getClass(), obj.get("big").getClass()); } /** * test BigInteger serialization */ @Test public void testBigInteger() { HashMap map = new HashMap(); BigInteger bigInt = new BigInteger(bigStr); map.put("big", bigInt); String test = JSONValue.toJSONString(map); String result = "{\"big\":" + bigStr + "}"; assertEquals(result, test); JSONObject obj = (JSONObject)JSONValue.parse(test); assertEquals(bigInt, obj.get("big")); assertEquals(bigInt.getClass(), obj.get("big").getClass()); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestCVE202457699.java000066400000000000000000000034611475302255200322440ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertThrows; public class TestCVE202457699 { private static final String MALICIOUS_STRING = createMaliciousString(); @Test public void jsonSimpleParserShouldRestrictDepth() { JSONParser p = new JSONParser(JSONParser.MODE_JSON_SIMPLE); assertThrows(ParseException.class, () -> p.parse(MALICIOUS_STRING), "Malicious payload, having non natural depths"); } @Test public void strictestParserShouldRestrictDepth() { JSONParser p = new JSONParser(JSONParser.MODE_STRICTEST); assertThrows(ParseException.class, () -> p.parse(MALICIOUS_STRING), "Malicious payload, having non natural depths"); } @Test public void rfc4627ParserShouldRestrictDepth() { JSONParser p = new JSONParser(JSONParser.MODE_RFC4627); assertThrows(ParseException.class, () -> p.parse(MALICIOUS_STRING), "Malicious payload, having non natural depths"); } @Test public void permissiveParserShouldRestrictDepth() { JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); assertThrows(ParseException.class, () -> p.parse(MALICIOUS_STRING), "Malicious payload, having non natural depths"); } private static String createMaliciousString() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000 ; i++) { sb.append("{\"a\":"); } sb.append("1"); for (int i = 0; i < 10000 ; i++) { sb.append("}"); } return sb.toString(); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestCompressor.java000066400000000000000000000024101475302255200330200ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class TestCompressor { @Test public void testCompressor() { String j = "{'a':{'b':'c','d':'e'},f:[1,2,'XYZ']}".replace('\'', '"'); String sol = j.replace(" ", "").replace("\"", ""); String comp = JSONValue.compress(j); assertEquals(sol, comp); } @Test public void testCompressor2() { String j = "[{} ]"; String sol = j.replace(" ", ""); String comp = JSONValue.compress(j); assertEquals(sol, comp); } @Test public void testCompressor3() { String j = "[[],[],[] ]"; String sol = j.replace(" ", ""); String comp = JSONValue.compress(j); assertEquals(sol, comp); } @Test public void testCompressor4() { String j = "[[1],[2,3],[4] ]"; String sol = j.replace(" ", ""); String comp = JSONValue.compress(j); assertEquals(sol, comp); } @Test public void testCompressor5() { String j = "[{},{},{} ]"; String sol = j.replace(" ", ""); String comp = JSONValue.compress(j); assertEquals(sol, comp); } @Test public void testCompressor6() { String j = "[{a:b},{c:d},{e:f}]"; String sol = j; String comp = JSONValue.compress(j); assertEquals(sol, comp); } } TestCompressorFlags.java000066400000000000000000000050521475302255200337230ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testpackage net.minidev.json.test; import net.minidev.json.JSONObject; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; /** * Test all Compression Styles * * @author Uriel Chemouni <uchemouni@gmail.com> * */ public class TestCompressorFlags { @Test public void testProtect() throws Exception { String compressed = "{k:value}"; String nCompress = "{\"k\":\"value\"}"; JSONObject obj = (JSONObject) JSONValue.parse(nCompress); // test MAX_COMPRESS String r = obj.toJSONString(JSONStyle.MAX_COMPRESS); assertEquals(compressed, r); // test LT_COMPRESS r = obj.toJSONString(JSONStyle.LT_COMPRESS); assertEquals(nCompress, r); // test NO_COMPRESS r = obj.toJSONString(JSONStyle.NO_COMPRESS); assertEquals(nCompress, r); // only keys values JSONStyle style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_KEYS); r = obj.toJSONString(style); assertEquals("{k:\"value\"}", r); // only protect values style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_VALUES); r = obj.toJSONString(style); assertEquals("{\"k\":value}", r); } @Test public void testAggresive() throws Exception { String r; JSONStyle style; String NProtectValue = "{\"a b\":\"c d\"}"; JSONObject obj = (JSONObject) JSONValue.parse(NProtectValue); /** * Test Without Agressive */ style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_KEYS); r = obj.toJSONString(style); assertEquals(NProtectValue, r); style = new JSONStyle(-1 & JSONStyle.FLAG_PROTECT_VALUES); r = obj.toJSONString(style); assertEquals(NProtectValue, r); /** * Test With Agressive */ style = new JSONStyle(-1 & (JSONStyle.FLAG_PROTECT_VALUES | JSONStyle.FLAG_AGRESSIVE)); r = obj.toJSONString(style); assertEquals("{\"a b\":c d}", r); style = new JSONStyle(-1 & (JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_AGRESSIVE)); r = obj.toJSONString(style); assertEquals("{a b:\"c d\"}", r); style = JSONStyle.MAX_COMPRESS; r = obj.toJSONString(style); assertEquals("{a b:c d}", r); } @Test public void test4Web() throws Exception { String NProtectValue = "{\"k\":\"http:\\/\\/url\"}"; JSONObject obj = (JSONObject) JSONValue.parse(NProtectValue); String r = obj.toJSONString(JSONStyle.MAX_COMPRESS); assertEquals("{k:\"http://url\"}", r); r = obj.toJSONString(JSONStyle.LT_COMPRESS); assertEquals("{\"k\":\"http://url\"}", r); r = obj.toJSONString(JSONStyle.NO_COMPRESS); assertEquals("{\"k\":\"http:\\/\\/url\"}", r); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestFloat.java000066400000000000000000000044141475302255200317370ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONObject; import net.minidev.json.JSONStyle; import net.minidev.json.parser.JSONParser; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class TestFloat { public static String[] TRUE_NUMBERS = new String[] { "1.0", "123.456", "1.0E1", "123.456E12", "1.0E+1", "123.456E+12", "1.0E-1", "123.456E-12", "1.0e1", "123.456e12", "1.0e+1", "123.456e+12", "1.0e-1", "123.456e-12" }; public static String[] FALSE_NUMBERS = new String[] { "1.0%", "123.45.6", "1.0E", "++123.456E12", "+-01", "1.0E+1.2" }; @Test public void testPrecisionFloat() throws Exception { JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); for (int len = 15; len < 25; len++) { StringBuilder sb = new StringBuilder("0."); for (int i = 0; i < len; i++) { sb.append("123456789".charAt(i % 9)); } String s = sb.toString(); String json = "{v:" + s + "}"; JSONObject obj = (JSONObject) p.parse(json); Object value = obj.get("v").toString(); assertEquals(s, value, "Should not loose precision on a " + len + " digits long"); } } @Test public void testFloat() throws Exception { JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); for (String s : TRUE_NUMBERS) { String json = "{v:" + s + "}"; Double val = Double.valueOf(s.trim()); JSONObject obj = (JSONObject) p.parse(json); Object value = obj.get("v"); assertEquals(val, value, "Should be parse as double"); } } @Test public void testNonFloat() throws Exception { JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE); for (String s : FALSE_NUMBERS) { String json = "{v:" + s + "}"; JSONObject obj = (JSONObject) p.parse(json); assertEquals(s, obj.get("v"), "Should be parse as string"); String correct = "{\"v\":\"" + s + "\"}"; assertEquals(correct, obj.toJSONString(), "Should be re serialized as"); } } /** * Error reported in issue 44 */ @Test public void testUUID() { String UUID = "58860611416142319131902418361e88"; JSONObject obj = new JSONObject(); obj.put("uuid", UUID); String compressed = obj.toJSONString(JSONStyle.MAX_COMPRESS); assertTrue(compressed.contains("uuid:\"")); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestFloatStrict.java000066400000000000000000000014321475302255200331250ustar00rootroot00000000000000package net.minidev.json.test; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; public class TestFloatStrict { @Test public void testFloat() throws Exception { for (String s : TestFloat.TRUE_NUMBERS) { String json = "{\"v\":" + s + "}"; Double val = Double.valueOf(s.trim()); JSONObject obj = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(json); Object value = obj.get("v"); assertEquals(val, value, "Should be parse as double"); } } @Test public void testNonFloat() throws Exception { for (String s : TestFloat.FALSE_NUMBERS) { String json = "{\"v\":" + s + "}"; MustThrows.testStrictInvalidJson(json, -1); } } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestGitHubIssue.java000066400000000000000000000007651475302255200330720ustar00rootroot00000000000000package net.minidev.json.test; import org.junit.jupiter.api.Test; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import static net.minidev.json.parser.JSONParser.MODE_PERMISSIVE; import org.junit.jupiter.api.Assertions; public class TestGitHubIssue { @Test public void issue68() { Assertions.assertThrows(ParseException.class, () -> { JSONParser parser = new JSONParser(MODE_PERMISSIVE); String input = "'1"; parser.parse(input); }); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestInts.java000066400000000000000000000061551475302255200316130ustar00rootroot00000000000000package net.minidev.json.test; import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigDecimal; import java.math.BigInteger; import org.junit.jupiter.api.Test; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; public class TestInts { @Test public void testIntMax() throws Exception { String s = "{t:" + Integer.MAX_VALUE + "}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), Integer.MAX_VALUE); } @Test public void testIntMin() throws Exception { String s = "{t:" + Integer.MIN_VALUE + "}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), Integer.MIN_VALUE); } @Test public void testIntResult() throws Exception { String s = "{\"t\":1}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); assertEquals(o.get("t"), Integer.valueOf(1)); o = (JSONObject) new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse(s); assertEquals(o.get("t"), Long.valueOf(1)); o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), Integer.valueOf(1)); } @Test public void testInt() throws Exception { String s = "{t:90}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), Integer.valueOf(90)); } @Test public void testIntNeg() throws Exception { String s = "{t:-90}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), -90); } @Test public void testBigInt() throws Exception { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) sb.append(Integer.MAX_VALUE); String bigText = sb.toString(); BigInteger big = new BigInteger(bigText, 10); String s = "{t:" + bigText + "}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), big); } @Test public void testBigDoubleInt() throws Exception { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) sb.append(Integer.MAX_VALUE); sb.append('.'); for (int i = 0; i < 10; i++) sb.append(Integer.MAX_VALUE); String bigText = sb.toString(); BigDecimal big = new BigDecimal(bigText); String s = "{\"t\":" + bigText + "}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); assertEquals(o.get("t"), big); o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), big); } @Test public void testjunkTaillingData() throws Exception { String s = "{\"t\":124}$ifsisg045"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse(s); assertEquals(o.get("t"), 124L); MustThrows.testInvalidJson(s, JSONParser.MODE_RFC4627, ParseException.ERROR_UNEXPECTED_TOKEN); // o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); // assertEquals(o.get("t"), 124); o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), 124); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestInvalidNumber.java000066400000000000000000000042451475302255200334330ustar00rootroot00000000000000package net.minidev.json.test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.api.Test; import net.minidev.json.JSONObject; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; /** * test invalid number that will be handle ad string * @author uriel * */ public class TestInvalidNumber { private void validFloatAsFloat(String test) { JSONObject o = new JSONObject(); o.put("a", test); String comp = JSONValue.toJSONString(o, JSONStyle.MAX_COMPRESS); assertEquals("{a:\"" + test + "\"}", comp); o = JSONValue.parse(comp, JSONObject.class); Object convertedValue = o.get("a"); assertEquals(convertedValue, test, "Should handle valid number '" + test + "' as number"); } private void invalidFloatAsText(String test) { JSONObject o = new JSONObject(); o.put("a", test); String comp = JSONValue.toJSONString(o, JSONStyle.MAX_COMPRESS); assertEquals("{a:" + test + "}", comp); o = JSONValue.parse(comp, JSONObject.class); Object convertedValue = o.get("a"); assertEquals(convertedValue, test, "should handle invalid number '" + test + "' as string"); } @Test public void testF1() { validFloatAsFloat("51e88"); } @Test public void testF2() { validFloatAsFloat("51e+88"); } @Test public void testF3() { validFloatAsFloat("51e-88"); } @Test public void testF4() { invalidFloatAsText("51ee88"); } @Test public void testCVE_2021_27568() { try { JSONValue.parseWithException("{a:-.}"); assertFalse(true, "should Throws Exception before"); } catch (Exception e) { assertEquals(e.getMessage(), "Unexpected token -. at position 5.", "should throw EOF"); } try { JSONValue.parseWithException("{a:2e+}"); assertFalse(true, "should Throws Exception before"); } catch (Exception e) { assertEquals(e.getMessage(), "Unexpected token 2e+ at position 6.", "should throw EOF"); } try { JSONValue.parseWithException("{a:[45e-}"); assertFalse(true, "should Throws Exception before"); } catch (Exception e) { assertEquals(e.getMessage(), "Unexpected End Of File position 8: EOF", "should throw EOF"); } } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestKeyword.java000066400000000000000000000023041475302255200323120ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; public class TestKeyword { @Test public void testBool() throws Exception { String s = "{t:true}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), true); s = "{t:false}"; o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), false); } @Test public void testNull() throws Exception { String s = "{t:null}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertNull(o.get("t")); } @Test public void testNaN() throws Exception { String s = "{t:NaN}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), Float.NaN); } @Test public void testNaNStrict() throws Exception { String s = "{\"t\":NaN}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_TOKEN); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestMisc.java000066400000000000000000000035141475302255200315650ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class TestMisc { @Test public void testIssue23() throws Exception { String s = JSONValue.toJSONString(new int[] { 1, 2, 50, 1234, 10000 }); assertEquals("[1,2,50,1234,10000]", s); } @Test public void testEmptyStrict() throws Exception { String s = "{\"key1\":\"v1\", \"key2\":{}, \"key3\":[]}"; JSONObject o = (JSONObject) JSONValue.parseStrict(s); assertEquals(o.get("key1"), "v1"); assertEquals(((JSONObject) o.get("key2")).size(), 0); assertEquals(((JSONArray) o.get("key3")).size(), 0); } @Test public void testBool() throws Exception { String s = "{\"key1\":\"v1\", \"key2\":{}, \"key3\":[]}"; JSONObject o = (JSONObject) JSONValue.parseWithException(s); assertEquals(o.get("key1"), "v1"); assertEquals(((JSONObject) o.get("key2")).size(), 0); assertEquals(((JSONArray) o.get("key3")).size(), 0); } @Test public void testInt() throws Exception { String s = "123"; Object o = JSONValue.parseWithException(s); assertEquals(o, 123); } @Test public void testFloat() throws Exception { String s = "123.5"; Object o = JSONValue.parseWithException(s); assertEquals(o, Double.valueOf(123.5)); } @Test public void testFloat2() throws Exception { String s = "123.5E1"; Object o = JSONValue.parseWithException(s); assertEquals(o, Double.valueOf(1235)); } @Test public void testFloat3() throws Exception { String s = "123..5"; Object o = JSONValue.parseWithException(s); assertEquals(o, "123..5"); } @Test public void testFloat4() throws Exception { String s = "123é.5"; Object o = JSONValue.parseWithException(s); assertEquals(o, 123); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestNavi.java000066400000000000000000000044321475302255200315670ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONAwareEx; import net.minidev.json.JSONNavi; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class TestNavi { @Test public void testNaviWrite() { JSONNavi nav = JSONNavi.newInstance(); nav.set("name", "jhone").set("age", 42).at("childName").add("fifi", "riri", "loulou").up().at("cat") .set("color", "red"); String s1 = "{\"name\":\"jhone\",\"age\":42,\"childName\":[\"fifi\",\"riri\",\"loulou\"],\"cat\":{\"color\":\"red\"}}"; String s2 = nav.toString(); assertEquals(s1, s2); } @Test public void testNaviWrite2() { JSONNavi nav = JSONNavi.newInstance(); nav.at("name").set("toto").up().set("tutu", "V2").at("size").set("width", 10).set("higth", 35).up(3) .set("FinUp", 1).at("array").add(0, 1, 2, 3, 4, 5); nav.at(-1); assertEquals("/array[5]", nav.getJPath()); String s1 = "{'name':'toto','tutu':'V2','size':{'width':10,'higth':35},'FinUp':1,'array':[0,1,2,3,4,5]}" .replace('\'', '"'); String s2 = nav.toString(); assertEquals(s1, s2); } @Test public void testNaviRead() { String json = "{name:foo,str:null,ar:[1,2,3,4]}"; JSONNavi nav = new JSONNavi(json, JSONAwareEx.class); nav.at(5); assertTrue(nav.hasFailure(), "Navigator should be in error stat"); nav.root(); assertEquals(3, nav.at("ar").at(2).asInt()); nav.up(2); assertEquals(4, nav.at("ar").at(-1).asInt()); nav.up(2); assertEquals("foo", nav.at("name").asString()); } @Test public void testNaviWriteArray() { String expected = "{'type':'bundle','data':[{'type':'object','name':'obj1'},{'type':'object','name':'obj2'}]}".replace('\'', '"'); JSONNavi nav = JSONNavi.newInstance(); nav.set("type", "bundle").at("data").array().at(0).set("type", "object").set("name", "obj1").up().at(1).set("type", "object").set("name", "obj2").root(); String s2 = nav.toString(); assertEquals(expected, s2); nav = JSONNavi.newInstance(); nav.set("type", "bundle").at("data").array().atNext().set("type", "object").set("name", "obj1").up().atNext().set("type", "object").set("name", "obj2").root(); s2 = nav.toString(); assertEquals(expected, s2); } } TestNumberPrecision.java000066400000000000000000000021741475302255200337200ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testpackage net.minidev.json.test; import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigInteger; import net.minidev.json.JSONArray; import net.minidev.json.JSONValue; import org.junit.jupiter.api.Test; public class TestNumberPrecision { @Test public void testMaxLong() { Long v = Long.MAX_VALUE; String s = "[" + v + "]"; JSONArray array = (JSONArray) JSONValue.parse(s); Object r = array.get(0); assertEquals(v, r); } @Test public void testMinLong() { Long v = Long.MIN_VALUE; String s = "[" + v + "]"; JSONArray array = (JSONArray) JSONValue.parse(s); Object r = array.get(0); assertEquals(v, r); } @Test public void testMinBig() { BigInteger v = BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE); String s = "[" + v + "]"; JSONArray array = (JSONArray) JSONValue.parse(s); Object r = array.get(0); assertEquals(v, r); } @Test public void testMaxBig() { BigInteger v = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE); String s = "[" + v + "]"; JSONArray array = (JSONArray) JSONValue.parse(s); Object r = array.get(0); assertEquals(v, r); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestOverflow.java000066400000000000000000000034771475302255200325050ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONArray; import net.minidev.json.JSONValue; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import org.junit.jupiter.api.Test; public class TestOverflow { @Test public void stressTest() throws Exception { int size = 10000; StringBuilder sb = new StringBuilder(10 + size*4); for (int i=0; i < size; i++) { sb.append("{a:"); } sb.append("true"); for (int i=0; i < size; i++) { sb.append("}"); } String s = sb.toString(); try { JSONValue.parseWithException(s); } catch (ParseException e) { assertEquals(e.getErrorType(), ParseException.ERROR_UNEXPECTED_JSON_DEPTH); return; } fail(); } @Test public void shouldNotFailWhenInfiniteJsonDepth() throws Exception { int size = 500; StringBuilder sb = new StringBuilder(10 + size*4); for (int i=0; i < size; i++) { sb.append("{a:"); } sb.append("true"); for (int i=0; i < size; i++) { sb.append("}"); } String s = sb.toString(); try { JSONParser parser = new JSONParser(DEFAULT_PERMISSIVE_MODE & ~JSONParser.LIMIT_JSON_DEPTH); parser.parse(s, JSONValue.defaultReader.DEFAULT); } catch (ParseException e) { fail(); } } @Test public void shouldNotFailParsingArraysWith400Elements() throws Exception { int size = 400; StringBuilder sb = new StringBuilder(); sb.append("["); for (int i=0; i < size; i++) { sb.append("{a:true}"); if(i+1 < size) { sb.append(","); } } sb.append("]"); String s = sb.toString(); JSONArray array = (JSONArray) JSONValue.parseWithException(s); assertEquals(array.size(), size); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestStrict.java000066400000000000000000000033141475302255200321400ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class TestStrict { @Test public void testS1() throws Exception { String text = "My Test"; String s = "{t:\"" + text + "\"}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), text); } @Test public void testS2() throws Exception { String text = "My Test"; String s = "{t:'" + text + "'}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), text); } @Test public void testSEscape() throws Exception { String text = "My\r\nTest"; String text2 = "My\\r\\nTest"; String s = "{t:'" + text2 + "'}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), text); } @Test public void testBadString() throws Exception { String s = "{\"t\":\"Before\u000CAfter\"}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals("Before\u000CAfter", o.get("t")); try { o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); assertEquals("nothink", o.get("t")); } catch (ParseException e) { assertEquals("Exception", "Exception"); } } /** * issue report gitHub 8 by jochenberger */ @Test public void testDataAfterValue() throws Exception { String s = "{\"foo\":\"bar\"x}"; MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE, ParseException.ERROR_UNEXPECTED_TOKEN); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestString.java000066400000000000000000000031201475302255200321310ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class TestString { @Test public void testS0() throws Exception { MustThrows.testStrictInvalidJson("{\"1\":\"one\"\n\"2\":\"two\"}", ParseException.ERROR_UNEXPECTED_TOKEN); } @Test public void testS1() throws Exception { String text = "My Test"; String s = "{t:\"" + text + "\"}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), text); } @Test public void testS2() throws Exception { String text = "My Test"; String s = "{t:'" + text + "'}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), text); } @Test public void testSEscape() throws Exception { String text = "My\r\nTest"; String text2 = "My\\r\\nTest"; String s = "{t:'" + text2 + "'}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), text); } @Test public void testBadString() throws Exception { String s = "{\"t\":\"Before\u000CAfter\"}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals("Before\u000CAfter", o.get("t")); try { o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); assertEquals("nothink", o.get("t")); } catch (ParseException e) { assertEquals("Exception", "Exception"); } } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestStringStrict.java000066400000000000000000000010501475302255200333220ustar00rootroot00000000000000package net.minidev.json.test; import org.junit.jupiter.api.Test; import net.minidev.json.parser.ParseException; public class TestStringStrict { @Test public void testS1() throws Exception { String text = "My Test"; String s = "{t:\"" + text + "\"}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_TOKEN); } @Test public void testSEscape() throws Exception { String text2 = "My\\r\\nTest"; String s = "{\"t\":'" + text2 + "'}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestTruncated.java000066400000000000000000000011461475302255200326220ustar00rootroot00000000000000package net.minidev.json.test; import net.minidev.json.parser.ParseException; import org.junit.jupiter.api.Test; public class TestTruncated { @Test public void testS1() throws Exception { String s = "{\"key\":{}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_EOF); } @Test public void testS2() throws Exception { String s = "{\"key\":"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_EOF); } @Test public void testS3() throws Exception { String s = "{\"key\":123"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_EOF); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/TestUtf8.java000066400000000000000000000056551475302255200315300ustar00rootroot00000000000000package net.minidev.json.test; import java.io.ByteArrayInputStream; import java.io.StringReader; import java.util.stream.Stream; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; public class TestUtf8 { public static Stream languages() { return Stream.of(Arguments.of("Sinhala", "සිංහල ජාතිය"), Arguments.of("Japanese", "日本語"), Arguments.of("Russian", "Русский"), Arguments.of("Farsi", "فارسی"), Arguments.of("Korean", "한국어"), Arguments.of("Armenian", "Հայերեն"), Arguments.of("Hindi", "हिन्दी"), Arguments.of("Hebrew", "עברית"), Arguments.of("Chinese", "中文"), Arguments.of("Amharic", "አማርኛ"), Arguments.of("Malayalam", "മലയാളം"), Arguments.of("Assyrian Neo-Aramaic", "ܐܬܘܪܝܐ"), Arguments.of("Georgian", "მარგალური"), Arguments.of("Emojis", "🐶🐱🐭🐹🐰🦊🐻🐼🐻‍❄🐨🐯🦁🐮🐷🐽🐸🐵🙈🙉🙊🐒🐔🐧🐦🐤🐣🐥🦆🦅🦉🦇🐺🐗🐴🦄🐝🐛")); }; @ParameterizedTest @MethodSource("languages") public void supportI18nString(String language, String nonLatinText) throws Exception { String json = "{\"key\":\"" + nonLatinText + "\"}"; JSONObject obj = (JSONObject) JSONValue.parse(json); String actual = (String) obj.get("key"); assertEquals(nonLatinText, actual, "Parsing String " + language + " text"); } @ParameterizedTest @MethodSource("languages") public void supportI18nStringReader(String language, String nonLatinText) throws Exception { String json = "{\"key\":\"" + nonLatinText + "\"}"; StringReader reader = new StringReader(json); JSONObject obj = (JSONObject) JSONValue.parse(reader); String actual = (String) obj.get("key"); assertEquals(nonLatinText, actual, "Parsing StringReader " + language + " text"); } @ParameterizedTest @MethodSource("languages") public void supportI18nByteArrayInputStream(String language, String nonLatinText) throws Exception { String json = "{\"key\":\"" + nonLatinText + "\"}"; ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf8")); JSONObject obj = (JSONObject) JSONValue.parse(bis); String actual = (String) obj.get("key"); assertEquals(nonLatinText, actual, "Parsing ByteArrayInputStream " + language + " text"); } @ParameterizedTest @MethodSource("languages") public void supportI18nBytes(String language, String nonLatinText) throws Exception { String json = "{\"key\":\"" + nonLatinText + "\"}"; byte[] bs = json.getBytes("utf8"); JSONObject obj = JSONValue.parse(bs, JSONObject.class); String actual = (String) obj.get("key"); assertEquals(nonLatinText, actual, "Parsing bytes[] " + language + " text"); } }netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/strict/000077500000000000000000000000001475302255200304745ustar00rootroot00000000000000TestExcessiveComma.java000066400000000000000000000031631475302255200350360ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/strictpackage net.minidev.json.test.strict; import net.minidev.json.JSONValue; import net.minidev.json.parser.ParseException; import net.minidev.json.test.MustThrows; import org.junit.jupiter.api.Test; public class TestExcessiveComma { @Test public void testExcessiveComma1A() throws Exception { String s = "[1,2,,3]"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); JSONValue.parseWithException(s); } @Test public void testExcessiveComma2A() throws Exception { String s = "[1,2,]"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); JSONValue.parseWithException(s); } @Test public void testExcessiveComma3A() throws Exception { String s = "[,]"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); JSONValue.parseWithException(s); } @Test public void testExcessiveComma4A() throws Exception { String s = "[,5]"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); JSONValue.parseWithException(s); } @Test public void testExcessiveComma1O() throws Exception { String s = "{\"a\":1,,\"b\":1}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); JSONValue.parseWithException(s); } @Test public void testExcessiveComma2O() throws Exception { String s = "{\"a\":1,}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); JSONValue.parseWithException(s); } @Test public void testExcessiveComma3O() throws Exception { String s = "{,}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_CHAR); JSONValue.parseWithException(s); } } TestSpecialChar.java000066400000000000000000000016761475302255200343100ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/strictpackage net.minidev.json.test.strict; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import net.minidev.json.JSONArray; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import net.minidev.json.test.MustThrows; /** * Test control charaters * * @author uriel * */ public class TestSpecialChar { @Test public void testSpecial127() throws Exception { String s127 = String.format("%c", 127); String s = String.format("[\"%c\"]", 127); MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_CHAR); JSONArray o = (JSONArray) new JSONParser(JSONParser.MODE_RFC4627).parse(s); assertEquals(o.get(0), s127); } @Test public void testSpecial31() throws Exception { String s = String.format("[\"%c\"]", 31); MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_CHAR); } } TestTaillingJunk.java000066400000000000000000000031241475302255200345130ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/strictpackage net.minidev.json.test.strict; import net.minidev.json.JSONObject; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import net.minidev.json.test.MustThrows; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; /** * @since 1.0.7 */ public class TestTaillingJunk { @Test public void testTaillingSpace() throws Exception { String s = "{\"t\":0} "; MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_TOKEN); s = "{\"t\":0} "; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE).parse(s); assertEquals(o.get("t"), 0); } @Test public void testTaillingSpace2() throws Exception { String s = "{\"t\":0} \r\n "; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE).parse(s); assertEquals(o.get("t"), 0); } @Test public void testTaillingData() throws Exception { String s = "{\"t\":0} 0"; MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST, ParseException.ERROR_UNEXPECTED_TOKEN, null); } @Test public void testTaillingDataPermisive() throws Exception { String s = "{\"t\":0} 0"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), 0); } @Test public void testTaillingDataWithSpaceAllowed() throws Exception { String s = "{\"t\":0}{"; MustThrows.testInvalidJson(s, JSONParser.MODE_STRICTEST | JSONParser.ACCEPT_TAILLING_SPACE, ParseException.ERROR_UNEXPECTED_TOKEN); } } TestZeroLead.java000066400000000000000000000033341475302255200336300ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/strictpackage net.minidev.json.test.strict; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import net.minidev.json.test.MustThrows; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; /** * @since 1.0.7 */ public class TestZeroLead { @Test public void test0O() throws Exception { String s = "{\"t\":0}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_RFC4627).parse(s); assertEquals(o.get("t"), 0); JSONValue.parseWithException(s); } @Test public void test0A() throws Exception { String s = "[0]"; JSONArray o = (JSONArray) new JSONParser(JSONParser.MODE_RFC4627).parse(s); assertEquals(o.get(0), 0); JSONValue.parseWithException(s); } @Test public void test0Float() throws Exception { String s = "[00.0]"; // strict MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_LEADING_0); // PERMISIVE JSONValue.parseWithException(s); } @Test public void test01Float() throws Exception { String s = "[01.0]"; // strict MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_LEADING_0); // PERMISIVE JSONValue.parseWithException(s); } @Test public void test00001() throws Exception { String s = "{\"t\":00001}"; JSONObject o = (JSONObject) new JSONParser(JSONParser.MODE_PERMISSIVE).parse(s); assertEquals(o.get("t"), 1); JSONValue.parseWithException(s); } @Test public void test00001Strict() throws Exception { String s = "{\"t\":00001}"; MustThrows.testStrictInvalidJson(s, ParseException.ERROR_UNEXPECTED_LEADING_0); JSONValue.parseWithException(s); } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/writer/000077500000000000000000000000001475302255200305005ustar00rootroot00000000000000TestWriteFeatures.java000066400000000000000000000014311475302255200347140ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/test/writerpackage net.minidev.json.test.writer; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; public class TestWriteFeatures { @Test public void testS1() throws Exception { Beans beans = new Beans(); String s = JSONValue.toJSONString(beans, JSONStyle.MAX_COMPRESS); assertEquals("{}", s); s = JSONValue.toJSONString(beans, JSONStyle.NO_COMPRESS); if (s.startsWith("{\"b")) { assertEquals("{\"b\":null,\"a\":null}", s); } else { assertEquals("{\"a\":null,\"b\":null}", s); } beans.a = "a"; s = JSONValue.toJSONString(beans, JSONStyle.MAX_COMPRESS); assertEquals("{a:a}", s); } public static class Beans { public String a; public String b; } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMapping/000077500000000000000000000000001475302255200305005ustar00rootroot00000000000000TestAdvancedMapper.java000066400000000000000000000017161475302255200350030ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import static org.junit.jupiter.api.Assertions.assertEquals; import java.text.SimpleDateFormat; import java.util.Date; import org.junit.jupiter.api.Test; import net.minidev.asm.BeansAccessConfig; import net.minidev.json.JSONValue; public class TestAdvancedMapper { public static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); @Test public void testCustomBean() throws Exception { BeansAccessConfig.addTypeMapper(Object.class, MyLocalConverterot.class); String s = "{'val':2,'date':'19/04/2010'}"; TestBean r = JSONValue.parseWithException(s, TestBean.class); assertEquals("19/04/2010", sdf.format(r.date)); } public static class TestBean { public int val; public Date date; } public static class MyLocalConverterot { public static Date fromString(Object text) throws Exception { if (text == null) return null; synchronized (sdf) { return sdf.parse(text.toString()); } } } } TestCustomMappingInstant.java000066400000000000000000000040251475302255200362540ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; import java.time.Instant; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; import net.minidev.json.parser.ParseException; import net.minidev.json.writer.JsonReaderI; import org.junit.jupiter.api.Test; /** * Test JDK 8+ java.time.Instant * * Serialize a custom class Sample 1 * * @author uriel * */ public class TestCustomMappingInstant { @Test public void test_dummy() throws IOException { @SuppressWarnings("unused") ParseException e = null; JSONValue.toJSONString(true, JSONStyle.MAX_COMPRESS); } public void test_instant() { JSONValue.registerWriter(java.time.Instant.class, new net.minidev.json.reader.JsonWriterI() { @Override public void writeJSONString(java.time.Instant value, Appendable out, JSONStyle compression) throws IOException { if (value == null) out.append("null"); else out.append(Long.toString(value.toEpochMilli())); } }); JSONValue.registerReader(RegularClass.class, new JsonReaderI(JSONValue.defaultReader) { @Override public void setValue(Object current, String key, Object value) throws ParseException, IOException { if (key.equals("instant")) { Instant inst = Instant.ofEpochMilli((((Number)value).longValue())); ((RegularClass)current).setInstant(inst); } } @Override public Object createObject() { return new RegularClass(); } }); Instant instant = Instant.now(); RegularClass regularClass = new RegularClass(); regularClass.setInstant(instant); String data = JSONValue.toJSONString(regularClass); RegularClass result = JSONValue.parse(data, RegularClass.class); assertEquals(result.getInstant(), instant); } public static class RegularClass { private java.time.Instant instant; public java.time.Instant getInstant() { return instant; } public void setInstant(java.time.Instant instant) { this.instant = instant; } } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMapping/TestDate.java000066400000000000000000000011151475302255200330560ustar00rootroot00000000000000package net.minidev.json.testMapping; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class TestDate { @Test public void testBooleans() throws Exception { String s = "[true,true,false]"; boolean[] bs = new boolean[] { true, true, false }; String s2 = JSONValue.toJSONString(bs); assertEquals(s, s2); } @Test public void testInts() throws Exception { String s = "[1,2,3]"; int[] bs = new int[] { 1, 2, 3 }; String s2 = JSONValue.toJSONString(bs); assertEquals(s, s2); } } TestFieldRename.java000066400000000000000000000013701475302255200343000ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; public class TestFieldRename { public static class TRen { public String new_; public String default_; } @Test public void testRemap() throws Exception { String text = "{'new':'foo','default':'bar'}"; JSONValue.remapField(TRen.class, "default", "default_"); JSONValue.remapField(TRen.class, "new", "new_"); TRen t = JSONValue.parse(text, TRen.class); assertEquals(t.new_, "foo"); assertEquals(t.default_, "bar"); String dest = JSONValue.toJSONString(t); assertTrue(dest.contains("\"default\"")); } } TestMapBeans.java000066400000000000000000000041621475302255200336150ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import java.util.Map; import net.minidev.json.JSONValue; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class TestMapBeans { @Test public void testObjInts() throws Exception { String s = "{\"vint\":[1,2,3]}"; T1 r = JSONValue.parse(s, T1.class); assertEquals(3, r.vint[2]); } @Test public void testObjIntKey() throws Exception { String s = "{\"data\":{\"1\":\"toto\"}}"; T2 r = JSONValue.parse(s, T2.class); assertEquals("toto", r.data.get(1)); } @Test public void testObjEnumKey() throws Exception { String s = "{\"data\":{\"red\":10}}"; T3 r = JSONValue.parse(s, T3.class); assertEquals((Integer)10, r.data.get(ColorEnum.red)); } @Test public void testObjBool1() throws Exception { String s = "{\"data\":true}"; T4 r = JSONValue.parse(s, T4.class); assertEquals(true, r.data); } @Test public void testObjBool2() throws Exception { String s = "{\"data\":true}"; T5 r = JSONValue.parse(s, T5.class); assertEquals(true, r.data); } /** * class containing primitive array; */ public static class T1 { private int[] vint; public int[] getVint() { return vint; } public void setVint(int[] vint) { this.vint = vint; } } /** * class containing Map interface; */ public static class T2 { private Map data; public Map getData() { return data; } public void setData(Map data) { this.data = data; } } public static enum ColorEnum { bleu, green, red, yellow } public static class T3 { private Map data; public Map getData() { return data; } public void setData(Map data) { this.data = data; } } public static class T4 { private boolean data; public boolean getData() { return data; } public void setData(boolean data) { this.data = data; } } public static class T5 { private boolean data; public boolean isData() { return data; } public void setData(boolean data) { this.data = data; } } } TestMapPrimArrays.java000066400000000000000000000023201475302255200346500ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import net.minidev.json.JSONValue; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class TestMapPrimArrays { @Test public void testInts() throws Exception { String s = "[1,2,3]"; int[] r = JSONValue.parse(s, int[].class); assertEquals(3, r[2]); } @Test public void testIntss() throws Exception { String s = "[[1],[2],[3,4]]"; int[][] r = JSONValue.parse(s, int[][].class); assertEquals(3, r[2][0]); assertEquals(4, r[2][1]); } @Test public void testLongs() throws Exception { String s = "[1,2,3]"; long[] r = JSONValue.parse(s, long[].class); assertEquals(3, r[2]); } @Test public void testFloat() throws Exception { String s = "[1.2,22.4,3.14]"; float[] r = JSONValue.parse(s, float[].class); assertEquals(3.14F, r[2]); } @Test public void testDouble() throws Exception { String s = "[1.2,22.4,3.14]"; double[] r = JSONValue.parse(s, double[].class); assertEquals(3.14, r[2]); } @Test public void testBooleans() throws Exception { String s = "[true,true,false]"; boolean[] r = JSONValue.parse(s, boolean[].class); assertEquals(true, r[1]); assertEquals(false, r[2]); } } TestMapPublic.java000066400000000000000000000036771475302255200340150ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Map; import java.util.TreeMap; import net.minidev.json.JSONValue; import org.junit.jupiter.api.Test; public class TestMapPublic { @Test public void testObjInts() throws Exception { String s = "{\"vint\":[1,2,3]}"; T1 r = JSONValue.parse(s, T1.class); assertEquals(3, r.vint[2]); } String MultiTyepJson = "{\"name\":\"B\",\"age\":120,\"cost\":12000,\"flag\":3,\"valid\":true,\"f\":1.2,\"d\":1.5,\"l\":12345678912345}"; @Test public void testObjMixte() throws Exception { T2 r = JSONValue.parse(MultiTyepJson, T2.class); assertEquals("B", r.name); assertEquals(120, r.age); assertEquals(12000, r.cost); assertEquals(3, r.flag); assertEquals(true, r.valid); assertEquals(1.2F, r.f); assertEquals(1.5, r.d); assertEquals(12345678912345L, r.l); } @Test public void testObjMixtePrim() throws Exception { T3 r = JSONValue.parse(MultiTyepJson, T3.class); assertEquals("B", r.name); assertEquals(Short.valueOf((short) 120), r.age); assertEquals(Integer.valueOf(12000), r.cost); assertEquals(Byte.valueOf((byte) 3), r.flag); assertEquals(Boolean.TRUE, r.valid); assertEquals(1.2F, r.f); assertEquals(1.5, r.d); assertEquals(Long.valueOf(12345678912345L), r.l); } public static class T1 { public int[] vint; } public static class T2 { public String name; public short age; public int cost; public byte flag; public boolean valid; public float f; public double d; public long l; } public static class T3 { public String name; public Short age; public Integer cost; public Byte flag; public Boolean valid; public Float f; public Double d; public Long l; } public static class T123 { public T1 t1; public T2 t2; public T3 t3; } public static class T5 { public Map data; } public static class T6 { public TreeMap data; } } TestMapPublic2.java000066400000000000000000000015251475302255200340650ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Map; import java.util.TreeMap; import net.minidev.json.JSONValue; import org.junit.jupiter.api.Test; public class TestMapPublic2 { String s = "{\"data\":{\"a\":\"b\"}}"; @Test public void testMapPublicInterface() throws Exception { T5 r = JSONValue.parse(s, T5.class); assertEquals(1, r.data.size()); } @Test public void testMapPublicMapClass() throws Exception { T6 r = JSONValue.parse(s, T6.class); assertEquals(1, r.data.size()); } String MultiTyepJson = "{\"name\":\"B\",\"age\":120,\"cost\":12000,\"flag\":3,\"valid\":true,\"f\":1.2,\"d\":1.5,\"l\":12345678912345}"; public static class T5 { public Map data; } public static class T6 { public TreeMap data; } } TestSerPrimArrays.java000066400000000000000000000016551475302255200346760ustar00rootroot00000000000000netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMappingpackage net.minidev.json.testMapping; import static org.junit.jupiter.api.Assertions.assertEquals; import java.text.SimpleDateFormat; import java.util.Date; import net.minidev.json.JSONValue; import org.junit.jupiter.api.Test; public class TestSerPrimArrays { SimpleDateFormat sdf; String testDateString; Date testDate; public TestSerPrimArrays() { try { sdf = new SimpleDateFormat("dd/MM/yyyy"); testDateString = "12/01/2010"; testDate = sdf.parse(testDateString); } catch (Exception e) { } } @Test public void testDate() throws Exception { String s = "'" + testDateString + "'"; Date dt = JSONValue.parse(s, Date.class); assertEquals(dt, this.testDate); } @Test public void testDtObj() throws Exception { String s = "{date:'" + testDateString + "'}"; ADate dt = JSONValue.parse(s, ADate.class); assertEquals(dt.date, this.testDate); } public static class ADate { public Date date; } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMapping/TestUUID.java000066400000000000000000000032051475302255200327510ustar00rootroot00000000000000package net.minidev.json.testMapping; import net.minidev.json.JSONObject; import net.minidev.json.JSONStyle; import net.minidev.json.JSONValue; import net.minidev.json.parser.ParseException; import net.minidev.json.reader.JsonWriterI; import net.minidev.json.writer.JsonReaderI; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; import java.util.UUID; import org.junit.jupiter.api.Test; public class TestUUID { @Test void testUUID() throws ParseException { JSONObject obj = new JSONObject(); UUID uuid = new UUID(123, 456); JSONValue.registerWriter(UUID.class, new JsonWriterI() { @Override public void writeJSONString(UUID value, Appendable out, JSONStyle compression) throws IOException { out.append(value.toString()); } }); JSONValue.registerReader(UUIDHolder.class, new JsonReaderI(JSONValue.defaultReader) { @Override public void setValue(Object current, String key, Object value) throws ParseException, IOException { if ("v".equals(key)) { ((UUIDHolder)current).setV(UUID.fromString((String)value)); return; } super.setValue(current, key, value); } @Override public Object createObject() { return new UUIDHolder(); } }); obj.put("v", uuid); String asText = obj.toJSONString(); assertEquals("{\"v\":00000000-0000-007b-0000-0000000001c8}", asText); UUIDHolder rebuild = JSONValue.parseWithException(asText, UUIDHolder.class); assertEquals(uuid, rebuild.getV()); } public static class UUIDHolder { private UUID v; public UUID getV() { return v; } public void setV(UUID uuid) { this.v = uuid; } } } netplex-json-smart-v2-20dff24/json-smart/src/test/java/net/minidev/json/testMapping/TestUpdater.java000066400000000000000000000030771475302255200336160ustar00rootroot00000000000000package net.minidev.json.testMapping; import net.minidev.json.JSONValue; import net.minidev.json.testMapping.TestMapPublic.T123; import net.minidev.json.testMapping.TestMapPublic.T1; import net.minidev.json.testMapping.TestMapPublic.T2; import net.minidev.json.testMapping.TestMapPublic.T3; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class TestUpdater { @Test public void testUpdate1() throws Exception { T3 t3 = new T3(); t3.age = 20; t3.f = 1.4f; t3.l = 120000L; String s = "{\"name\":\"text\"}"; T3 t3_1 = JSONValue.parse(s, t3); assertEquals(t3, t3_1); assertEquals("text", t3.name); assertEquals((Long) 120000L, t3.l); } @Test public void testUpdateExistingBeans() throws Exception { T123 t123 = new T123(); T1 t1 = new T1(); T2 t2 = new T2(); T3 t3 = new T3(); t123.t1 = t1; t123.t2 = t2; t123.t3 = t3; String s = "{\"t2\":{\"name\":\"valueT2\"},\"t3\":{\"name\":\"valueT3\"},}"; T123 res = JSONValue.parse(s, t123); assertEquals(res, t123); assertEquals(res.t2, t2); assertEquals(res.t2.name, "valueT2"); assertEquals(res.t3.name, "valueT3"); } @Test public void testUpdateNullBean() throws Exception { T123 t123 = new T123(); T1 t1 = new T1(); T2 t2 = null; T3 t3 = null; t123.t1 = t1; t123.t2 = t2; t123.t3 = t3; String s = "{\"t2\":{\"name\":\"valueT2\"},\"t3\":{\"name\":\"valueT3\"},}"; T123 res = JSONValue.parse(s, t123); assertEquals(res, t123); assertEquals(res.t2.name, "valueT2"); assertEquals(res.t3.name, "valueT3"); } }