diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000000..282080ed6b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,34 @@ +--- +name: Java CI + +on: [push, pull_request] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-18.04, macOS-latest] + java: [8] + fail-fast: false + max-parallel: 4 + name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - uses: actions/cache@v2 + env: + cache-name: cache-maven-modules + with: + path: ~/.m2/repository + key: ${{ runner.os }}-build-${{ env.cache-name }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }} + - name: Test with Maven + run: mvn test -B --file pom.xml diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index b3fd69dc9d..20987c97d1 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ /.idea /.DS_Store *.iml - +/src/test/java/com/alibaba/json/bvt/parser/autoType/ /bin/ diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000000..177ab796fc --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,7 @@ +tasks: + - init: mvn install -DskipTests=true + +vscode: + extensions: + - vscjava.vscode-maven@0.21.0:37ZOg7jK2M04yXsE+ItbZg== + - GabrielBB.vscode-lombok@1.0.0:fYRHVd+UkrccCfjaRz7jKw== \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index ef2c288661..a48a573440 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - oraclejdk8 + - openjdk8 before_install: - pip install --user codecov after_success: @@ -8,3 +8,7 @@ after_success: branches: except: - appveyor + +cache: + directories: + - $HOME/.m2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..48682c20a5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,27 @@ + +## Contributing + +If you want to contribute to a project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new technologies and their ecosystems, and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. + +### How to make a clean pull request + +Look for a project's contribution instructions. If there are any, follow them. + +- Create a personal fork of the project on Github. +- Clone the fork on your local machine. Your remote repo on Github is called `origin`. +- Add the original repository as a remote called `upstream`. +- If you created your fork a while ago be sure to pull upstream changes into your local repository. +- Create a new branch to work on! Branch from `develop` if it exists, else from `master`. +- Implement/fix your feature, comment your code. +- Follow the code style of the project, including indentation. +- If the project has tests run them! +- Write or adapt tests as needed. +- Add or change the documentation as needed. +- Create a new branch if necessary. +- Push your branch to your fork on Github, the remote `origin`. +- From your fork open a pull request in the correct branch. Target the project's `develop` branch if there is one, else go for `master`! +- Wait for approval. +- Once the pull request is approved and merged you can pull the changes from `upstream` to your local repo and delete +your extra branch(es). + +And last but not least: Always write your commit messages in the present tense. Your commit message should describe what the commit, when applied, does to the code – not what you did to the code. diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 14703f2e5f..977f6a8fd9 --- a/README.md +++ b/README.md @@ -1,15 +1,20 @@ + # fastjson -[![Build Status](https://travis-ci.org/alibaba/fastjson.svg?branch=master)](https://travis-ci.org/alibaba/fastjson) +[![Java CI](https://github.com/alibaba/fastjson/actions/workflows/ci.yaml/badge.svg?branch=master)](https://github.com/alibaba/fastjson/actions/workflows/ci.yaml) [![Codecov](https://codecov.io/gh/alibaba/fastjson/branch/master/graph/badge.svg)](https://codecov.io/gh/alibaba/fastjson/branch/master) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.alibaba/fastjson/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.alibaba/fastjson/) [![GitHub release](https://img.shields.io/github/release/alibaba/fastjson.svg)](https://github.com/alibaba/fastjson/releases) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/alibaba/fastjson) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/fastjson2.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:fastjson2) +======= +[![QualityGate](https://quality-gate.com/backend/api/timeline?branchName=master&projectName=alibaba_fastjson)](https://quality-gate.com/dashboard/branches/7816#overview) Fastjson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Fastjson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of. ### Fastjson Goals - * Provide best performance in server side and android client + * Provide the best performance on the server-side and android client * Provide simple toJSONString() and parseObject() methods to convert Java objects to JSON and vice-versa * Allow pre-existing unmodifiable objects to be converted to and from JSON * Extensive support of Java Generics @@ -21,6 +26,7 @@ Fastjson is a Java library that can be used to convert Java Objects into their J ## Documentation - [Documentation Home](https://github.com/alibaba/fastjson/wiki) +- [Contributing Code](https://github.com/nschaffner/fastjson/blob/master/CONTRIBUTING.md) - [Frequently Asked Questions](https://github.com/alibaba/fastjson/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) ## Benchmark @@ -30,9 +36,9 @@ https://github.com/eishay/jvm-serializers/wiki ## Download - [maven][1] -- [the latest JAR][2] +- [the latest JAR][2] -[1]: http://repo1.maven.org/maven2/com/alibaba/fastjson/ +[1]: https://repo1.maven.org/maven2/com/alibaba/fastjson/ [2]: https://search.maven.org/remote_content?g=com.alibaba&a=fastjson&v=LATEST ## Maven @@ -41,7 +47,7 @@ https://github.com/eishay/jvm-serializers/wiki com.alibaba fastjson - 1.2.40 + 1.2.76 ``` @@ -49,21 +55,21 @@ https://github.com/eishay/jvm-serializers/wiki com.alibaba fastjson - 1.1.65.android + 1.1.72.android ``` ## Gradle via JCenter ``` groovy -compile 'com.alibaba:fastjson:1.2.40' +compile 'com.alibaba:fastjson:1.2.76' ``` ``` groovy -compile 'com.alibaba:fastjson:1.1.65.android' +compile 'com.alibaba:fastjson:1.1.72.android' ``` -Please see this [Wiki Download Page][Wiki] for more repository infos. +Please see this [Wiki Download Page][Wiki] for more repository info. [Wiki]: https://github.com/alibaba/fastjson/wiki#download @@ -72,11 +78,11 @@ Please see this [Wiki Download Page][Wiki] for more repository infos. Fastjson is released under the [Apache 2.0 license](license.txt). ``` -Copyright 1999-2017 Alibaba Group Holding Ltd. +Copyright 1999-2020 Alibaba Group Holding Ltd. 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 following link. +You may obtain a copy of the License at the following link. http://www.apache.org/licenses/LICENSE-2.0 diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..d6ddf96d06 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,120 @@ +# 漏洞奖励计划 +## 报告 +如果您认为自己在本程序中发现了任何安全(技术)漏洞,欢迎您通过 https://security.alibaba.com 向我们提交漏洞报告。 +如果您报告任何安全漏洞,请注意您可能包含以下信息(合格报告): +* git程序URL地址,运行的环境 +* 包含必要屏幕截图的详细说明 +* 重现漏洞的步骤以及修复漏洞的建议。 +* 其他有用信息 + +## 处理 +ASRC(Alibaba Security Response Center阿里安全响应中心)将尽快审核并回复您的提交内容,并在我们努力修复您提交的漏洞时随时通知您。如有必要,我们可能会与您联系以获取更多信息。 + + +## 条款和条件 +1. 仅接受技术漏洞并对其进行评级 +2. 出于安全原因,上报者同意与ASRC合作完成他/她提交的漏洞,不向任何第三方透露任何漏洞信息 +3. 如果不止一个人报告相同的安全漏洞,奖励将给予完成合格报告的第一个人 +4. 为了保护程序的用户,请在修复之前不要直接提交git的issue,也不要在社区讨论任何漏洞信息 +5. 所有奖励和声誉积分将提供给仅向ASRC提交其安全漏洞的上报者 +6. 安全漏洞奖励的解释权利归ASRC所有 + +## 收集范围 +我们的主要收集漏洞类别是: +* 服务器端请求伪造(SSRF) +* SQL注入 +* 拒绝服务攻击 +* 远程执行代码(RCE) +* XML外部实体攻击(XXE) +* 访问控制问题(不安全的直接对象参考问题等) +* 敏感目录遍历问题 +* 本地文件读取(LFD) +* 敏感信息泄露(密钥,Cookie,Session等) + +## 奖励 +* 可直接导致严重问题的每个漏洞奖励7000元人民币 +* 存在限制及需要一定特殊环境下才能利用的问题将给予700-5600元人民币不等的奖励,比如需要用户主动点击才会触发的问题或需要admin权限 +* 只有在指定环境下才可以运行的利用将有可能被收纳但不给予奖励,或直接被忽略,比如只在fastjson+linux特定版本才会出现的问题 + +## 不在收集范围的报告 +* 影响过时浏览器或平台用户的漏洞 +* Self-XSS +* 会话固定 +* 内容欺骗 +* 缺少cookie标记 +* 混合内容警告 +* SSL / TLS问题 +* Clickjacking +* 基于Flash的漏洞 +* 反射文件下载攻击(RFD) +* 物理或社会工程攻击 +* 未验证自动化工具或扫描仪的结果 +* 登录/注销/未认证/低影响CSRF +* 需要MITM或物理访问用户设备的攻击 +* 与网络协议或行业标准相关的问题 +* 不能用于直接攻击的错误信息泄露 +* 缺少与安全相关的HTTP标头等 + + + + + +# Vulnerability Reward Program +## Reporting +If you believe you have found any security (technical) vulnerability in the Program, you are welcomed to submit a vulnerability report to us at https://security.alibaba.com +In case of reporting any security vulnerability, please be noted that you may including following information (Qualified Reporting): +* The git program URL and running version +* A detailed description with necessary screenshots +* Steps to reappearance the vulnerability and your advice to fix it +* Other useful information + + +## Processing +ASRC (Alibaba Security Response Center) will review and respond as quickly as possible to your submission, and keep you informed as we work to fix the vulnerability you submitted. We may contact you for further information if necessary. + + +## Terms and Conditions +1. ONLY technical vulnerabilities will be accepted and rated. +2. With regarding to security reasons, reporters agree to cooperate with ASRC exclusively on the vulnerability he/she submitted and not disclose any information of vulnerability to any third-parties. +3. In the case that more than one person report the same security vulnerability, the reward will be given to the first person who accomplish a Qualified Reporting. +4. To protect users of the program, please do not directly submit issue on github or discuss anything with the community +5. All Rewards and Reputation Credits are given to the reporters who submit his/her security vulnerabilities ONLY to ASRC. +6. All rights for the security vulnerability rewards are reserved by ASRC. + +## Scope of Collecting +The main categories of vulnerabilities that we are sincerely looking for are: +* Server-Side Request Forgery (SSRF) +* SQL Injection +* Denial of Service Attack +* Remote Code Execution (RCE) +* XML External Entity Attacks (XXE) +* Access Control Issues (Insecure Direct Object Reference issues, etc.) +* Directory Traversal Issues +* Local File Disclosure (LFD) +* Sensitive Information Leakage (Key, Cookie, Session etc.) + +## Reward +* $1,000 for one valid report +* $100-$800 for Vuls which is limited. For example, Vuls that need user interactions or administrator authority +* Vuls which only work on the special version will be accepted but no reward, or directly rejected. For example, Vul runs only on a special linux version + +## Ineligible Reports +* Vulnerabilities affecting users of outdated browsers or platforms +* "Self" XSS +* Session fixation +* Content Spoofing +* Missing cookie flags +* Mixed content warnings +* SSL/TLS best practices +* Clickjacking/UI redressing +* Flash-based vulnerabilities +* Reflected file download attacks (RFD) +* Physical or social engineering attacks +* Unverified Results of automated tools or scanners +* Login/logout/unauthenticated/low-impact CSRF +* Attacks requiring MITM or physical access to a user's device +* Issues related to networking protocols or industry standards +* Error information disclosure that cannot be used to make a direct attack +* Missing security-related HTTP headers which do not lead directly to a vulnerability + + diff --git a/license.txt b/license.txt index 8deeff6746..fb0553f943 100644 --- a/license.txt +++ b/license.txt @@ -1,13 +1,201 @@ -Copyright 1999-2016 Alibaba Group Holding Ltd. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -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 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - http://www.apache.org/licenses/LICENSE-2.0 + 1. Definitions. -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. + "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 1999-2019 Alibaba Group Holding Ltd. + + 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. diff --git a/pom.xml b/pom.xml old mode 100755 new mode 100644 index cc2f819ca0..18d8f3c8e9 --- a/pom.xml +++ b/pom.xml @@ -1,509 +1,316 @@ - 4.0.0 - com.alibaba - fastjson - 1.2.41-SNAPSHOT - - jar - fastjson - Fastjson is a JSON processor (JSON parser + JSON generator) written in Java - - https://github.com/alibaba/fastjson - 2012 - - - 4.12 - true - false - UTF-8 - 1.5 - - - - https://github.com/alibaba/fastjson - scm:git:https://git@github.com/alibaba/fastjson.git - - - - - local-file - file://${basedir}/lib/ - default - - - - - Alibaba Group - https://github.com/alibaba - - - - - wenshao - wenshao - szujobs@hotmail.com - - - axmanwang - axmanwang - iamaxman@hotmail.com - - - kimmking - kimmking - kimmking@163.com - - - Victor Zeng - Victor Zeng - Victor.Zxy@outlook.com - - - Neil Dong - Neil Dong - email_dsl@163.com - - - 李恒名 - https://github.com/lihengming/ - 89921218@qq.com - - - - - - Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - A business-friendly OSS license - - - - - - - org.apache.maven.wagon - wagon-webdav - 1.0-beta-2 - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 3.5.1 - - UTF-8 - ${jdk.version} - ${jdk.version} - - - - org.codehaus.plexus - plexus-compiler-javac - 2.7 - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar-no-fork - - - - - true - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/bvt/**/*.java - - - - - - maven-javadoc-plugin - - - attach-javadoc - - jar - - - - - ${javadoc.skip} - public - UTF-8 - UTF-8 - UTF-8 - - http://docs.oracle.com/javase/6/docs/api - - - - - - maven-gpg-plugin - - ${gpg.skip} - - - - sign-artifacts - verify - - sign - - - - - - - - - - javax.servlet - javax.servlet-api - 3.1.0 - provided - true - - - javax.ws.rs - javax.ws.rs-api - 2.0.1 - provided - true - - - - org.apache.cxf - cxf-rt-transports-http - 3.1.2 - provided - true - - - org.apache.cxf - cxf-rt-frontend-jaxrs - 3.1.2 - provided - true - - - - org.springframework - spring-websocket - 4.3.7.RELEASE - provided - true - - - org.springframework - spring-webmvc - 4.3.7.RELEASE - provided - true - - - - org.springframework.data - spring-data-redis - 1.8.6.RELEASE - provided - true - - - - com.squareup.retrofit2 - retrofit - 2.1.0 - provided - - - com.squareup.okhttp3 - okhttp - 3.6.0 - provided - - - - io.springfox - springfox-spring-web - 2.6.1 - provided - true - - - - io.javaslang - javaslang - 2.0.6 - provided - - - - org.glassfish.jersey.core - jersey-common - 2.23.2 - provided - - - - org.eclipse.jetty - jetty-server - 8.1.8.v20121106 - test - true - - - org.eclipse.jetty - jetty-webapp - 8.1.8.v20121106 - test - true - - - - junit - junit - ${junit.version} - test - - - - com.fasterxml.jackson.core - jackson-databind - 2.9.0 - test - - - com.fasterxml.jackson.module - jackson-module-afterburner - 2.9.0 - test - - - com.fasterxml.jackson.module - jackson-module-kotlin - 2.9.0 - test - - - - cglib - cglib-nodep - 2.2.2 - test - - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - 2.8.7 - test - - - com.googlecode.json-simple - json-simple - 1.1.1 - test - - - - commons-io - commons-io - 1.4 - test - - - - net.sf.json-lib - json-lib - 2.4 - jdk15 - test - - - - com.google.code.gson - gson - 2.6.2 - test - - - net.minidev - json-smart - 2.2.1 - test - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.alibaba + fastjson + 1.2.83 + + jar + fastjson + Fastjson is a JSON processor (JSON parser + JSON generator) written in Java + + https://github.com/alibaba/fastjson + 2012 + + + false + false + UTF-8 + 1.5 + + + + https://github.com/alibaba/fastjson + scm:git:https://git@github.com/alibaba/fastjson.git + + + + Alibaba Group + https://github.com/alibaba + + + + + wenshao + wenshao + szujobs@hotmail.com + + + axmanwang + axmanwang + iamaxman@hotmail.com + + + kimmking + kimmking + kimmking@163.com + + + Victor Zeng + Victor Zeng + Victor.Zxy@outlook.com + + + Neil Dong + Neil Dong + email_dsl@163.com + + + 李恒名 + https://github.com/lihengming/ + 89921218@qq.com + + + Omega-Ariston + Jiechuan Chen + 654815312@qq.com + + + + + + Apache 2 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + UTF-8 + ${jdk.version} + ${jdk.version} + + + + org.codehaus.plexus + plexus-compiler-javac + 2.7 + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/bvt/**/*.java + + + + + + maven-javadoc-plugin + + + attach-javadoc + + jar + + + + + ${javadoc.skip} + public + UTF-8 + UTF-8 + UTF-8 + + http://docs.oracle.com/javase/6/docs/api + + + + + + maven-gpg-plugin + + ${gpg.skip} + + + + sign-artifacts + verify + + sign + + + + + + + + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + true + + + javax.ws.rs + javax.ws.rs-api + 2.0.1 + provided + true + - - org.clojure - clojure - 1.5.1 - test - - - org.codehaus.groovy - groovy - 2.1.5 - test - + + org.apache.cxf + cxf-rt-transports-http + 3.1.2 + provided + true + + + org.apache.cxf + cxf-rt-frontend-jaxrs + 3.1.2 + provided + true + - - org.springframework - spring-test - 4.3.7.RELEASE - test - - - org.javassist - javassist - 3.18.0-GA - test - + + org.springframework + spring-websocket + 4.3.7.RELEASE + provided + true + + + org.springframework + spring-webmvc + 4.3.7.RELEASE + provided + true + - - org.apache.cxf - cxf-rt-rs-client - 3.1.2 - test - - - - org.springframework.data - spring-data-commons-core - 1.4.1.RELEASE - test - + + org.springframework + spring-messaging + 4.3.7.RELEASE + provided + true + - - org.glassfish.jersey.containers - jersey-container-servlet - 2.23.2 - test - - - org.glassfish.jersey.core - jersey-client - 2.23.2 - test - - - org.glassfish.jersey.test-framework.providers - jersey-test-framework-provider-jdk-http - 2.23.2 - test - - - org.glassfish.jersey.media - jersey-media-json-jackson - 2.23.2 - test - - - com.jsoniter - jsoniter - 0.9.8 - test - - - org.apache.commons - commons-lang3 - 3.4 - test - + + org.springframework.data + spring-data-redis + 1.8.6.RELEASE + provided + true + - - org.hibernate - hibernate-core - 5.2.10.Final - test - + + com.squareup.retrofit2 + retrofit + 2.5.0 + provided + + + com.squareup.okhttp3 + okhttp + 3.6.0 + provided + - - com.jayway.jsonpath - json-path - 2.3.0 - test - + + io.springfox + springfox-spring-web + 2.6.1 + provided + true + - org.jetbrains.kotlin - kotlin-stdlib - 1.1.3-2 - test + io.javaslang + javaslang + 2.0.6 + provided - - org.jetbrains.kotlin - kotlin-reflect - 1.1.3-2 - test - + + org.glassfish.jersey.core + jersey-common + 2.23.2 + provided + - - org.springframework.security - spring-security-web - 4.2.3.RELEASE - test - + + joda-time + joda-time + 2.10 + provided + - + + net.sf.trove4j + core + 3.1.0 + provided + - - - travis - - - env.TRAVIS - true - - - - - - - - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - - prepare-agent - - - - report - test - - report - - - - - - - + + org.javamoney.moneta + moneta-core + 1.3 + provided + - + + io.airlift + slice + 0.36 + provided + + diff --git a/rfc4627.txt b/rfc4627.txt old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/JSON.java b/src/main/java/com/alibaba/fastjson/JSON.java old mode 100755 new mode 100644 index 48c8a50b0c..1a94647148 --- a/src/main/java/com/alibaba/fastjson/JSON.java +++ b/src/main/java/com/alibaba/fastjson/JSON.java @@ -15,25 +15,19 @@ */ package com.alibaba.fastjson; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Writer; +import java.io.*; import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.lang.reflect.Type; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.zip.GZIPInputStream; -import com.alibaba.fastjson.parser.DefaultJSONParser; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.*; import com.alibaba.fastjson.parser.deserializer.ExtraProcessor; import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider; import com.alibaba.fastjson.parser.deserializer.FieldTypeResolver; @@ -41,7 +35,6 @@ import com.alibaba.fastjson.serializer.*; import com.alibaba.fastjson.util.IOUtils; import com.alibaba.fastjson.util.TypeUtils; -import sun.reflect.annotation.AnnotationType; /** * This is the main class for using Fastjson. You usually call these two methods {@link #toJSONString(Object)} and {@link #parseObject(String, Class)}. @@ -72,15 +65,14 @@ public abstract class JSON implements JSONStreamAware, JSONAware { public static TimeZone defaultTimeZone = TimeZone.getDefault(); public static Locale defaultLocale = Locale.getDefault(); - public static String DEFAULT_TYPE_KEY = "@type"; - static final SerializeFilter[] emptyFilters = new SerializeFilter[0]; - public static String DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; - //public static String DEFFAULT_LOCAL_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS"; - public static int DEFAULT_PARSER_FEATURE; + public static int DEFAULT_GENERATE_FEATURE; + + private static final ConcurrentHashMap mixInsMapper = new ConcurrentHashMap(16); + static { int features = 0; features |= Feature.AutoCloseSource.getMask(); @@ -94,7 +86,6 @@ public abstract class JSON implements JSONStreamAware, JSONAware { DEFAULT_PARSER_FEATURE = features; } - public static int DEFAULT_GENERATE_FEATURE; static { int features = 0; features |= SerializerFeature.QuoteFieldNames.getMask(); @@ -102,17 +93,42 @@ public abstract class JSON implements JSONStreamAware, JSONAware { features |= SerializerFeature.WriteEnumUsingName.getMask(); features |= SerializerFeature.SortField.getMask(); + DEFAULT_GENERATE_FEATURE = features; + + config(IOUtils.DEFAULT_PROPERTIES); + } + + private static void config(Properties properties) { { - String featuresProperty = IOUtils.getStringProperty("fastjson.serializerFeatures.MapSortField"); + String featuresProperty = properties.getProperty("fastjson.serializerFeatures.MapSortField"); int mask = SerializerFeature.MapSortField.getMask(); if ("true".equals(featuresProperty)) { - features |= mask; + DEFAULT_GENERATE_FEATURE |= mask; } else if ("false".equals(featuresProperty)) { - features &= ~mask; + DEFAULT_GENERATE_FEATURE &= ~mask; } } - DEFAULT_GENERATE_FEATURE = features; + { + if ("true".equals(properties.getProperty("parser.features.NonStringKeyAsString"))) { + DEFAULT_PARSER_FEATURE |= Feature.NonStringKeyAsString.getMask(); + } + } + + { + if ("true".equals(properties.getProperty("parser.features.ErrorOnEnumNotMatch")) + || "true".equals(properties.getProperty("fastjson.parser.features.ErrorOnEnumNotMatch"))) + { + DEFAULT_PARSER_FEATURE |= Feature.ErrorOnEnumNotMatch.getMask(); + } + } + + { + if ("false".equals(properties.getProperty("fastjson.asmEnable"))) { + ParserConfig.global.setAsmEnable(false); + SerializeConfig.globalInstance.setAsmEnable(false); + } + } } /** @@ -139,6 +155,19 @@ public static Object parse(String text, ParserConfig config) { return parse(text, config, DEFAULT_PARSER_FEATURE); } + /** + * + * @since 1.2.68 + */ + public static Object parse(String text, ParserConfig config, Feature... features) { + int featureValues = DEFAULT_PARSER_FEATURE; + for (Feature feature : features) { + featureValues = Feature.config(featureValues, feature, true); + } + + return parse(text, config, featureValues); + } + /** * * @since 1.2.38 @@ -239,8 +268,8 @@ public static JSONObject parseObject(String text) { * * @param text json string * @param type type refernce - * @param features - * @return + * @param features parser features + * @return an object of type T from the string */ @SuppressWarnings("unchecked") public static T parseObject(String text, TypeReference type, Feature... features) { @@ -336,7 +365,7 @@ public static T parseObject(String input, Type clazz, ParserConfig config, i @SuppressWarnings("unchecked") public static T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor, int featureValues, Feature... features) { - if (input == null) { + if (input == null || input.length() == 0) { return null; } @@ -381,25 +410,70 @@ public static T parseObject(byte[] bytes, Type clazz, Feature... features) { */ @SuppressWarnings("unchecked") public static T parseObject(byte[] bytes, int offset, int len, Charset charset, Type clazz, Feature... features) { + return (T) parseObject(bytes, offset, len, charset, clazz, ParserConfig.global, null, DEFAULT_PARSER_FEATURE, features); + } + + /** + * @since 1.2.55 + */ + @SuppressWarnings("unchecked") + public static T parseObject(byte[] bytes, + Charset charset, + Type clazz, + ParserConfig config, + ParseProcess processor, + int featureValues, + Feature... features) { + return (T) parseObject(bytes, 0, bytes.length, charset, clazz, config, processor, featureValues, features); + } + + /** + * @since 1.2.55 + */ + @SuppressWarnings("unchecked") + public static T parseObject(byte[] bytes, int offset, int len, + Charset charset, + Type clazz, + ParserConfig config, + ParseProcess processor, + int featureValues, + Feature... features) { if (charset == null) { charset = IOUtils.UTF8; } - - String strVal; + + String strVal = null; if (charset == IOUtils.UTF8) { char[] chars = allocateChars(bytes.length); int chars_len = IOUtils.decodeUTF8(bytes, offset, len, chars); + if (chars_len < 0) { + InputStreamReader gzipReader = null; + try { + gzipReader = new InputStreamReader( + new GZIPInputStream( + new ByteArrayInputStream(bytes, offset, len)), "UTF-8"); + strVal = IOUtils.readAll(gzipReader); + } catch (Exception ex) { + return null; + } finally { + IOUtils.close(gzipReader); + } + } + if (strVal == null && chars_len < 0) { return null; } - strVal = new String(chars, 0, chars_len); + + if (strVal == null) { + strVal = new String(chars, 0, chars_len); + } } else { if (len < 0) { return null; } strVal = new String(bytes, offset, len, charset); } - return (T) parseObject(strVal, clazz, features); + return (T) parseObject(strVal, clazz, config, processor, featureValues, features); } @SuppressWarnings("unchecked") @@ -443,7 +517,7 @@ public static T parseObject(char[] input, int length, Type clazz, Feature... return (T) value; } - + /** * @since 1.2.11 */ @@ -453,7 +527,7 @@ public static T parseObject(InputStream is, // Feature... features) throws IOException { return (T) parseObject(is, IOUtils.UTF8, type, features); } - + /** * @since 1.2.11 */ @@ -462,10 +536,36 @@ public static T parseObject(InputStream is, // Charset charset, // Type type, // Feature... features) throws IOException { + return (T) parseObject(is, charset, type, ParserConfig.global, features); + } + + /** + * @since 1.2.55 + */ + @SuppressWarnings("unchecked") + public static T parseObject(InputStream is, // + Charset charset, // + Type type, // + ParserConfig config, // + Feature... features) throws IOException { + return (T) parseObject(is, charset, type, config, null, DEFAULT_PARSER_FEATURE, features); + } + + /** + * @since 1.2.55 + */ + @SuppressWarnings("unchecked") + public static T parseObject(InputStream is, // + Charset charset, // + Type type, // + ParserConfig config, // + ParseProcess processor, // + int featureValues, // + Feature... features) throws IOException { if (charset == null) { charset = IOUtils.UTF8; } - + byte[] bytes = allocateBytes(1024 * 64); int offset = 0; for (;;) { @@ -480,8 +580,8 @@ public static T parseObject(InputStream is, // bytes = newBytes; } } - - return (T) parseObject(bytes, 0, offset, charset, type, features); + + return (T) parseObject(bytes, 0, offset, charset, type, config, processor, featureValues, features); } public static T parseObject(String text, Class clazz) { @@ -489,11 +589,15 @@ public static T parseObject(String text, Class clazz) { } public static JSONArray parseArray(String text) { + return parseArray(text, ParserConfig.global); + } + + public static JSONArray parseArray(String text, ParserConfig parserConfig) { if (text == null) { return null; } - DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance()); + DefaultJSONParser parser = new DefaultJSONParser(text, parserConfig); JSONArray array; @@ -501,7 +605,7 @@ public static JSONArray parseArray(String text) { if (lexer.token() == JSONToken.NULL) { lexer.nextToken(); array = null; - } else if (lexer.token() == JSONToken.EOF) { + } else if (lexer.token() == JSONToken.EOF && lexer.isBlankInput()) { array = null; } else { array = new JSONArray(); @@ -516,13 +620,17 @@ public static JSONArray parseArray(String text) { } public static List parseArray(String text, Class clazz) { + return parseArray(text, clazz, ParserConfig.global); + } + + public static List parseArray(String text, Class clazz, ParserConfig config) { if (text == null) { return null; } List list; - DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance()); + DefaultJSONParser parser = new DefaultJSONParser(text, config); JSONLexer lexer = parser.lexer; int token = lexer.token(); if (token == JSONToken.NULL) { @@ -543,13 +651,17 @@ public static List parseArray(String text, Class clazz) { } public static List parseArray(String text, Type[] types) { + return parseArray(text, types, ParserConfig.global); + } + + public static List parseArray(String text, Type[] types, ParserConfig config) { if (text == null) { return null; } List list; - DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance()); + DefaultJSONParser parser = new DefaultJSONParser(text, config); Object[] objectArray = parser.parseArray(types); if (objectArray == null) { list = null; @@ -579,7 +691,7 @@ public static String toJSONString(Object object) { public static String toJSONString(Object object, SerializerFeature... features) { return toJSONString(object, DEFAULT_GENERATE_FEATURE, features); } - + /** * @since 1.2.11 */ @@ -589,7 +701,15 @@ public static String toJSONString(Object object, int defaultFeatures, Serializer try { JSONSerializer serializer = new JSONSerializer(out); serializer.write(object); - return out.toString(); + String outString = out.toString(); + int len = outString.length(); + if (len > 0 + && outString.charAt(len -1) == '.' + && object instanceof Number + && !out.isEnabled(SerializerFeature.WriteClassName)) { + return outString.substring(0, len - 1); + } + return outString; } finally { out.close(); } @@ -614,6 +734,10 @@ public static String toJSONString(Object object, SerializeFilter[] filters, Seri public static byte[] toJSONBytes(Object object, SerializerFeature... features) { return toJSONBytes(object, DEFAULT_GENERATE_FEATURE, features); } + + public static byte[] toJSONBytes(Object object, SerializeFilter filter, SerializerFeature... features) { + return toJSONBytes(object, SerializeConfig.globalInstance, new SerializeFilter[] {filter}, DEFAULT_GENERATE_FEATURE, features); + } /** * @since 1.2.11 @@ -639,7 +763,7 @@ public static String toJSONString(Object object, // SerializerFeature... features) { return toJSONString(object, config, filters, null, DEFAULT_GENERATE_FEATURE, features); } - + /** * @since 1.2.9 * @return @@ -681,20 +805,109 @@ public static String toJSONStringZ(Object object, SerializeConfig mapping, Seria return toJSONString(object, mapping, emptyFilters, null, 0, features); } + /** + * @since 1.2.42 + */ public static byte[] toJSONBytes(Object object, SerializeConfig config, SerializerFeature... features) { - return toJSONBytes(object, config, DEFAULT_GENERATE_FEATURE, features); + return toJSONBytes(object, config, emptyFilters, DEFAULT_GENERATE_FEATURE, features); } - + /** - * @since 1.2.11 + * @since 1.2.11 */ public static byte[] toJSONBytes(Object object, SerializeConfig config, int defaultFeatures, SerializerFeature... features) { + return toJSONBytes(object, config, emptyFilters, defaultFeatures, features); + } + + /** + * @since 1.2.42 + */ + public static byte[] toJSONBytes(Object object, SerializeFilter[] filters, SerializerFeature... features) { + return toJSONBytes(object, SerializeConfig.globalInstance, filters, DEFAULT_GENERATE_FEATURE, features); + } + + public static byte[] toJSONBytes(Object object, SerializeConfig config, SerializeFilter filter, SerializerFeature... features) { + return toJSONBytes(object, config, new SerializeFilter[] {filter}, DEFAULT_GENERATE_FEATURE, features); + } + + /** + * @since 1.2.42 + */ + public static byte[] toJSONBytes(Object object, SerializeConfig config, SerializeFilter[] filters, int defaultFeatures, SerializerFeature... features) { + return toJSONBytes(object, config, filters, null, defaultFeatures, features); + } + + /** + * @since 1.2.55 + */ + public static byte[] toJSONBytes(Object object, SerializeConfig config, SerializeFilter[] filters, String dateFormat, int defaultFeatures, SerializerFeature... features) { + return toJSONBytes(IOUtils.UTF8, object, config, filters, dateFormat, defaultFeatures, features); + } + + /** + * @since 1.2.55 + */ + public static byte[] toJSONBytes(Charset charset, // + Object object, // + SerializeConfig config, // + SerializeFilter[] filters, // + String dateFormat, // + int defaultFeatures, // + SerializerFeature... features) { SerializeWriter out = new SerializeWriter(null, defaultFeatures, features); try { JSONSerializer serializer = new JSONSerializer(out, config); + + if (dateFormat != null && dateFormat.length() != 0) { + serializer.setDateFormat(dateFormat); + serializer.config(SerializerFeature.WriteDateUseDateFormat, true); + } + + if (filters != null) { + for (SerializeFilter filter : filters) { + serializer.addFilter(filter); + } + } + + serializer.write(object); + return out.toBytes(charset); + } finally { + out.close(); + } + } + + /** + * Use the date format in FastJsonConfig to serialize JSON + * + * @param dateFormat the date format in FastJsonConfigs + * @since 1.2.55 + */ + public static byte[] toJSONBytesWithFastJsonConfig(Charset charset, // + Object object, // + SerializeConfig config, // + SerializeFilter[] filters, // + String dateFormat, // + int defaultFeatures, // + SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(null, defaultFeatures, features); + + try { + JSONSerializer serializer = new JSONSerializer(out, config); + + if (dateFormat != null && dateFormat.length() != 0) { + serializer.setFastJsonConfigDateFormatPattern(dateFormat); + serializer.config(SerializerFeature.WriteDateUseDateFormat, true); + } + + if (filters != null) { + for (SerializeFilter filter : filters) { + serializer.addFilter(filter); + } + } + serializer.write(object); - return out.toBytes(IOUtils.UTF8); + return out.toBytes(charset); } finally { out.close(); } @@ -707,7 +920,7 @@ public static String toJSONString(Object object, boolean prettyFormat) { return toJSONString(object, SerializerFeature.PrettyFormat); } - + /** * @deprecated use writeJSONString */ @@ -740,7 +953,7 @@ public static void writeJSONString(Writer writer, Object object, int defaultFeat out.close(); } } - + /** * write object as json to OutputStream * @param os output stream @@ -770,7 +983,7 @@ public static final int writeJSONString(OutputStream os, // null, // defaultFeatures, // features); - } + } public static final int writeJSONString(OutputStream os, // Charset charset, // @@ -819,6 +1032,39 @@ public static final int writeJSONString(OutputStream os, // } } + public static final int writeJSONStringWithFastJsonConfig(OutputStream os, // + Charset charset, // + Object object, // + SerializeConfig config, // + SerializeFilter[] filters, // + String dateFormat, // + int defaultFeatures, // + SerializerFeature... features) throws IOException { + SerializeWriter writer = new SerializeWriter(null, defaultFeatures, features); + + try { + JSONSerializer serializer = new JSONSerializer(writer, config); + + if (dateFormat != null && dateFormat.length() != 0) { + serializer.setFastJsonConfigDateFormatPattern(dateFormat); + serializer.config(SerializerFeature.WriteDateUseDateFormat, true); + } + + if (filters != null) { + for (SerializeFilter filter : filters) { + serializer.addFilter(filter); + } + } + + serializer.write(object); + + int len = writer.writeToEx(os, charset); + return len; + } finally { + writer.close(); + } + } + // ====================================== @Override public String toString() { @@ -835,6 +1081,20 @@ public String toJSONString() { } } + /** + * @since 1.2.57 + */ + public String toString(SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(null, JSON.DEFAULT_GENERATE_FEATURE, features); + + try { + new JSONSerializer(out).write(this); + return out.toString(); + } finally { + out.close(); + } + } + public void writeJSONString(Appendable appendable) { SerializeWriter out = new SerializeWriter(); try { @@ -892,7 +1152,7 @@ public static Object toJSON(Object javaObject, SerializeConfig config) { for (Map.Entry entry : map.entrySet()) { Object key = entry.getKey(); String jsonKey = TypeUtils.castToString(key); - Object jsonValue = toJSON(entry.getValue()); + Object jsonValue = toJSON(entry.getValue(), config); json.put(jsonKey, jsonValue); } @@ -905,7 +1165,7 @@ public static Object toJSON(Object javaObject, SerializeConfig config) { JSONArray array = new JSONArray(collection.size()); for (Object item : collection) { - Object jsonValue = toJSON(item); + Object jsonValue = toJSON(item, config); array.add(jsonValue); } @@ -944,12 +1204,23 @@ public static Object toJSON(Object javaObject, SerializeConfig config) { ObjectSerializer serializer = config.getObjectWriter(clazz); if (serializer instanceof JavaBeanSerializer) { JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer) serializer; - - JSONObject json = new JSONObject(); + + JSONType jsonType = javaBeanSerializer.getJSONType(); + boolean ordered = false; + if (jsonType != null) { + for (SerializerFeature serializerFeature : jsonType.serialzeFeatures()) { + if (serializerFeature == SerializerFeature.SortField + || serializerFeature == SerializerFeature.MapSortField) { + ordered = true; + } + } + } + + JSONObject json = new JSONObject(ordered); try { Map values = javaBeanSerializer.getFieldValuesMap(javaObject); for (Map.Entry entry : values.entrySet()) { - json.put(entry.getKey(), toJSON(entry.getValue())); + json.put(entry.getKey(), toJSON(entry.getValue(), config)); } } catch (Exception e) { throw new JSONException("toJSON error", e); @@ -957,7 +1228,7 @@ public static Object toJSON(Object javaObject, SerializeConfig config) { return json; } - String text = JSON.toJSONString(javaObject); + String text = JSON.toJSONString(javaObject, config); return JSON.parse(text); } @@ -969,6 +1240,10 @@ public static T toJavaObject(JSON json, Class clazz) { * @since 1.2.9 */ public T toJavaObject(Class clazz) { + if (clazz == JSONArray.class || clazz == JSON.class || clazz == Collection.class || clazz == List.class) { + return (T) this; + } + return TypeUtils.cast(this, clazz, ParserConfig.getGlobalInstance()); } @@ -1004,7 +1279,7 @@ private static byte[] allocateBytes(int length) { return chars; } - + private final static ThreadLocal charsLocal = new ThreadLocal(); private static char[] allocateChars(int length) { char[] chars = charsLocal.get(); @@ -1023,9 +1298,128 @@ private static char[] allocateChars(int length) { return chars; } + /** + * @deprecated Please use {@link com.alibaba.fastjson.JSONValidator} instead. + */ + public static boolean isValid(String str) { + if (str == null || str.length() == 0) { + return false; + } + + JSONScanner lexer = new JSONScanner(str); + try { + lexer.nextToken(); + + final int token = lexer.token(); + switch (token) { + case JSONToken.LBRACE: + if (lexer.getCurrent() == JSONLexer.EOI) { + return false; + } + lexer.skipObject(true); + break; + case JSONToken.LBRACKET: + lexer.skipArray(true); + break; + case JSONToken.LITERAL_INT: + case JSONToken.LITERAL_STRING: + case JSONToken.LITERAL_FLOAT: + case JSONToken.LITERAL_ISO8601_DATE: + case JSONToken.NULL: + case JSONToken.TRUE: + case JSONToken.FALSE: + lexer.nextToken(); + break; + default: + return false; + } + + return lexer.token() == JSONToken.EOF; + } catch (Exception ex) { + return false; + } finally { + lexer.close(); + } + } + + /** + * @deprecated Please use {@link com.alibaba.fastjson.JSONValidator} instead. + */ + public static boolean isValidObject(String str) { + if (str == null || str.length() == 0) { + return false; + } + + JSONScanner lexer = new JSONScanner(str); + + try { + lexer.nextToken(); + final int token = lexer.token(); + if (token == JSONToken.LBRACE) { + if (lexer.getCurrent() == JSONLexer.EOI) { + return false; + } + lexer.skipObject(true); + return lexer.token() == JSONToken.EOF; + } + return false; + } catch (Exception ex) { + return false; + } finally { + lexer.close(); + } + } + + /** + * @deprecated Please use {@link com.alibaba.fastjson.JSONValidator} instead. + */ + public static boolean isValidArray(String str) { + if (str == null || str.length() == 0) { + return false; + } + + JSONScanner lexer = new JSONScanner(str); + try { + lexer.nextToken(); + final int token = lexer.token(); + if (token == JSONToken.LBRACKET) { + lexer.skipArray(true); + return lexer.token() == JSONToken.EOF; + } + return false; + } catch (Exception ex) { + return false; + } finally { + lexer.close(); + } + } + public static void handleResovleTask(DefaultJSONParser parser, T value) { parser.handleResovleTask(value); } + + public static void addMixInAnnotations(Type target, Type mixinSource) { + if (target != null && mixinSource != null) { + mixInsMapper.put(target, mixinSource); + } + } + + public static void removeMixInAnnotations(Type target) { + if (target != null) { + mixInsMapper.remove(target); + } + } + + public static void clearMixInAnnotations() { + mixInsMapper.clear(); + } + + public static Type getMixInAnnotations(Type target) { + if (target != null) { + return mixInsMapper.get(target); + } + return null; + } - public final static String VERSION = "1.2.41"; + public final static String VERSION = "1.2.83"; } diff --git a/src/main/java/com/alibaba/fastjson/JSONArray.java b/src/main/java/com/alibaba/fastjson/JSONArray.java old mode 100755 new mode 100644 index 7e73d773d3..25807e484f --- a/src/main/java/com/alibaba/fastjson/JSONArray.java +++ b/src/main/java/com/alibaba/fastjson/JSONArray.java @@ -29,19 +29,15 @@ import static com.alibaba.fastjson.util.TypeUtils.castToString; import static com.alibaba.fastjson.util.TypeUtils.castToTimestamp; +import java.io.IOException; +import java.io.ObjectInputStream; import java.io.Serializable; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.RandomAccess; +import java.util.*; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import com.alibaba.fastjson.util.TypeUtils; /** @@ -59,6 +55,9 @@ public JSONArray(){ } public JSONArray(List list){ + if (list == null){ + throw new IllegalArgumentException("list is null."); + } this.list = list; } @@ -132,20 +131,20 @@ public boolean containsAll(Collection c) { return list.containsAll(c); } - public boolean addAll(Collection c) { + public boolean addAll(Collection c) { return list.addAll(c); } - public JSONArray fluentAddAll(Collection c) { + public JSONArray fluentAddAll(Collection c) { list.addAll(c); return this; } - public boolean addAll(int index, Collection c) { + public boolean addAll(int index, Collection c) { return list.addAll(index, c); } - public JSONArray fluentAddAll(int index, Collection c) { + public JSONArray fluentAddAll(int index, Collection c) { list.addAll(index, c); return this; } @@ -182,7 +181,7 @@ public Object set(int index, Object element) { list.add(element); return null; } - + if (list.size() <= index) { for (int i = list.size(); i < index; ++i) { list.add(null); @@ -190,7 +189,7 @@ public Object set(int index, Object element) { list.add(element); return null; } - + return list.set(index, element); } @@ -248,6 +247,10 @@ public JSONObject getJSONObject(int index) { return (JSONObject) value; } + if (value instanceof Map) { + return new JSONObject((Map) value); + } + return (JSONObject) toJSON(value); } @@ -258,6 +261,10 @@ public JSONArray getJSONArray(int index) { return (JSONArray) value; } + if (value instanceof List) { + return new JSONArray((List) value); + } + return (JSONArray) toJSON(value); } @@ -305,11 +312,12 @@ public Byte getByte(int index) { public byte getByteValue(int index) { Object value = get(index); - if (value == null) { + Byte byteVal = castToByte(value); + if (byteVal == null) { return 0; } - return castToByte(value).byteValue(); + return byteVal; } public Short getShort(int index) { @@ -321,11 +329,12 @@ public Short getShort(int index) { public short getShortValue(int index) { Object value = get(index); - if (value == null) { + Short shortVal = castToShort(value); + if (shortVal == null) { return 0; } - return castToShort(value).shortValue(); + return shortVal; } public Integer getInteger(int index) { @@ -337,11 +346,12 @@ public Integer getInteger(int index) { public int getIntValue(int index) { Object value = get(index); - if (value == null) { + Integer intVal = castToInt(value); + if (intVal == null) { return 0; } - return castToInt(value).intValue(); + return intVal; } public Long getLong(int index) { @@ -353,11 +363,12 @@ public Long getLong(int index) { public long getLongValue(int index) { Object value = get(index); - if (value == null) { + Long longVal = castToLong(value); + if (longVal == null) { return 0L; } - return castToLong(value).longValue(); + return longVal; } public Float getFloat(int index) { @@ -369,11 +380,12 @@ public Float getFloat(int index) { public float getFloatValue(int index) { Object value = get(index); - if (value == null) { + Float floatValue = castToFloat(value); + if (floatValue == null) { return 0F; } - return castToFloat(value).floatValue(); + return floatValue; } public Double getDouble(int index) { @@ -385,11 +397,12 @@ public Double getDouble(int index) { public double getDoubleValue(int index) { Object value = get(index); - if (value == null) { + Double doubleValue = castToDouble(value); + if (doubleValue == null) { return 0D; } - return castToDouble(value); + return doubleValue; } public BigDecimal getBigDecimal(int index) { @@ -416,13 +429,13 @@ public java.util.Date getDate(int index) { return castToDate(value); } - public java.sql.Date getSqlDate(int index) { + public Object getSqlDate(int index) { Object value = get(index); return castToSqlDate(value); } - public java.sql.Timestamp getTimestamp(int index) { + public Object getTimestamp(int index) { Object value = get(index); return castToTimestamp(value); @@ -450,10 +463,43 @@ public Object clone() { } public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof JSONArray) { + return this.list.equals(((JSONArray) obj).list); + } + return this.list.equals(obj); } public int hashCode() { return this.list.hashCode(); } + + private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + JSONObject.SecureObjectInputStream.ensureFields(); + if (JSONObject.SecureObjectInputStream.fields != null && !JSONObject.SecureObjectInputStream.fields_error) { + ObjectInputStream secIn = new JSONObject.SecureObjectInputStream(in); + try { + secIn.defaultReadObject(); + return; + } catch (java.io.NotActiveException e) { + // skip + } + } + + in.defaultReadObject(); + for (Object item : list) { + if (item == null) { + continue; + } + + String typeName = item.getClass().getName(); + if (TypeUtils.getClassFromMapping(typeName) == null) { + ParserConfig.global.checkAutoType(typeName, null); + } + } + } } diff --git a/src/main/java/com/alibaba/fastjson/JSONAware.java b/src/main/java/com/alibaba/fastjson/JSONAware.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/JSONException.java b/src/main/java/com/alibaba/fastjson/JSONException.java old mode 100755 new mode 100644 index 6dcae3675c..f225de337c --- a/src/main/java/com/alibaba/fastjson/JSONException.java +++ b/src/main/java/com/alibaba/fastjson/JSONException.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2019 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,15 +21,15 @@ @SuppressWarnings("serial") public class JSONException extends RuntimeException { - public JSONException(){ + public JSONException() { super(); } - public JSONException(String message){ + public JSONException(String message) { super(message); } - public JSONException(String message, Throwable cause){ + public JSONException(String message, Throwable cause) { super(message, cause); } } diff --git a/src/main/java/com/alibaba/fastjson/JSONObject.java b/src/main/java/com/alibaba/fastjson/JSONObject.java old mode 100755 new mode 100644 index 6476c2fac9..ac24bf0ee0 --- a/src/main/java/com/alibaba/fastjson/JSONObject.java +++ b/src/main/java/com/alibaba/fastjson/JSONObject.java @@ -29,20 +29,17 @@ import static com.alibaba.fastjson.util.TypeUtils.castToSqlDate; import static com.alibaba.fastjson.util.TypeUtils.castToTimestamp; -import java.io.Serializable; +import java.io.*; +import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.TypeUtils; @@ -61,6 +58,9 @@ public JSONObject(){ } public JSONObject(Map map){ + if (map == null) { + throw new IllegalArgumentException("map is null."); + } this.map = map; } @@ -89,7 +89,17 @@ public boolean isEmpty() { } public boolean containsKey(Object key) { - return map.containsKey(key); + boolean result = map.containsKey(key); + if (!result) { + if (key instanceof Number + || key instanceof Character + || key instanceof Boolean + || key instanceof UUID + ) { + result = map.containsKey(key.toString()); + } + } + return result; } public boolean containsValue(Object value) { @@ -99,13 +109,24 @@ public boolean containsValue(Object value) { public Object get(Object key) { Object val = map.get(key); - if (val == null && key instanceof Number) { - val = map.get(key.toString()); + if (val == null) { + if (key instanceof Number + || key instanceof Character + || key instanceof Boolean + || key instanceof UUID + ) { + val = map.get(key.toString()); + } } return val; } + public Object getOrDefault(Object key, Object defaultValue) { + Object v; + return ((v = get(key)) != null) ? v : defaultValue; + } + public JSONObject getJSONObject(String key) { Object value = map.get(key); @@ -113,6 +134,10 @@ public JSONObject getJSONObject(String key) { return (JSONObject) value; } + if (value instanceof Map) { + return new JSONObject((Map) value); + } + if (value instanceof String) { return JSON.parseObject((String) value); } @@ -127,6 +152,10 @@ public JSONArray getJSONArray(String key) { return (JSONArray) value; } + if (value instanceof List) { + return new JSONArray((List) value); + } + if (value instanceof String) { return (JSONArray) JSON.parse((String) value); } @@ -313,32 +342,32 @@ public Date getDate(String key) { return castToDate(value); } - public java.sql.Date getSqlDate(String key) { + public Object getSqlDate(String key) { Object value = get(key); return castToSqlDate(value); } - public java.sql.Timestamp getTimestamp(String key) { + public Object getTimestamp(String key) { Object value = get(key); return castToTimestamp(value); } - + public Object put(String key, Object value) { return map.put(key, value); } - + public JSONObject fluentPut(String key, Object value) { map.put(key, value); return this; } - public void putAll(Map m) { + public void putAll(Map m) { map.putAll(m); } - public JSONObject fluentPutAll(Map m) { + public JSONObject fluentPutAll(Map m) { map.putAll(m); return this; } @@ -374,17 +403,27 @@ public Set> entrySet() { } @Override - public Object clone() { + public JSONObject clone() { return new JSONObject(map instanceof LinkedHashMap // - ? new LinkedHashMap(map) // - : new HashMap(map) - ); + ? new LinkedHashMap(map) // + : new HashMap(map) + ); } + @Override public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof JSONObject) { + return this.map.equals(((JSONObject) obj).map); + } + return this.map.equals(obj); } + @Override public int hashCode() { return this.map.hashCode(); } @@ -395,14 +434,14 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl if (method.getName().equals("equals")) { return this.equals(args[0]); } - + Class returnType = method.getReturnType(); if (returnType != void.class) { throw new JSONException("illegal setter"); } String name = null; - JSONField annotation = method.getAnnotation(JSONField.class); + JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class); if (annotation != null) { if (annotation.name().length() != 0) { name = annotation.name(); @@ -411,7 +450,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl if (name == null) { name = method.getName(); - + if (!name.startsWith("set")) { throw new JSONException("illegal setter"); } @@ -434,7 +473,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl } String name = null; - JSONField annotation = method.getAnnotation(JSONField.class); + JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class); if (annotation != null) { if (annotation.name().length() != 0) { name = annotation.name(); @@ -463,7 +502,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl throw new JSONException("illegal getter"); } } - + Object value = map.get(name); return TypeUtils.cast(value, method.getGenericReturnType(), ParserConfig.getGlobalInstance()); } @@ -474,4 +513,131 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl public Map getInnerMap() { return this.map; } + + + + private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + SecureObjectInputStream.ensureFields(); + if (SecureObjectInputStream.fields != null && !SecureObjectInputStream.fields_error) { + ObjectInputStream secIn = new SecureObjectInputStream(in); + try { + secIn.defaultReadObject(); + return; + } catch (java.io.NotActiveException e) { + // skip + } + } + + in.defaultReadObject(); + for (Entry entry : map.entrySet()) { + final Object key = entry.getKey(); + if (key != null) { + ParserConfig.global.checkAutoType(key.getClass()); + } + + final Object value = entry.getValue(); + if (value != null) { + ParserConfig.global.checkAutoType(value.getClass()); + } + } + } + + static class SecureObjectInputStream extends ObjectInputStream { + static Field[] fields; + static volatile boolean fields_error; + + static void ensureFields() { + if (fields == null && !fields_error) { + try { + final Field[] declaredFields = ObjectInputStream.class.getDeclaredFields(); + String[] fieldnames = new String[]{"bin", "passHandle", "handles", "curContext"}; + Field[] array = new Field[fieldnames.length]; + for (int i = 0; i < fieldnames.length; i++) { + Field field = TypeUtils + .getField(ObjectInputStream.class + , fieldnames[i] + , declaredFields + ); + field.setAccessible(true); + array[i] = field; + } + fields = array; + } catch (Throwable error) { + fields_error = true; + } + } + } + + public SecureObjectInputStream(ObjectInputStream in) throws IOException { + super(in); + try { + for (int i = 0; i < fields.length; i++) { + final Field field = fields[i]; + final Object value = field.get(in); + field.set(this, value); + } + } catch (IllegalAccessException e) { + fields_error = true; + } + } + + protected Class resolveClass(ObjectStreamClass desc) + throws IOException, ClassNotFoundException { + String name = desc.getName(); + if (name.length() > 2) { + int index = name.lastIndexOf('['); + if (index != -1) { + name = name.substring(index + 1); + } + if (name.length() > 2 && name.charAt(0) == 'L' && name.charAt(name.length() - 1) == ';') { + name = name.substring(1, name.length() - 1); + } + + if (TypeUtils.getClassFromMapping(name) == null) { + ParserConfig.global.checkAutoType(name, null, Feature.SupportAutoType.mask); + } + } + return super.resolveClass(desc); + } + + protected Class resolveProxyClass(String[] interfaces) + throws IOException, ClassNotFoundException { + for (String interfacename : interfaces) { + //检查是否处于黑名单 + if (TypeUtils.getClassFromMapping(interfacename) == null) { + ParserConfig.global.checkAutoType(interfacename, null); + } + } + return super.resolveProxyClass(interfaces); + } + + //Hack:默认构造方法会调用这个方法,重写此方法使用反射还原部分关键属性 + protected void readStreamHeader() throws IOException, StreamCorruptedException { + + } + } + + public T toJavaObject(Class clazz) { + if (clazz == Map.class || clazz == JSONObject.class || clazz == JSON.class) { + return (T) this; + } + + if (clazz == Object.class && !containsKey(JSON.DEFAULT_TYPE_KEY)) { + return (T) this; + } + + return TypeUtils.castToJavaBean(this, clazz, ParserConfig.getGlobalInstance()); + } + + public T toJavaObject(Class clazz, ParserConfig config, int features) { + if (clazz == Map.class) { + return (T) this; + } + + if (clazz == Object.class && !containsKey(JSON.DEFAULT_TYPE_KEY)) { + return (T) this; + } + + return TypeUtils.castToJavaBean(this, clazz, config); + } } diff --git a/src/main/java/com/alibaba/fastjson/JSONPObject.java b/src/main/java/com/alibaba/fastjson/JSONPObject.java index 65d018ad08..b4527c4c9f 100644 --- a/src/main/java/com/alibaba/fastjson/JSONPObject.java +++ b/src/main/java/com/alibaba/fastjson/JSONPObject.java @@ -14,8 +14,6 @@ public class JSONPObject implements JSONSerializable { public static String SECURITY_PREFIX = "/**/"; private String function; - private static final int BrowserSecureMask = SerializerFeature.BrowserSecure.mask; - private final List parameters = new ArrayList(); public JSONPObject() { @@ -49,7 +47,9 @@ public String toJSONString() { public void write(JSONSerializer serializer, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter writer = serializer.out; - if ((features & BrowserSecureMask) != 0 || (writer.isEnabled(BrowserSecureMask))) { + if ((features & SerializerFeature.BrowserSecure.mask) != 0 + || (writer.isEnabled(SerializerFeature.BrowserSecure.mask))) + { writer.write(SECURITY_PREFIX); } diff --git a/src/main/java/com/alibaba/fastjson/JSONPatch.java b/src/main/java/com/alibaba/fastjson/JSONPatch.java new file mode 100644 index 0000000000..05db0db6c0 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONPatch.java @@ -0,0 +1,91 @@ +package com.alibaba.fastjson; + +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONPatch { + public static String apply(String original, String patch) { + Object object + = apply( + JSON.parse(original, Feature.OrderedField), patch); + return JSON.toJSONString(object); + } + + public static Object apply(Object object, String patch) { + Operation[] operations; + if (isObject(patch)) { + operations = new Operation[] { + JSON.parseObject(patch, Operation.class)}; + } else { + operations = JSON.parseObject(patch, Operation[].class); + } + + for (Operation op : operations) { + JSONPath path = JSONPath.compile(op.path); + switch (op.type) { + case add: + path.patchAdd(object, op.value, false); + break; + case replace: + path.patchAdd(object, op.value, true); + break; + case remove: + path.remove(object); + break; + case copy: + case move: + JSONPath from = JSONPath.compile(op.from); + Object fromValue = from.eval(object); + if (op.type == OperationType.move) { + boolean success = from.remove(object); + if (!success) { + throw new JSONException("json patch move error : " + op.from + " -> " + op.path); + } + } + path.set(object, fromValue); + break; + case test: + Object result = path.eval(object); + if (result == null) { + return op.value == null; + } + return result.equals(op.value); + default: + break; + } + } + + return object; + } + + private static boolean isObject(String patch) { + if (patch == null) { + return false; + } + + for (int i = 0; i < patch.length(); ++i) { + char ch = patch.charAt(i); + if (JSONScanner.isWhitespace(ch)) { + continue; + } + return ch == '{'; + } + + return false; + } + + @JSONType(orders = {"op", "from", "path", "value"}) + public static class Operation { + @JSONField(name = "op") + public OperationType type; + public String from; + public String path; + public Object value; + } + + public enum OperationType { + add, remove, replace, move, copy, test + } +} diff --git a/src/main/java/com/alibaba/fastjson/JSONPath.java b/src/main/java/com/alibaba/fastjson/JSONPath.java index aa8c96afa5..a8cc592d93 100644 --- a/src/main/java/com/alibaba/fastjson/JSONPath.java +++ b/src/main/java/com/alibaba/fastjson/JSONPath.java @@ -1,15 +1,10 @@ package com.alibaba.fastjson; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONLexerBase; +import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; @@ -21,6 +16,30 @@ import com.alibaba.fastjson.util.IOUtils; import com.alibaba.fastjson.util.TypeUtils; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * @author wenshao[szujobs@hotmail.com] * @since 1.2.0 @@ -29,16 +48,23 @@ public class JSONPath implements JSONAware { private static ConcurrentMap pathCache = new ConcurrentHashMap(128, 0.75f, 1); private final String path; - private Segement[] segments; + private Segment[] segments; + private boolean hasRefSegment; private SerializeConfig serializeConfig; private ParserConfig parserConfig; + private boolean ignoreNullValue; + public JSONPath(String path){ - this(path, SerializeConfig.getGlobalInstance(), ParserConfig.getGlobalInstance()); + this(path, SerializeConfig.getGlobalInstance(), ParserConfig.getGlobalInstance(), true); + } + + public JSONPath(String path, boolean ignoreNullValue){ + this(path, SerializeConfig.getGlobalInstance(), ParserConfig.getGlobalInstance(), ignoreNullValue); } - public JSONPath(String path, SerializeConfig serializeConfig, ParserConfig parserConfig){ + public JSONPath(String path, SerializeConfig serializeConfig, ParserConfig parserConfig, boolean ignoreNullValue){ if (path == null || path.length() == 0) { throw new JSONPathException("json-path can not be null or empty"); } @@ -46,6 +72,7 @@ public JSONPath(String path, SerializeConfig serializeConfig, ParserConfig parse this.path = path; this.serializeConfig = serializeConfig; this.parserConfig = parserConfig; + this.ignoreNullValue = ignoreNullValue; } protected void init() { @@ -54,10 +81,30 @@ protected void init() { } if ("*".equals(path)) { - this.segments = new Segement[] { WildCardSegement.instance }; + this.segments = new Segment[] { WildCardSegment.instance }; } else { JSONPathParser parser = new JSONPathParser(path); this.segments = parser.explain(); + this.hasRefSegment = parser.hasRefSegment; + } + } + + public boolean isRef() { + try { + init(); + for (int i = 0; i < segments.length; ++i) { + Segment segment = segments[i]; + Class segmentType = segment.getClass(); + if (segmentType == ArrayAccessSegment.class + || segmentType == PropertySegment.class) { + continue; + } + return false; + } + return true; + } catch (JSONPathException ex) { + // skip + return false; } } @@ -70,11 +117,115 @@ public Object eval(Object rootObject) { Object currentObject = rootObject; for (int i = 0; i < segments.length; ++i) { - Segement segement = segments[i]; - currentObject = segement.eval(this, rootObject, currentObject); + Segment segment = segments[i]; + currentObject = segment.eval(this, rootObject, currentObject); } return currentObject; } + + /** + * @since 1.2.76 + * @param rootObject + * @param clazz + * @param parserConfig + * @return + */ + public T eval(Object rootObject, Type clazz, ParserConfig parserConfig) { + Object obj = this.eval(rootObject); + return TypeUtils.cast(obj, clazz, parserConfig); + } + + /** + * @since 1.2.76 + * @param rootObject + * @param clazz + * @return + */ + public T eval(Object rootObject, Type clazz) { + return this.eval(rootObject, clazz, ParserConfig.getGlobalInstance()); + } + + public Object extract(DefaultJSONParser parser) { + if (parser == null) { + return null; + } + + init(); + + if (hasRefSegment) { + Object root = parser.parse(); + return this.eval(root); + } + + if (segments.length == 0) { + return parser.parse(); + } + + Segment lastSegment = segments[segments.length - 1]; + if (lastSegment instanceof TypeSegment + || lastSegment instanceof FloorSegment + || lastSegment instanceof MultiIndexSegment) { + return eval( + parser.parse()); + } + + Context context = null; + for (int i = 0; i < segments.length; ++i) { + Segment segment = segments[i]; + boolean last = i == segments.length - 1; + + if (context != null && context.object != null) { + context.object = segment.eval(this, null, context.object); + continue; + } + + boolean eval; + + if (!last) { + Segment nextSegment = segments[i + 1]; + if (segment instanceof PropertySegment + && ((PropertySegment) segment).deep + && (nextSegment instanceof ArrayAccessSegment + || nextSegment instanceof MultiIndexSegment + || nextSegment instanceof MultiPropertySegment + || nextSegment instanceof SizeSegment + || nextSegment instanceof PropertySegment + || nextSegment instanceof FilterSegment)) + { + eval = true; + } else if (nextSegment instanceof ArrayAccessSegment + && ((ArrayAccessSegment) nextSegment).index < 0) { + eval = true; + } else if (nextSegment instanceof FilterSegment) { + eval = true; + } else if (segment instanceof WildCardSegment) { + eval = true; + }else if(segment instanceof MultiIndexSegment){ + eval = true; + } else { + eval = false; + } + } else { + eval = true; + } + + context = new Context(context, eval); + segment.extract(this, parser, context); + } + + return context.object; + } + + private static class Context { + final Context parent; + final boolean eval; + Object object; + + public Context(Context parent, boolean eval) { + this.parent = parent; + this.eval = eval; + } + } public boolean contains(Object rootObject) { if (rootObject == null) { @@ -85,10 +236,15 @@ public boolean contains(Object rootObject) { Object currentObject = rootObject; for (int i = 0; i < segments.length; ++i) { + Object parentObject = currentObject; currentObject = segments[i].eval(this, rootObject, currentObject); if (currentObject == null) { return false; } + + if (currentObject == Collections.EMPTY_LIST && parentObject instanceof List) { + return ((List) parentObject).contains(currentObject); + } } return true; @@ -136,6 +292,93 @@ public int size(Object rootObject) { return evalSize(currentObject); } + /** + * Extract keySet or field names from rootObject on this JSONPath. + * + * @param rootObject Can be a map or custom object. Array and Collection are not supported. + * @return Set of keys, or null if not supported. + */ + public Set keySet(Object rootObject) { + if (rootObject == null) { + return null; + } + + init(); + + Object currentObject = rootObject; + for (int i = 0; i < segments.length; ++i) { + currentObject = segments[i].eval(this, rootObject, currentObject); + } + + return evalKeySet(currentObject); + } + + public void patchAdd(Object rootObject, Object value, boolean replace) { + if (rootObject == null) { + return; + } + + init(); + + Object currentObject = rootObject; + Object parentObject = null; + for (int i = 0; i < segments.length; ++i) { + parentObject = currentObject; + Segment segment = segments[i]; + currentObject = segment.eval(this, rootObject, currentObject); + if (currentObject == null && i != segments.length - 1) { + if (segment instanceof PropertySegment) { + currentObject = new JSONObject(); + ((PropertySegment) segment).setValue(this, parentObject, currentObject); + } + } + } + + Object result = currentObject; + + if ((!replace) && result instanceof Collection) { + Collection collection = (Collection) result; + collection.add(value); + return; + } + + Object newResult; + + if (result != null && !replace) { + Class resultClass = result.getClass(); + + if (resultClass.isArray()) { + int length = Array.getLength(result); + Object descArray = Array.newInstance(resultClass.getComponentType(), length + 1); + + System.arraycopy(result, 0, descArray, 0, length); + Array.set(descArray, length, value); + newResult = descArray; + } + else if (Map.class.isAssignableFrom(resultClass)) { + newResult = value; + } else { + throw new JSONException("unsupported array put operation. " + resultClass); + } + } else { + newResult = value; + } + + Segment lastSegment = segments[segments.length - 1]; + if (lastSegment instanceof PropertySegment) { + PropertySegment propertySegment = (PropertySegment) lastSegment; + propertySegment.setValue(this, parentObject, newResult); + return; + } + + if (lastSegment instanceof ArrayAccessSegment) { + ((ArrayAccessSegment) lastSegment).setValue(this, parentObject, newResult); + return; + } + + throw new UnsupportedOperationException(); + } + @SuppressWarnings({ "rawtypes", "unchecked" }) public void arrayAdd(Object rootObject, Object... values) { if (values == null || values.length == 0) { @@ -188,15 +431,15 @@ public void arrayAdd(Object rootObject, Object... values) { throw new JSONException("unsupported array put operation. " + resultClass); } - Segement lastSegement = segments[segments.length - 1]; - if (lastSegement instanceof PropertySegement) { - PropertySegement propertySegement = (PropertySegement) lastSegement; - propertySegement.setValue(this, parentObject, newResult); + Segment lastSegment = segments[segments.length - 1]; + if (lastSegment instanceof PropertySegment) { + PropertySegment propertySegment = (PropertySegment) lastSegment; + propertySegment.setValue(this, parentObject, newResult); return; } - if (lastSegement instanceof ArrayAccessSegement) { - ((ArrayAccessSegement) lastSegement).setValue(this, parentObject, newResult); + if (lastSegment instanceof ArrayAccessSegment) { + ((ArrayAccessSegment) lastSegment).setValue(this, parentObject, newResult); return; } @@ -212,12 +455,51 @@ public boolean remove(Object rootObject) { Object currentObject = rootObject; Object parentObject = null; + + Segment lastSegment = segments[segments.length - 1]; for (int i = 0; i < segments.length; ++i) { if (i == segments.length - 1) { parentObject = currentObject; break; } - currentObject = segments[i].eval(this, rootObject, currentObject); + Segment segement = segments[i]; + if (i == segments.length - 2 + && lastSegment instanceof FilterSegment + && segement instanceof PropertySegment + ) { + FilterSegment filterSegment = (FilterSegment) lastSegment; + + if (currentObject instanceof List) { + PropertySegment propertySegment = (PropertySegment) segement; + List list = (List) currentObject; + + for (Iterator it = list.iterator();it.hasNext();) { + Object item = it.next(); + Object result = propertySegment.eval(this, rootObject, item); + if (result instanceof Iterable) { + filterSegment.remove(this, rootObject, result); + } else if (result instanceof Map) { + if (filterSegment.filter.apply(this, rootObject, currentObject, result)) { + it.remove(); + } + } + } + return true; + } else if (currentObject instanceof Map) { + PropertySegment propertySegment = (PropertySegment) segement; + Object result = propertySegment.eval(this, rootObject, currentObject); + if (result == null) { + return false; + } + if (result instanceof Map + && filterSegment.filter.apply(this, rootObject, currentObject, result)) { + propertySegment.remove(this, currentObject); + return true; + } + } + } + + currentObject = segement.eval(this, rootObject, currentObject); if (currentObject == null) { break; } @@ -227,18 +509,18 @@ public boolean remove(Object rootObject) { return false; } - Segement lastSegement = segments[segments.length - 1]; - if (lastSegement instanceof PropertySegement) { - PropertySegement propertySegement = (PropertySegement) lastSegement; + + if (lastSegment instanceof PropertySegment) { + PropertySegment propertySegment = (PropertySegment) lastSegment; if (parentObject instanceof Collection) { if (segments.length > 1) { - Segement parentSegement = segments[segments.length - 2]; - if (parentSegement instanceof RangeSegement || parentSegement instanceof MultiIndexSegement) { + Segment parentSegment = segments[segments.length - 2]; + if (parentSegment instanceof RangeSegment || parentSegment instanceof MultiIndexSegment) { Collection collection = (Collection) parentObject; boolean removedOnce = false; for (Object item : collection) { - boolean removed = propertySegement.remove(this, item); + boolean removed = propertySegment.remove(this, item); if (removed) { removedOnce = true; } @@ -247,11 +529,16 @@ public boolean remove(Object rootObject) { } } } - return propertySegement.remove(this, parentObject); + return propertySegment.remove(this, parentObject); + } + + if (lastSegment instanceof ArrayAccessSegment) { + return ((ArrayAccessSegment) lastSegment).remove(this, parentObject); } - if (lastSegement instanceof ArrayAccessSegement) { - return ((ArrayAccessSegement) lastSegement).remove(this, parentObject); + if (lastSegment instanceof FilterSegment) { + FilterSegment filterSegment = (FilterSegment) lastSegment; + return filterSegment.remove(this, rootObject, parentObject); } throw new UnsupportedOperationException(); @@ -277,20 +564,20 @@ public boolean set(Object rootObject, Object value, boolean p) { // } // parentObject = currentObject; - Segement segment = segments[i]; + Segment segment = segments[i]; currentObject = segment.eval(this, rootObject, currentObject); if (currentObject == null) { - Segement nextSegement = null; + Segment nextSegment = null; if (i < segments.length - 1) { - nextSegement = segments[i + 1]; + nextSegment = segments[i + 1]; } Object newObj = null; - if (nextSegement instanceof PropertySegement) { + if (nextSegment instanceof PropertySegment) { JavaBeanDeserializer beanDeserializer = null; Class fieldClass = null; - if (segment instanceof PropertySegement) { - String propertyName = ((PropertySegement) segment).propertyName; + if (segment instanceof PropertySegment) { + String propertyName = ((PropertySegment) segment).propertyName; Class parentClass = parentObject.getClass(); JavaBeanDeserializer parentBeanDeserializer = getJavaBeanDeserializer(parentClass); if (parentBeanDeserializer != null) { @@ -310,18 +597,18 @@ public boolean set(Object rootObject, Object value, boolean p) { } else { newObj = new JSONObject(); } - } else if (nextSegement instanceof ArrayAccessSegement) { + } else if (nextSegment instanceof ArrayAccessSegment) { newObj = new JSONArray(); } if (newObj != null) { - if (segment instanceof PropertySegement) { - PropertySegement propSegement = (PropertySegement) segment; + if (segment instanceof PropertySegment) { + PropertySegment propSegement = (PropertySegment) segment; propSegement.setValue(this, parentObject, newObj); currentObject = newObj; continue; - } else if (segment instanceof ArrayAccessSegement) { - ArrayAccessSegement arrayAccessSegement = (ArrayAccessSegement) segment; + } else if (segment instanceof ArrayAccessSegment) { + ArrayAccessSegment arrayAccessSegement = (ArrayAccessSegment) segment; arrayAccessSegement.setValue(this, parentObject, newObj); currentObject = newObj; continue; @@ -336,15 +623,15 @@ public boolean set(Object rootObject, Object value, boolean p) { return false; } - Segement lastSegement = segments[segments.length - 1]; - if (lastSegement instanceof PropertySegement) { - PropertySegement propertySegement = (PropertySegement) lastSegement; - propertySegement.setValue(this, parentObject, value); + Segment lastSegment = segments[segments.length - 1]; + if (lastSegment instanceof PropertySegment) { + PropertySegment propertySegment = (PropertySegment) lastSegment; + propertySegment.setValue(this, parentObject, value); return true; } - if (lastSegement instanceof ArrayAccessSegement) { - return ((ArrayAccessSegement) lastSegement).setValue(this, parentObject, value); + if (lastSegment instanceof ArrayAccessSegment) { + return ((ArrayAccessSegment) lastSegment).setValue(this, parentObject, value); } throw new UnsupportedOperationException(); @@ -355,12 +642,30 @@ public static Object eval(Object rootObject, String path) { return jsonpath.eval(rootObject); } + public static Object eval(Object rootObject, String path, boolean ignoreNullValue) { + JSONPath jsonpath = compile(path, ignoreNullValue); + return jsonpath.eval(rootObject); + } + public static int size(Object rootObject, String path) { JSONPath jsonpath = compile(path); Object result = jsonpath.eval(rootObject); return jsonpath.evalSize(result); } + /** + * Compile jsonPath and use it to extract keySet or field names from rootObject. + * + * @param rootObject Can be a map or custom object. Array and Collection are not supported. + * @param path JSONPath string to be compiled. + * @return Set of keys, or null if not supported. + */ + public static Set keySet(Object rootObject, String path) { + JSONPath jsonpath = compile(path); + Object result = jsonpath.eval(rootObject); + return jsonpath.evalKeySet(result); + } + public static boolean contains(Object rootObject, String path) { if (rootObject == null) { return false; @@ -405,7 +710,23 @@ public static JSONPath compile(String path) { } return jsonpath; } - + + public static JSONPath compile(String path, boolean ignoreNullValue) { + if (path == null) { + throw new JSONPathException("jsonpath can not be null"); + } + + JSONPath jsonpath = pathCache.get(path); + if (jsonpath == null) { + jsonpath = new JSONPath(path, ignoreNullValue); + if (pathCache.size() < 1024) { + pathCache.putIfAbsent(path, jsonpath); + jsonpath = pathCache.get(path); + } + } + return jsonpath; + } + /** * @since 1.2.9 * @param json @@ -413,11 +734,54 @@ public static JSONPath compile(String path) { * @return */ public static Object read(String json, String path) { - Object object = JSON.parse(json); - JSONPath jsonpath = compile(path); - return jsonpath.eval(object); + return compile(path) + .eval( + JSON.parse(json) + ); + } + + /** + * @since 1.2.76 + * @param json + * @param path + * @param clazz + * @param parserConfig + * @return + */ + public static T read(String json, String path, Type clazz, ParserConfig parserConfig) { + return compile(path).eval(JSON.parse(json), clazz, parserConfig); } + /** + * @since 1.2.76 + * @param json + * @param path + * @param clazz + * @return + */ + public static T read(String json, String path, Type clazz) { + return read(json, path, clazz, null); + } + + /** + * @since 1.2.51 + * @param json + * @param path + * @return + */ + public static Object extract(String json, String path, ParserConfig config, int features, Feature... optionFeatures) { + features |= Feature.OrderedField.mask; + DefaultJSONParser parser = new DefaultJSONParser(json, config, features); + JSONPath jsonPath = compile(path); + Object result = jsonPath.extract(parser); + parser.lexer.close(); + return result; + } + + public static Object extract(String json, String path) { + return extract(json, path, ParserConfig.global, JSON.DEFAULT_PARSER_FEATURE); + } + public static Map paths(Object javaObject) { return paths(javaObject, SerializeConfig.globalInstance); } @@ -437,10 +801,15 @@ private static void paths(Map values, Map paths, String p = values.put(javaObject, parent); if (p != null) { - boolean basicType = javaObject instanceof String + Class type = javaObject.getClass(); + boolean basicType = type == String.class + || type == Boolean.class + || type == Character.class + || type == UUID.class + || type.isEnum() || javaObject instanceof Number || javaObject instanceof Date - || javaObject instanceof UUID; + ; if (!basicType) { return; @@ -519,119 +888,44 @@ private static void paths(Map values, Map paths, return; } - @SuppressWarnings("rawtypes") - private static void paths(Map paths, String parent, Object javaObject, SerializeConfig config) { - if (javaObject == null) { - return; - } - - if (paths.containsKey(javaObject)) { - return; - } - - paths.put(javaObject, parent); - - if (javaObject instanceof Map) { - Map map = (Map) javaObject; + public String getPath() { + return path; + } - for (Object entryObj : map.entrySet()) { - Map.Entry entry = (Map.Entry) entryObj; - Object key = entry.getKey(); - - if (key instanceof String) { - String path = parent.equals("/") ? "/" + key : parent + "/" + key; - paths(paths, path, entry.getValue(), config); - } - } - return; - } + static class JSONPathParser { - if (javaObject instanceof Collection) { - Collection collection = (Collection) javaObject; + private final String path; + private int pos; + private char ch; + private int level; + private boolean hasRefSegment; + private static final String strArrayRegex = "\'\\s*,\\s*\'"; + private static final Pattern strArrayPatternx = Pattern.compile(strArrayRegex); - int i = 0; - for (Object item : collection) { - String path = parent.equals("/") ? "/" + i : parent + "/" + i; - paths(paths, path, item, config); - ++i; - } - - return; + public JSONPathParser(String path){ + this.path = path; + next(); } - Class clazz = javaObject.getClass(); - - if (clazz.isArray()) { - int len = Array.getLength(javaObject); + void next() { + ch = path.charAt(pos++); + } - for (int i = 0; i < len; ++i) { - Object item = Array.get(javaObject, i); - - String path = parent.equals("/") ? "/" + i : parent + "/" + i; - paths(paths, path, item, config); - } - - return; + char getNextChar() { + return path.charAt(pos); } - if (ParserConfig.isPrimitive2(clazz) || clazz.isEnum()) { - return; + boolean isEOF() { + return pos >= path.length(); } - ObjectSerializer serializer = config.getObjectWriter(clazz); - if (serializer instanceof JavaBeanSerializer) { - JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer) serializer; - - try { - Map fieldValues = javaBeanSerializer.getFieldValuesMap(javaObject); - for (Map.Entry entry : fieldValues.entrySet()) { - String key = entry.getKey(); - - if (key instanceof String) { - String path = parent.equals("/") ? "/" + key : parent + "/" + key; - paths(paths, path, entry.getValue(), config); - } - } - } catch (Exception e) { - throw new JSONException("toJSON error", e); - } - return; - } - - return; - } - - public String getPath() { - return path; - } - - static class JSONPathParser { - - private final String path; - private int pos; - private char ch; - private int level; - - public JSONPathParser(String path){ - this.path = path; - next(); - } - - void next() { - ch = path.charAt(pos++); - } - - boolean isEOF() { - return pos >= path.length(); - } - - Segement readSegement() { + Segment readSegement() { if (level == 0 && path.length() == 1) { if (isDigitFirst(ch)) { int index = ch - '0'; - return new ArrayAccessSegement(index); + return new ArrayAccessSegment(index); } else if ((ch >= 'a' && ch <= 'z') || ((ch >= 'A' && ch <= 'Z'))) { - return new PropertySegement(Character.toString(ch), false); + return new PropertySegment(Character.toString(ch), false); } } while (!isEOF()) { @@ -639,6 +933,11 @@ Segement readSegement() { if (ch == '$') { next(); + skipWhitespace(); + if (ch == '?') { + return new FilterSegment( + (Filter) parseArrayAccessFilter(false)); + } continue; } @@ -660,12 +959,21 @@ Segement readSegement() { next(); } } - if (ch == '*') { + if (ch == '*' || (deep && ch == '[')) { + boolean objectOnly = ch == '['; if (!isEOF()) { next(); } - return WildCardSegement.instance; + if (deep) { + if (objectOnly) { + return WildCardSegment.instance_deep_objectOnly; + } else { + return WildCardSegment.instance_deep; + } + } else { + return WildCardSegment.instance; + } } if (isDigitFirst(ch)) { @@ -680,8 +988,18 @@ Segement readSegement() { next(); } - if ("size".equals(propertyName)) { - return SizeSegement.instance; + if ("size".equals(propertyName) || "length".equals(propertyName)) { + return SizeSegment.instance; + } else if ("max".equals(propertyName)) { + return MaxSegment.instance; + } else if ("min".equals(propertyName)) { + return MinSegment.instance; + } else if ("keySet".equals(propertyName)) { + return KeySetSegment.instance; + } else if ("type".equals(propertyName)) { + return TypeSegment.instance; + } else if ("floor".equals(propertyName)) { + return FloorSegment.instance; } throw new JSONPathException("not support jsonpath : " + path); @@ -690,7 +1008,7 @@ Segement readSegement() { throw new JSONPathException("not support jsonpath : " + path); } - return new PropertySegement(propertyName, deep); + return new PropertySegment(propertyName, deep); } if (ch == '[') { @@ -700,7 +1018,12 @@ Segement readSegement() { if (level == 0) { String propertyName = readName(); - return new PropertySegement(propertyName, false); + return new PropertySegment(propertyName, false); + } + + if (ch == '?') { + return new FilterSegment( + (Filter) parseArrayAccessFilter(false)); } throw new JSONPathException("not support jsonpath : " + path); @@ -720,41 +1043,103 @@ public final void skipWhitespace() { } } - Segement parseArrayAccess(boolean acceptBracket) { + Segment parseArrayAccess(boolean acceptBracket) { + Object object = parseArrayAccessFilter(acceptBracket); + if (object instanceof Segment) { + return ((Segment) object); + } + return new FilterSegment((Filter) object); + } + + Object parseArrayAccessFilter(boolean acceptBracket) { if (acceptBracket) { accept('['); } boolean predicateFlag = false; + int lparanCount = 0; if (ch == '?') { next(); accept('('); - if (ch == '@') { + lparanCount++; + while (ch == '(') { next(); - accept('.'); + lparanCount++; } - predicateFlag = true; } - if (predicateFlag || IOUtils.firstIdentifier(ch)) { + skipWhitespace(); + + if (predicateFlag + || IOUtils.firstIdentifier(ch) + || Character.isJavaIdentifierStart(ch) + || ch == '\\' + || ch == '@') { + boolean self = false; + if (ch == '@') { + next(); + accept('.'); + self = true; + } String propertyName = readName(); skipWhitespace(); if (predicateFlag && ch == ')') { next(); + + Filter filter = new NotNullSegement(propertyName, false); + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + if (acceptBracket) { accept(']'); } - - return new FilterSegement(new NotNullSegement(propertyName)); + return filter; } if (acceptBracket && ch == ']') { + if (isEOF()) { + if (propertyName.equals("last")) { + return new MultiIndexSegment(new int[]{-1}); + } + } + + next(); + Filter filter = new NotNullSegement(propertyName, false); + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); + } + return filter; + } + + boolean function = false; + skipWhitespace(); + if (ch == '(') { next(); - return new FilterSegement(new NotNullSegement(propertyName)); + accept(')'); + skipWhitespace(); + function = true; } Operator op = readOp(); @@ -779,9 +1164,12 @@ Segement parseArrayAccess(boolean acceptBracket) { } if (isInt(startValue.getClass()) && isInt(endValue.getClass())) { - Filter filter = new IntBetweenSegement(propertyName, ((Number) startValue).longValue(), - ((Number) endValue).longValue(), not); - return new FilterSegement(filter); + Filter filter = new IntBetweenSegement(propertyName + , function + , TypeUtils.longExtractValue((Number) startValue) + , TypeUtils.longExtractValue((Number) endValue) + , not); + return filter; } throw new JSONPathException(path); @@ -806,15 +1194,6 @@ Segement parseArrayAccess(boolean acceptBracket) { value = readValue(); valueList.add(value); } - - accept(')'); - if (predicateFlag) { - accept(')'); - } - - if (acceptBracket) { - accept(']'); - } } boolean isInt = true; @@ -841,26 +1220,83 @@ Segement parseArrayAccess(boolean acceptBracket) { } if (valueList.size() == 1 && valueList.get(0) == null) { + Filter filter; if (not) { - return new FilterSegement(new NotNullSegement(propertyName)); + filter = new NotNullSegement(propertyName, function); } else { - return new FilterSegement(new NullSegement(propertyName)); + filter = new NullSegement(propertyName, function); + } + + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); } + + return filter; } if (isInt) { if (valueList.size() == 1) { - long value = ((Number) valueList.get(0)).longValue(); + long value = TypeUtils.longExtractValue((Number) valueList.get(0)); Operator intOp = not ? Operator.NE : Operator.EQ; - return new FilterSegement(new IntOpSegement(propertyName, value, intOp)); + Filter filter = new IntOpSegement(propertyName, function, value, intOp); + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); + } + + return filter; } long[] values = new long[valueList.size()]; for (int i = 0; i < values.length; ++i) { - values[i] = ((Number) valueList.get(i)).longValue(); + values[i] = TypeUtils.longExtractValue((Number) valueList.get(i)); + } + + Filter filter = new IntInSegement(propertyName, function, values, not); + + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); } - return new FilterSegement(new IntInSegement(propertyName, values, not)); + return filter; } if (isString) { @@ -868,13 +1304,51 @@ Segement parseArrayAccess(boolean acceptBracket) { String value = (String) valueList.get(0); Operator intOp = not ? Operator.NE : Operator.EQ; - return new FilterSegement(new StringOpSegement(propertyName, value, intOp)); + Filter filter = new StringOpSegement(propertyName, function, value, intOp); + + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); + } + + return filter; } String[] values = new String[valueList.size()]; valueList.toArray(values); - return new FilterSegement(new StringInSegement(propertyName, values, not)); + Filter filter = new StringInSegement(propertyName, function, values, not); + + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); + } + + return filter; } if (isIntObj) { @@ -882,11 +1356,30 @@ Segement parseArrayAccess(boolean acceptBracket) { for (int i = 0; i < values.length; ++i) { Number item = (Number) valueList.get(i); if (item != null) { - values[i] = item.longValue(); + values[i] = TypeUtils.longExtractValue(item); } } - return new FilterSegement(new IntObjInSegement(propertyName, values, not)); + Filter filter = new IntObjInSegement(propertyName, function, values, not); + + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); + } + + return filter; } throw new UnsupportedOperationException(); @@ -894,23 +1387,13 @@ Segement parseArrayAccess(boolean acceptBracket) { if (ch == '\'' || ch == '"') { String strValue = readString(); - if (predicateFlag) { - accept(')'); - } - - if (acceptBracket) { - accept(']'); - } + Filter filter = null; if (op == Operator.RLIKE) { - return new FilterSegement(new RlikeSegement(propertyName, strValue, false)); - } - - if (op == Operator.NOT_RLIKE) { - return new FilterSegement(new RlikeSegement(propertyName, strValue, true)); - } - - if (op == Operator.LIKE || op == Operator.NOT_LIKE) { + filter = new RlikeSegement(propertyName, function, strValue, false); + } else if (op == Operator.NOT_RLIKE) { + filter = new RlikeSegement(propertyName, function, strValue, true); + } else if (op == Operator.LIKE || op == Operator.NOT_LIKE) { while (strValue.indexOf("%%") != -1) { strValue = strValue.replaceAll("%%", "%"); } @@ -924,6 +1407,7 @@ Segement parseArrayAccess(boolean acceptBracket) { } else { op = Operator.NE; } + filter = new StringOpSegement(propertyName, function, strValue, op); } else { String[] items = strValue.split("%"); @@ -942,7 +1426,11 @@ Segement parseArrayAccess(boolean acceptBracket) { } } } else if (strValue.charAt(strValue.length() - 1) == '%') { - containsValues = items; + if (items.length == 1) { + startsWithValue = items[0]; + } else { + containsValues = items; + } } else { if (items.length == 1) { startsWithValue = items[0]; @@ -957,13 +1445,30 @@ Segement parseArrayAccess(boolean acceptBracket) { } } - return new FilterSegement(new MatchSegement(propertyName, startsWithValue, endsWithValue, - containsValues, not)); - + filter = new MatchSegement(propertyName, function, startsWithValue, endsWithValue, + containsValues, not); } + } else { + filter = new StringOpSegement(propertyName, function, strValue, op); + } + + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { + accept(']'); } - return new FilterSegement(new StringOpSegement(propertyName, strValue, op)); + return filter; } if (isDigitFirst(ch)) { @@ -974,54 +1479,150 @@ Segement parseArrayAccess(boolean acceptBracket) { } + Filter filter; + + if (doubleValue == 0) { + filter = new IntOpSegement(propertyName, function, value, op); + } else { + filter = new DoubleOpSegement(propertyName, function, doubleValue, op); + } + + while (ch == ' ') { + next(); + } + + if (lparanCount > 1 && ch == ')') { + next(); + lparanCount--; + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + if (predicateFlag) { + lparanCount--; accept(')'); } - + if (acceptBracket) { accept(']'); } - if (doubleValue == 0) { - return new FilterSegement(new IntOpSegement(propertyName, value, op)); - } else { - return new FilterSegement(new DoubleOpSegement(propertyName, doubleValue, op)); + return filter; + } else if (ch == '$') { + Segment segment = readSegement(); + RefOpSegement filter = new RefOpSegement(propertyName, function, segment, op); + hasRefSegment = true; + while (ch == ' ') { + next(); } - } - if (ch == 'n') { - String name = readName(); - if ("null".equals(name)) { - if (predicateFlag) { - accept(')'); - } + if (predicateFlag) { + accept(')'); + } + + if (acceptBracket) { accept(']'); + } - if (op == Operator.EQ) { - return new FilterSegement(new NullSegement(propertyName)); + return filter; + } else if (ch == '/') { + int flags = 0; + StringBuilder regBuf = new StringBuilder(); + for (;;) { + next(); + if (ch == '/') { + next(); + if (ch == 'i') { + next(); + flags |= Pattern.CASE_INSENSITIVE; + } + break; } - if (op == Operator.NE) { - return new FilterSegement(new NotNullSegement(propertyName)); + if (ch == '\\') { + next(); + regBuf.append(ch); + } else { + regBuf.append(ch); } + } - throw new UnsupportedOperationException(); + Pattern pattern = Pattern.compile(regBuf.toString(), flags); + RegMatchSegement filter = new RegMatchSegement(propertyName, function, pattern, op); + + if (predicateFlag) { + accept(')'); } - } else if (ch == 't') { - String name = readName(); - - if ("true".equals(name)) { + + if (acceptBracket) { + accept(']'); + } + + return filter; + } + + if (ch == 'n') { + String name = readName(); + if ("null".equals(name)) { + Filter filter = null; + if (op == Operator.EQ) { + filter = new NullSegement(propertyName, function); + } else if (op == Operator.NE) { + filter = new NotNullSegement(propertyName, function); + } + + if (filter != null) { + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + } + if (predicateFlag) { accept(')'); } accept(']'); + if (filter != null) { + return filter; + } + + throw new UnsupportedOperationException(); + } + } else if (ch == 't') { + String name = readName(); + + if ("true".equals(name)) { + Filter filter = null; + if (op == Operator.EQ) { - return new FilterSegement(new ValueSegment(propertyName, Boolean.TRUE, true)); + filter = new ValueSegment(propertyName, function, Boolean.TRUE, true); + } else if (op == Operator.NE) { + filter = new ValueSegment(propertyName, function, Boolean.TRUE, false); } - if (op == Operator.NE) { - return new FilterSegement(new ValueSegment(propertyName, Boolean.TRUE, false)); + if (filter != null) { + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + } + + if (predicateFlag) { + accept(')'); + } + accept(']'); + + if (filter != null) { + return filter; } throw new UnsupportedOperationException(); @@ -1030,17 +1631,31 @@ Segement parseArrayAccess(boolean acceptBracket) { String name = readName(); if ("false".equals(name)) { + Filter filter = null; + + if (op == Operator.EQ) { + filter = new ValueSegment(propertyName, function, Boolean.FALSE, true); + } else if (op == Operator.NE) { + filter = new ValueSegment(propertyName, function, Boolean.FALSE, false); + } + + if (filter != null) { + while (ch == ' ') { + next(); + } + + if (ch == '&' || ch == '|') { + filter = filterRest(filter); + } + } + if (predicateFlag) { accept(')'); } accept(']'); - if (op == Operator.EQ) { - return new FilterSegement(new ValueSegment(propertyName, Boolean.FALSE, true)); - } - - if (op == Operator.NE) { - return new FilterSegement(new ValueSegment(propertyName, Boolean.FALSE, false)); + if (filter != null) { + return filter; } throw new UnsupportedOperationException(); @@ -1052,10 +1667,13 @@ Segement parseArrayAccess(boolean acceptBracket) { } int start = pos - 1; + char startCh = ch; while (ch != ']' && ch != '/' && !isEOF()) { if (ch == '.' // && (!predicateFlag) // - && !predicateFlag) { + && !predicateFlag + && startCh != '\'' + ) { break; } @@ -1077,13 +1695,44 @@ Segement parseArrayAccess(boolean acceptBracket) { } String text = path.substring(start, end); + + if (text.indexOf('\\') != 0) { + StringBuilder buf = new StringBuilder(text.length()); + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch == '\\' && i < text.length() - 1) { + char c2 = text.charAt(i + 1); + if (c2 == '@' || ch == '\\' || ch == '\"') { + buf.append(c2); + i++; + continue; + } + } + + buf.append(ch); + } + text = buf.toString(); + } if (text.indexOf("\\.") != -1) { - String propName = text.replaceAll("\\\\\\.","\\."); - return new PropertySegement(propName, false); + String propName; + if (startCh == '\'' && text.length() > 2 && text.charAt(text.length() - 1) == startCh) { + propName = text.substring(1, text.length() - 1); + } else { + propName = text.replaceAll("\\\\\\.", "\\."); + if (propName.indexOf("\\-") != -1) { + propName = propName.replaceAll("\\\\-", "-"); + } + } + + if (predicateFlag) { + accept(')'); + } + + return new PropertySegment(propName, false); } - Segement segment = buildArraySegement(text); + Segment segment = buildArraySegement(text); if (acceptBracket && !isEOF()) { accept(']'); @@ -1092,6 +1741,33 @@ Segement parseArrayAccess(boolean acceptBracket) { return segment; } + Filter filterRest(Filter filter) { + boolean and = ch == '&'; + if ((ch == '&' && getNextChar() == '&') || (ch == '|' && getNextChar() == '|')) { + next(); + next(); + + boolean paren = false; + if (ch == '(') { + paren = true; + next(); + } + + while (ch == ' ') { + next(); + } + + Filter right = (Filter) parseArrayAccessFilter(false); + + filter = new FilterGroup(filter, right, and); + + if (paren && ch == ')') { + next(); + } + } + return filter; + } + protected long readLongValue() { int beginIndex = pos - 1; if (ch == '+' || ch == '-') { @@ -1155,7 +1831,15 @@ protected Operator readOp() { Operator op = null; if (ch == '=') { next(); - op = Operator.EQ; + if (ch == '~') { + next(); + op = Operator.REG_MATCH; + } else if (ch == '=') { + next(); + op = Operator.EQ; + } else { + op = Operator.EQ; + } } else if (ch == '!') { next(); accept('='); @@ -1197,6 +1881,8 @@ protected Operator readOp() { } else { throw new UnsupportedOperationException(); } + } else if ("nin".equalsIgnoreCase(name)) { + op = Operator.NOT_IN; } else { if ("like".equalsIgnoreCase(name)) { op = Operator.LIKE; @@ -1217,7 +1903,7 @@ protected Operator readOp() { String readName() { skipWhitespace(); - if (ch != '\\' && !IOUtils.firstIdentifier(ch)) { + if (ch != '\\' && !Character.isJavaIdentifierStart(ch)) { throw new JSONPathException("illeal jsonpath syntax. " + path); } @@ -1227,13 +1913,13 @@ String readName() { next(); buf.append(ch); if (isEOF()) { - break; + return buf.toString(); } next(); continue; } - boolean identifierFlag = IOUtils.isIdent(ch); + boolean identifierFlag = Character.isJavaIdentifierPart(ch); if (!identifierFlag) { break; } @@ -1241,13 +1927,11 @@ String readName() { next(); } - if (isEOF() && IOUtils.isIdent(ch)) { + if (isEOF() && Character.isJavaIdentifierPart(ch)) { buf.append(ch); } - String propertyName = buf.toString(); - - return propertyName; + return buf.toString(); } String readString() { @@ -1267,6 +1951,10 @@ String readString() { } void accept(char expect) { + if (ch == ' ') { + next(); + } + if (ch != expect) { throw new JSONPathException("expect '" + expect + ", but '" + ch + "'"); } @@ -1276,37 +1964,44 @@ void accept(char expect) { } } - public Segement[] explain() { + public Segment[] explain() { if (path == null || path.length() == 0) { throw new IllegalArgumentException(); } - Segement[] segements = new Segement[8]; + Segment[] segments = new Segment[8]; for (;;) { - Segement segment = readSegement(); + Segment segment = readSegement(); if (segment == null) { break; } - - if (level == segements.length) { - Segement[] t = new Segement[level * 3 / 2]; - System.arraycopy(segements, 0, t, 0, level); - segements = t; + + if (segment instanceof PropertySegment) { + PropertySegment propertySegment = (PropertySegment) segment; + if ((!propertySegment.deep) && propertySegment.propertyName.equals("*")) { + continue; + } } - segements[level++] = segment; + + if (level == segments.length) { + Segment[] t = new Segment[level * 3 / 2]; + System.arraycopy(segments, 0, t, 0, level); + segments = t; + } + segments[level++] = segment; } - if (level == segements.length) { - return segements; + if (level == segments.length) { + return segments; } - Segement[] result = new Segement[level]; - System.arraycopy(segements, 0, result, 0, level); + Segment[] result = new Segment[level]; + System.arraycopy(segments, 0, result, 0, level); return result; } - Segement buildArraySegement(String indexText) { + Segment buildArraySegement(String indexText) { final int indexTextLen = indexText.length(); final char firstChar = indexText.charAt(0); final char lastChar = indexText.charAt(indexTextLen - 1); @@ -1315,19 +2010,14 @@ Segement buildArraySegement(String indexText) { if (indexText.length() > 2 && firstChar == '\'' && lastChar == '\'') { - if (commaIndex == -1) { - String propertyName = indexText.substring(1, indexTextLen - 1); - return new PropertySegement(propertyName, false); - } + String propertyName = indexText.substring(1, indexTextLen - 1); - String[] indexesText = indexText.split(","); - String[] propertyNames = new String[indexesText.length]; - for (int i = 0; i < indexesText.length; ++i) { - String indexesTextItem = indexesText[i]; - propertyNames[i] = indexesTextItem.substring(1, indexesTextItem.length() - 1); + if (commaIndex == -1 || !strArrayPatternx.matcher(indexText).find()) { + return new PropertySegment(propertyName, false); } - return new MultiPropertySegement(propertyNames); + String[] propertyNames = propertyName.split(strArrayRegex); + return new MultiPropertySegment(propertyNames); } int colonIndex = indexText.indexOf(':'); @@ -1336,12 +2026,15 @@ Segement buildArraySegement(String indexText) { if (TypeUtils.isNumber(indexText)) { try { int index = Integer.parseInt(indexText); - return new ArrayAccessSegement(index); + return new ArrayAccessSegment(index); }catch (NumberFormatException ex){ - return new PropertySegement(indexText, false); // fix ISSUE-1208 + return new PropertySegment(indexText, false); // fix ISSUE-1208 } } else { - return new PropertySegement(indexText, false); + if (indexText.charAt(0) == '"' && indexText.charAt(indexText.length() - 1) == '"') { + indexText = indexText.substring(1, indexText.length() - 1); + } + return new PropertySegment(indexText, false); } } @@ -1351,7 +2044,7 @@ Segement buildArraySegement(String indexText) { for (int i = 0; i < indexesText.length; ++i) { indexes[i] = Integer.parseInt(indexesText[i]); } - return new MultiIndexSegement(indexes); + return new MultiIndexSegment(indexes); } if (colonIndex != -1) { @@ -1392,35 +2085,260 @@ Segement buildArraySegement(String indexText) { if (step <= 0) { throw new UnsupportedOperationException("step must greater than zero : " + step); } - return new RangeSegement(start, end, step); + return new RangeSegment(start, end, step); } throw new UnsupportedOperationException(); } } - interface Segement { + interface Segment { Object eval(JSONPath path, Object rootObject, Object currentObject); + void extract(JSONPath path, DefaultJSONParser parser, Context context); } - static class SizeSegement implements Segement { - - public final static SizeSegement instance = new SizeSegement(); - + static class SizeSegment implements Segment { + public final static SizeSegment instance = new SizeSegment(); public Integer eval(JSONPath path, Object rootObject, Object currentObject) { return path.evalSize(currentObject); } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + Object object = parser.parse(); + context.object = path.evalSize(object); + } + } + + static class TypeSegment implements Segment { + public final static TypeSegment instance = new TypeSegment(); + + public String eval(JSONPath path, Object rootObject, Object currentObject) { + if (currentObject == null) { + return "null"; + } + + if (currentObject instanceof Collection) { + return "array"; + } + + if (currentObject instanceof Number) { + return "number"; + } + + if (currentObject instanceof Boolean) { + return "boolean"; + } + + if (currentObject instanceof String + || currentObject instanceof UUID + || currentObject instanceof Enum) { + return "string"; + } + + return "object"; + } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + throw new UnsupportedOperationException(); + } + } + + static class FloorSegment implements Segment { + public final static FloorSegment instance = new FloorSegment(); + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + if (currentObject instanceof JSONArray) { + JSONArray array = ((JSONArray) ((JSONArray) currentObject).clone()); + for (int i = 0; i < array.size(); i++) { + Object item = array.get(i); + Object newItem = floor(item); + if (newItem != item) { + array.set(i , newItem); + } + } + return array; + } + + return floor(currentObject); + } + + private static Object floor(Object item) { + if (item == null) { + return null; + } + + if (item instanceof Float) { + return Math.floor((Float) item); + } + + if (item instanceof Double) { + return Math.floor((Double) item); + } + + if (item instanceof BigDecimal) { + BigDecimal decimal = (BigDecimal) item; + return decimal.setScale(0, RoundingMode.FLOOR); + } + + if (item instanceof Byte + || item instanceof Short + || item instanceof Integer + || item instanceof Long + || item instanceof BigInteger) { + return item; + } + + throw new UnsupportedOperationException(); + } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + throw new UnsupportedOperationException(); + } } - static class PropertySegement implements Segement { + static class MaxSegment implements Segment { + + public final static MaxSegment instance = new MaxSegment(); + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + Object max = null; + if (currentObject instanceof Collection) { + Iterator iterator = ((Collection) currentObject).iterator(); + while (iterator.hasNext()) { + Object next = iterator.next(); + if (next == null) { + continue; + } + + if (max == null) { + max = next; + } else if (compare(max, next) < 0) { + max = next; + } + } + } else { + throw new UnsupportedOperationException(); + } + + return max; + } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + throw new UnsupportedOperationException(); + } + } + + static class MinSegment implements Segment { + public final static MinSegment instance = new MinSegment(); + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + Object min = null; + if (currentObject instanceof Collection) { + Iterator iterator = ((Collection) currentObject).iterator(); + while (iterator.hasNext()) { + Object next = iterator.next(); + if (next == null) { + continue; + } + + if (min == null) { + min = next; + } else if (compare(min, next) > 0) { + min = next; + } + } + } else { + throw new UnsupportedOperationException(); + } + + return min; + } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + throw new UnsupportedOperationException(); + } + } + + static int compare(Object a, Object b) { + if (a.getClass() == b.getClass()) { + return ((Comparable) a).compareTo(b); + } + + Class typeA = a.getClass(); + Class typeB = b.getClass(); + + if (typeA == BigDecimal.class) { + if (typeB == Integer.class) { + b = new BigDecimal((Integer) b); + } else if (typeB == Long.class) { + b = new BigDecimal((Long) b); + } else if (typeB == Float.class) { + b = new BigDecimal((Float) b); + } else if (typeB == Double.class) { + b = new BigDecimal((Double) b); + } + } else if (typeA == Long.class) { + if (typeB == Integer.class) { + b = new Long((Integer) b); + } else if (typeB == BigDecimal.class) { + a = new BigDecimal((Long) a); + } else if (typeB == Float.class) { + a = new Float((Long) a); + } else if (typeB == Double.class) { + a = new Double((Long) a); + } + } else if (typeA == Integer.class) { + if (typeB == Long.class) { + a = new Long((Integer) a); + } else if (typeB == BigDecimal.class) { + a = new BigDecimal((Integer) a); + } else if (typeB == Float.class) { + a = new Float((Integer) a); + } else if (typeB == Double.class) { + a = new Double((Integer) a); + } + } else if (typeA == Double.class) { + if (typeB == Integer.class) { + b = new Double((Integer) b); + } else if (typeB == Long.class) { + b = new Double((Long) b); + } else if (typeB == Float.class) { + b = new Double((Float) b); + } + } else if (typeA == Float.class) { + if (typeB == Integer.class) { + b = new Float((Integer) b); + } else if (typeB == Long.class) { + b = new Float((Long) b); + } else if (typeB == Double.class) { + a = new Double((Float) a); + } + } + + return ((Comparable) a).compareTo(b); + } + + static class KeySetSegment implements Segment { + + public final static KeySetSegment instance = new KeySetSegment(); + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + return path.evalKeySet(currentObject); + } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + throw new UnsupportedOperationException(); + } + } + + static class PropertySegment implements Segment { private final String propertyName; private final long propertyNameHash; private final boolean deep; - public PropertySegement(String propertyName, boolean deep){ + public PropertySegment(String propertyName, boolean deep){ this.propertyName = propertyName; this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); this.deep = deep; @@ -1437,6 +2355,185 @@ public Object eval(JSONPath path, Object rootObject, Object currentObject) { } } + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + JSONLexerBase lexer = (JSONLexerBase) parser.lexer; + + if (deep && context.object == null) { + context.object = new JSONArray(); + } + + if (lexer.token() == JSONToken.LBRACKET) { + if ("*".equals(propertyName)) { + return; + } + + lexer.nextToken(); + JSONArray array; + + if (deep) { + array =(JSONArray) context.object; + } else { + array = new JSONArray(); + } + for (;;) { + switch (lexer.token()) { + case JSONToken.LBRACE: { + if (deep) { + extract(path, parser, context); + break; + } + int matchStat = lexer.seekObjectToField(propertyNameHash, deep); + if (matchStat == JSONLexer.VALUE) { + Object value; + switch (lexer.token()) { + case JSONToken.LITERAL_INT: + value = lexer.integerValue(); + lexer.nextToken(); + break; + case JSONToken.LITERAL_STRING: + value = lexer.stringVal(); + lexer.nextToken(); + break; + default: + value = parser.parse(); + break; + } + + array.add(value); + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + continue; + } else { + lexer.skipObject(false); + } + } else if (matchStat == JSONLexer.NOT_MATCH) { + continue; + } else { + if (deep) { + throw new UnsupportedOperationException(lexer.info()); + } else { + lexer.skipObject(false); + } + } + break; + } + case JSONToken.LBRACKET: + if (deep) { + extract(path, parser, context); + } else { + lexer.skipObject(false); + } + break; + case JSONToken.LITERAL_STRING: + case JSONToken.LITERAL_INT: + case JSONToken.LITERAL_FLOAT: + case JSONToken.LITERAL_ISO8601_DATE: + case JSONToken.TRUE: + case JSONToken.FALSE: + case JSONToken.NULL: + lexer.nextToken(); + break; + default: + break; + } + + if (lexer.token() == JSONToken.RBRACKET) { + lexer.nextToken(); + break; + } else if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(); + continue; + } else { + throw new JSONException("illegal json : " + lexer.info()); + } + } + + if (!deep) { + if (array.size() > 0) { + context.object = array; + } + } + return; + } + + if (!deep) { + int matchStat = lexer.seekObjectToField(propertyNameHash, deep); + if (matchStat == JSONLexer.VALUE) { + if (context.eval) { + Object value; + switch (lexer.token()) { + case JSONToken.LITERAL_INT: + value = lexer.integerValue(); + lexer.nextToken(JSONToken.COMMA); + break; + case JSONToken.LITERAL_FLOAT: + value = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + break; + case JSONToken.LITERAL_STRING: + value = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + break; + default: + value = parser.parse(); + break; + } + + if (context.eval) { + context.object = value; + } + } + } + return; + } + + // deep + for (;;) { + int matchStat = lexer.seekObjectToField(propertyNameHash, deep); + if (matchStat == JSONLexer.NOT_MATCH) { + break; + } + + if (matchStat == JSONLexer.VALUE) { + if (context.eval) { + Object value; + switch (lexer.token()) { + case JSONToken.LITERAL_INT: + value = lexer.integerValue(); + lexer.nextToken(JSONToken.COMMA); + break; + case JSONToken.LITERAL_FLOAT: + value = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + break; + case JSONToken.LITERAL_STRING: + value = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + break; + default: + value = parser.parse(); + break; + } + + if (context.eval) { + if (context.object instanceof List) { + List list = (List) context.object; + if (list.size() == 0 && value instanceof List) { + context.object = value; + } else { + list.add(value); + } + } else { + context.object = value; + } + } + } + } else if (matchStat == JSONLexer.OBJECT || matchStat == JSONLexer.ARRAY) { + extract(path, parser, context); + } + } + } + public void setValue(JSONPath path, Object parent, Object value) { if (deep) { path.deepSet(parent, propertyName, propertyNameHash, value); @@ -1446,16 +2543,16 @@ public void setValue(JSONPath path, Object parent, Object value) { } public boolean remove(JSONPath path, Object parent) { - return path.removePropertyValue(parent, propertyName); + return path.removePropertyValue(parent, propertyName, deep); } } - static class MultiPropertySegement implements Segement { + static class MultiPropertySegment implements Segment { private final String[] propertyNames; private final long[] propertyNamesHash; - public MultiPropertySegement(String[] propertyNames){ + public MultiPropertySegment(String[] propertyNames){ this.propertyNames = propertyNames; this.propertyNamesHash = new long[propertyNames.length]; for (int i = 0; i < propertyNamesHash.length; i++) { @@ -1473,23 +2570,165 @@ public Object eval(JSONPath path, Object rootObject, Object currentObject) { return fieldValues; } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + JSONLexerBase lexer = (JSONLexerBase) parser.lexer; + + JSONArray array; + if (context.object == null) { + context.object = array = new JSONArray(); + } else { + array = (JSONArray) context.object; + } + for (int i = array.size(); i < propertyNamesHash.length; ++i) { + array.add(null); + } + +// if (lexer.token() == JSONToken.LBRACKET) { +// lexer.nextToken(); +// JSONArray array; +// +// array = new JSONArray(); +// for (;;) { +// if (lexer.token() == JSONToken.LBRACE) { +// int index = lexer.seekObjectToField(propertyNamesHash); +// int matchStat = lexer.matchStat; +// if (matchStat == JSONLexer.VALUE) { +// Object value; +// switch (lexer.token()) { +// case JSONToken.LITERAL_INT: +// value = lexer.integerValue(); +// lexer.nextToken(); +// break; +// case JSONToken.LITERAL_STRING: +// value = lexer.stringVal(); +// lexer.nextToken(); +// break; +// default: +// value = parser.parse(); +// break; +// } +// +// array.add(index, value); +// if (lexer.token() == JSONToken.RBRACE) { +// lexer.nextToken(); +// continue; +// } else { +// lexer.skipObject(); +// } +// } else { +// lexer.skipObject(); +// } +// } +// +// if (lexer.token() == JSONToken.RBRACKET) { +// break; +// } else if (lexer.token() == JSONToken.COMMA) { +// lexer.nextToken(); +// continue; +// } else { +// throw new JSONException("illegal json."); +// } +// } +// +// context.object = array; +// return; +// } + + for_: + for (;;) { + int index = lexer.seekObjectToField(propertyNamesHash); + int matchStat = lexer.matchStat; + if (matchStat == JSONLexer.VALUE) { + Object value; + switch (lexer.token()) { + case JSONToken.LITERAL_INT: + value = lexer.integerValue(); + lexer.nextToken(JSONToken.COMMA); + break; + case JSONToken.LITERAL_FLOAT: + value = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + break; + case JSONToken.LITERAL_STRING: + value = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + break; + default: + value = parser.parse(); + break; + } + + array.set(index, value); + + if (lexer.token() == JSONToken.COMMA) { + continue for_; + } + } + + break; + } + } } - static class WildCardSegement implements Segement { + static class WildCardSegment implements Segment { + private boolean deep; + private boolean objectOnly; - public static WildCardSegement instance = new WildCardSegement(); + private WildCardSegment(boolean deep, boolean objectOnly) { + this.deep = deep; + this.objectOnly = objectOnly; + } + + public final static WildCardSegment instance = new WildCardSegment(false, false); + public final static WildCardSegment instance_deep = new WildCardSegment(true, false); + public final static WildCardSegment instance_deep_objectOnly = new WildCardSegment(true, true); public Object eval(JSONPath path, Object rootObject, Object currentObject) { - return path.getPropertyValues(currentObject); + if (!deep) { + return path.getPropertyValues(currentObject); + } + + List values = new ArrayList(); + path.deepGetPropertyValues(currentObject, values); + return values; } + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + if (context.eval) { + Object object = parser.parse(); + if (deep) { + List values = new ArrayList(); + if (objectOnly) { + path.deepGetObjects(object, values); + } else { + path.deepGetPropertyValues(object, values); + } + context.object = values; + return; + } + + if (object instanceof JSONObject) { + Collection values = ((JSONObject) object).values(); + JSONArray array = new JSONArray(values.size()); + array.addAll(values); + context.object = array; + return; + } else if (object instanceof JSONArray) { + context.object = object; + return; + } + } + + throw new JSONException("TODO"); + } } - static class ArrayAccessSegement implements Segement { + static class ArrayAccessSegment implements Segment { private final int index; - public ArrayAccessSegement(int index){ + public ArrayAccessSegment(int index){ this.index = index; } @@ -1504,40 +2743,71 @@ public boolean setValue(JSONPath path, Object currentObject, Object value) { public boolean remove(JSONPath path, Object currentObject) { return path.removeArrayItem(path, currentObject, index); } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + JSONLexerBase lexer = (JSONLexerBase) parser.lexer; + if (lexer.seekArrayToItem(index) + && context.eval) + { + context.object = parser.parse(); + } + } } - static class MultiIndexSegement implements Segement { + static class MultiIndexSegment implements Segment { private final int[] indexes; - public MultiIndexSegement(int[] indexes){ + public MultiIndexSegment(int[] indexes){ this.indexes = indexes; } public Object eval(JSONPath path, Object rootObject, Object currentObject) { - List items = new ArrayList(indexes.length); + List items = new JSONArray(indexes.length); for (int i = 0; i < indexes.length; ++i) { Object item = path.getArrayItem(currentObject, indexes[i]); items.add(item); } return items; } - } - static class RangeSegement implements Segement { + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + if (context.eval) { + Object object = parser.parse(); + if (object instanceof List) { + int[] indexes = new int[this.indexes.length]; + System.arraycopy(this.indexes, 0, indexes, 0, indexes.length); + boolean noneNegative = indexes[0] >= 0; + List list = (List) object; + if (noneNegative) { + for (int i = list.size() - 1; i >= 0; i--) { + if (Arrays.binarySearch(indexes, i) < 0) { + list.remove(i); + } + } + context.object = list; + return; + } + } + } + throw new UnsupportedOperationException(); + } + } + + static class RangeSegment implements Segment { private final int start; private final int end; private final int step; - public RangeSegement(int start, int end, int step){ + public RangeSegment(int start, int end, int step){ this.start = start; this.end = end; this.step = step; } public Object eval(JSONPath path, Object rootObject, Object currentObject) { - int size = SizeSegement.instance.eval(path, rootObject, currentObject); + int size = SizeSegment.instance.eval(path, rootObject, currentObject); int start = this.start >= 0 ? this.start : this.start + size; int end = this.end >= 0 ? this.end : this.end + size; @@ -1553,93 +2823,77 @@ public Object eval(JSONPath path, Object rootObject, Object currentObject) { } return items; } - } - - static class NotNullSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + throw new UnsupportedOperationException(); + } + } - public NotNullSegement(String propertyName){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + static class NotNullSegement extends PropertyFilter { + public NotNullSegement(String propertyName, boolean function){ + super(propertyName, function); } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); - - return propertyValue != null; + return path.getPropertyValue(item, propertyName, propertyNameHash) != null; } } - static class NullSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; - - public NullSegement(String propertyName){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + static class NullSegement extends PropertyFilter { + public NullSegement(String propertyName, boolean function){ + super(propertyName, function); } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); return propertyValue == null; } } - static class ValueSegment implements Filter { - private final String propertyName; - private final long propertyNameHash; + static class ValueSegment extends PropertyFilter { private final Object value; private boolean eq = true; - public ValueSegment(String propertyName, Object value, boolean eq){ + public ValueSegment(String propertyName,boolean function, Object value, boolean eq){ + super(propertyName, function); + if (value == null) { throw new IllegalArgumentException("value is null"); } - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); this.value = value; this.eq = eq; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); boolean result = value.equals(propertyValue); if (!eq) { result = !result; } return result; } - } - static class IntInSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class IntInSegement extends PropertyFilter { private final long[] values; private final boolean not; - public IntInSegement(String propertyName, long[] values, boolean not){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + public IntInSegement(String propertyName, boolean function, long[] values, boolean not){ + super(propertyName, function); this.values = values; this.not = not; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (propertyValue == null) { return false; } if (propertyValue instanceof Number) { - long longPropertyValue = ((Number) propertyValue).longValue(); + long longPropertyValue = TypeUtils.longExtractValue((Number) propertyValue); for (long value : values) { if (value == longPropertyValue) { return !not; @@ -1651,31 +2905,27 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } } - static class IntBetweenSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class IntBetweenSegement extends PropertyFilter { private final long startValue; private final long endValue; private final boolean not; - public IntBetweenSegement(String propertyName, long startValue, long endValue, boolean not){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + public IntBetweenSegement(String propertyName, boolean function, long startValue, long endValue, boolean not){ + super(propertyName, function); this.startValue = startValue; this.endValue = endValue; this.not = not; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (propertyValue == null) { return false; } if (propertyValue instanceof Number) { - long longPropertyValue = ((Number) propertyValue).longValue(); + long longPropertyValue = TypeUtils.longExtractValue((Number) propertyValue); if (longPropertyValue >= startValue && longPropertyValue <= endValue) { return !not; } @@ -1685,22 +2935,18 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } } - static class IntObjInSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class IntObjInSegement extends PropertyFilter { private final Long[] values; private final boolean not; - public IntObjInSegement(String propertyName, Long[] values, boolean not){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + public IntObjInSegement(String propertyName, boolean function, Long[] values, boolean not){ + super(propertyName, function); this.values = values; this.not = not; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (propertyValue == null) { for (Long value : values) { @@ -1713,7 +2959,7 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } if (propertyValue instanceof Number) { - long longPropertyValue = ((Number) propertyValue).longValue(); + long longPropertyValue = TypeUtils.longExtractValue((Number) propertyValue); for (Long value : values) { if (value == null) { continue; @@ -1729,22 +2975,18 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } } - static class StringInSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class StringInSegement extends PropertyFilter { private final String[] values; private final boolean not; - public StringInSegement(String propertyName, String[] values, boolean not){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + public StringInSegement(String propertyName, boolean function, String[] values, boolean not){ + super(propertyName, function); this.values = values; this.not = not; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); for (String value : values) { if (value == propertyValue) { @@ -1758,22 +3000,168 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } } - static class IntOpSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class IntOpSegement extends PropertyFilter { private final long value; private final Operator op; - public IntOpSegement(String propertyName, long value, Operator op){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + private BigDecimal valueDecimal; + private Float valueFloat; + private Double valueDouble; + + public IntOpSegement(String propertyName, boolean function, long value, Operator op){ + super(propertyName, function); + this.value = value; + this.op = op; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = get(path, rootObject, item); + + if (propertyValue == null) { + return false; + } + + if (!(propertyValue instanceof Number)) { + return false; + } + + if (propertyValue instanceof BigDecimal) { + if (valueDecimal == null) { + valueDecimal = BigDecimal.valueOf(value); + } + + int result = valueDecimal.compareTo((BigDecimal) propertyValue); + switch (op) { + case EQ: + return result == 0; + case NE: + return result != 0; + case GE: + return 0 >= result; + case GT: + return 0 > result; + case LE: + return 0 <= result; + case LT: + return 0 < result; + } + + return false; + } + + if (propertyValue instanceof Float) { + if (valueFloat == null) { + valueFloat = Float.valueOf(value); + } + + int result = valueFloat.compareTo((Float) propertyValue); + switch (op) { + case EQ: + return result == 0; + case NE: + return result != 0; + case GE: + return 0 >= result; + case GT: + return 0 > result; + case LE: + return 0 <= result; + case LT: + return 0 < result; + } + + return false; + } + + if (propertyValue instanceof Double) { + if (valueDouble == null) { + valueDouble = Double.valueOf(value); + } + + int result = valueDouble.compareTo((Double) propertyValue); + switch (op) { + case EQ: + return result == 0; + case NE: + return result != 0; + case GE: + return 0 >= result; + case GT: + return 0 > result; + case LE: + return 0 <= result; + case LT: + return 0 < result; + } + + return false; + } + + long longValue = TypeUtils.longExtractValue((Number) propertyValue); + + switch (op) { + case EQ: + return longValue == value; + case NE: + return longValue != value; + case GE: + return longValue >= value; + case GT: + return longValue > value; + case LE: + return longValue <= value; + case LT: + return longValue < value; + } + + return false; + } + } + + static abstract class PropertyFilter implements Filter { + static long TYPE = TypeUtils.fnv1a_64("type"); + + protected final String propertyName; + protected final long propertyNameHash; + protected final boolean function; + protected Segment functionExpr; + + protected PropertyFilter(String propertyName, boolean function) { + this.propertyName = propertyName; + this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + this.function = function; + + if (function) { + if (propertyNameHash == TYPE) { + functionExpr = TypeSegment.instance; + } else if (propertyNameHash == SIZE) { + functionExpr = SizeSegment.instance; + } else { + throw new JSONPathException("unsupported funciton : " + propertyName); + } + } + } + + protected Object get(JSONPath path, Object rootObject, Object currentObject) { + if (functionExpr != null) { + return functionExpr.eval(path, rootObject, currentObject); + } + return path.getPropertyValue(currentObject, propertyName, propertyNameHash); + } + } + + static class DoubleOpSegement extends PropertyFilter { + private final double value; + private final Operator op; + + public DoubleOpSegement(String propertyName, boolean function, double value, Operator op){ + super(propertyName, function); this.value = value; this.op = op; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (propertyValue == null) { return false; @@ -1783,43 +3171,39 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj return false; } - long longValue = ((Number) propertyValue).longValue(); + double doubleValue = ((Number) propertyValue).doubleValue(); - if (op == Operator.EQ) { - return longValue == value; - } else if (op == Operator.NE) { - return longValue != value; - } else if (op == Operator.GE) { - return longValue >= value; - } else if (op == Operator.GT) { - return longValue > value; - } else if (op == Operator.LE) { - return longValue <= value; - } else if (op == Operator.LT) { - return longValue < value; + switch (op) { + case EQ: + return doubleValue == value; + case NE: + return doubleValue != value; + case GE: + return doubleValue >= value; + case GT: + return doubleValue > value; + case LE: + return doubleValue <= value; + case LT: + return doubleValue < value; } return false; } } - - static class DoubleOpSegement implements Filter { - - private final String propertyName; - private final double value; - private final Operator op; - private final long propertyNameHash; + static class RefOpSegement extends PropertyFilter { + private final Segment refSgement; + private final Operator op; - public DoubleOpSegement(String propertyName, double value, Operator op){ - this.propertyName = propertyName; - this.value = value; + public RefOpSegement(String propertyName, boolean function, Segment refSgement, Operator op){ + super(propertyName, function); + this.refSgement = refSgement; this.op = op; - propertyNameHash = TypeUtils.fnv1a_64(propertyName); } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (propertyValue == null) { return false; @@ -1829,40 +3213,71 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj return false; } - double doubleValue = ((Number) propertyValue).doubleValue(); + Object refValue = refSgement.eval(path, rootObject, rootObject); + + if (refValue instanceof Integer || refValue instanceof Long || refValue instanceof Short || refValue instanceof Byte) { + long value = TypeUtils.longExtractValue((Number) refValue); + + if (propertyValue instanceof Integer || propertyValue instanceof Long || propertyValue instanceof Short || propertyValue instanceof Byte) { + long longValue = TypeUtils.longExtractValue((Number) propertyValue); + + switch (op) { + case EQ: + return longValue == value; + case NE: + return longValue != value; + case GE: + return longValue >= value; + case GT: + return longValue > value; + case LE: + return longValue <= value; + case LT: + return longValue < value; + } + } else if (propertyValue instanceof BigDecimal) { + BigDecimal valueDecimal = BigDecimal.valueOf(value); + + int result = valueDecimal.compareTo((BigDecimal) propertyValue); + switch (op) { + case EQ: + return result == 0; + case NE: + return result != 0; + case GE: + return 0 >= result; + case GT: + return 0 > result; + case LE: + return 0 <= result; + case LT: + return 0 < result; + } - if (op == Operator.EQ) { - return doubleValue == value; - } else if (op == Operator.NE) { - return doubleValue != value; - } else if (op == Operator.GE) { - return doubleValue >= value; - } else if (op == Operator.GT) { - return doubleValue > value; - } else if (op == Operator.LE) { - return doubleValue <= value; - } else if (op == Operator.LT) { - return doubleValue < value; + return false; + } } - return false; + throw new UnsupportedOperationException(); } } - static class MatchSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class MatchSegement extends PropertyFilter { private final String startsWithValue; private final String endsWithValue; private final String[] containsValues; private final int minLength; private final boolean not; - public MatchSegement(String propertyName, String startsWithValue, String endsWithValue, String[] containsValues, - boolean not){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + public MatchSegement( + String propertyName, + boolean function, + String startsWithValue, + String endsWithValue, + String[] containsValues, + boolean not) + { + super(propertyName, function); this.startsWithValue = startsWithValue; this.endsWithValue = endsWithValue; this.containsValues = containsValues; @@ -1887,7 +3302,7 @@ public MatchSegement(String propertyName, String startsWithValue, String endsWit } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (propertyValue == null) { return false; @@ -1927,22 +3342,18 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } } - static class RlikeSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class RlikeSegement extends PropertyFilter { private final Pattern pattern; private final boolean not; - public RlikeSegement(String propertyName, String pattern, boolean not){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + public RlikeSegement(String propertyName, boolean function, String pattern, boolean not){ + super(propertyName, function); this.pattern = Pattern.compile(pattern); this.not = not; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (propertyValue == null) { return false; @@ -1960,22 +3371,18 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } } - static class StringOpSegement implements Filter { - - private final String propertyName; - private final long propertyNameHash; + static class StringOpSegement extends PropertyFilter { private final String value; private final Operator op; - public StringOpSegement(String propertyName, String value, Operator op){ - this.propertyName = propertyName; - this.propertyNameHash = TypeUtils.fnv1a_64(propertyName); + public StringOpSegement(String propertyName, boolean function, String value, Operator op){ + super(propertyName, function); this.value = value; this.op = op; } public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { - Object propertyValue = path.getPropertyValue(item, propertyName, propertyNameHash); + Object propertyValue = get(path, rootObject, item); if (op == Operator.EQ) { return value.equals(propertyValue); @@ -2002,15 +3409,38 @@ public boolean apply(JSONPath path, Object rootObject, Object currentObject, Obj } } + static class RegMatchSegement extends PropertyFilter { + private final Pattern pattern; + private final Operator op; + + public RegMatchSegement(String propertyName, boolean function, Pattern pattern, Operator op){ + super(propertyName, function); + this.pattern = pattern; + this.op = op; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = get(path, rootObject, item); + if (propertyValue == null) { + return false; + } + + String str = propertyValue.toString(); + + Matcher m = pattern.matcher(str); + return m.matches(); + } + } + enum Operator { - EQ, NE, GT, GE, LT, LE, LIKE, NOT_LIKE, RLIKE, NOT_RLIKE, IN, NOT_IN, BETWEEN, NOT_BETWEEN + EQ, NE, GT, GE, LT, LE, LIKE, NOT_LIKE, RLIKE, NOT_RLIKE, IN, NOT_IN, BETWEEN, NOT_BETWEEN, And, Or, REG_MATCH } - static public class FilterSegement implements Segement { + static public class FilterSegment implements Segment { private final Filter filter; - public FilterSegement(Filter filter){ + public FilterSegment(Filter filter){ super(); this.filter = filter; } @@ -2042,13 +3472,68 @@ public Object eval(JSONPath path, Object rootObject, Object currentObject) { return null; } + + public void extract(JSONPath path, DefaultJSONParser parser, Context context) { + Object object = parser.parse(); + context.object = eval(path, object, object); + } + + public boolean remove(JSONPath path, Object rootObject, Object currentObject) { + if (currentObject == null) { + return false; + } + + if (currentObject instanceof Iterable) { + Iterator it = ((Iterable) currentObject).iterator(); + while (it.hasNext()) { + Object item = it.next(); + + if (filter.apply(path, rootObject, currentObject, item)) { + it.remove(); + } + } + + return true; + } + + return false; + } } interface Filter { - boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item); } + static class FilterGroup implements Filter { + private boolean and; + private List fitlers; + + public FilterGroup(Filter left, Filter right, boolean and) { + fitlers = new ArrayList(2); + fitlers.add(left); + fitlers.add(right); + this.and = and; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + if (and) { + for (Filter fitler : this.fitlers) { + if (!fitler.apply(path, rootObject, currentObject, item)) { + return false; + } + } + return true; + } else { + for (Filter fitler : this.fitlers) { + if (fitler.apply(path, rootObject, currentObject, item)) { + return true; + } + } + return false; + } + } + } + @SuppressWarnings("rawtypes") protected Object getArrayItem(final Object currentObject, int index) { if (currentObject == null) { @@ -2108,6 +3593,10 @@ protected Object getArrayItem(final Object currentObject, int index) { return null; } + if (index == 0) { + return currentObject; + } + throw new UnsupportedOperationException(); } @@ -2170,6 +3659,10 @@ public boolean removeArrayItem(JSONPath path, Object currentObject, int index) { @SuppressWarnings({ "rawtypes", "unchecked" }) protected Collection getPropertyValues(final Object currentObject) { + if (currentObject == null) { + return null; + } + final Class currentClass = currentObject.getClass(); JavaBeanSerializer beanSerializer = getJavaBeanSerializer(currentClass); @@ -2187,9 +3680,81 @@ protected Collection getPropertyValues(final Object currentObject) { return map.values(); } + if (currentObject instanceof Collection) { + return (Collection) currentObject; + } + throw new UnsupportedOperationException(); } + protected void deepGetObjects(final Object currentObject, List outValues) { + final Class currentClass = currentObject.getClass(); + + JavaBeanSerializer beanSerializer = getJavaBeanSerializer(currentClass); + + Collection collection = null; + if (beanSerializer != null) { + try { + collection = beanSerializer.getFieldValues(currentObject); + outValues.add(currentObject); + } catch (Exception e) { + throw new JSONPathException("jsonpath error, path " + path, e); + } + } else if (currentObject instanceof Map) { + outValues.add(currentObject); + Map map = (Map) currentObject; + collection = map.values(); + } else if (currentObject instanceof Collection) { + collection = (Collection) currentObject; + } + + if (collection != null) { + for (Object fieldValue : collection) { + if (fieldValue == null || ParserConfig.isPrimitive2(fieldValue.getClass())) { + // skip + } else { + deepGetObjects(fieldValue, outValues); + } + } + return; + } + + throw new UnsupportedOperationException(currentClass.getName()); + } + + protected void deepGetPropertyValues(final Object currentObject, List outValues) { + final Class currentClass = currentObject.getClass(); + + JavaBeanSerializer beanSerializer = getJavaBeanSerializer(currentClass); + + Collection collection = null; + if (beanSerializer != null) { + try { + collection = beanSerializer.getFieldValues(currentObject); + } catch (Exception e) { + throw new JSONPathException("jsonpath error, path " + path, e); + } + } else if (currentObject instanceof Map) { + Map map = (Map) currentObject; + collection = map.values(); + } else if (currentObject instanceof Collection) { + collection = (Collection) currentObject; + } + + if (collection != null) { + for (Object fieldValue : collection) { + if (fieldValue == null || ParserConfig.isPrimitive2(fieldValue.getClass())) { + outValues.add(fieldValue); + } else { + deepGetPropertyValues(fieldValue, outValues); + } + } + return; + } + + throw new UnsupportedOperationException(currentClass.getName()); + } + static boolean eq(Object a, Object b) { if (a == b) { return true; @@ -2226,7 +3791,7 @@ static boolean eqNotNull(Number a, Number b) { BigDecimal decimalA = (BigDecimal) a; if (isIntB) { - return decimalA.equals(BigDecimal.valueOf(b.longValue())); + return decimalA.equals(BigDecimal.valueOf(TypeUtils.longExtractValue(b))); } } @@ -2246,7 +3811,7 @@ static boolean eqNotNull(Number a, Number b) { if (isIntB) { if (a instanceof BigInteger) { BigInteger bigIntA = (BigInteger) a; - BigInteger bigIntB = BigInteger.valueOf(b.longValue()); + BigInteger bigIntB = BigInteger.valueOf(TypeUtils.longExtractValue(b)); return bigIntA.equals(bigIntB); } @@ -2273,17 +3838,27 @@ protected static boolean isInt(Class clazzA) { } final static long SIZE = 0x4dea9618e618ae3cL; // TypeUtils.fnv1a_64("size"); + final static long LENGTH = 0xea11573f1af59eb5L; // TypeUtils.fnv1a_64("length"); protected Object getPropertyValue(Object currentObject, String propertyName, long propertyNameHash) { if (currentObject == null) { return null; } + if (currentObject instanceof String) { + try { + JSONObject object = (JSONObject) JSON.parse((String) currentObject, parserConfig); + currentObject = object; + } catch (Exception ex) { + // skip + } + } + if (currentObject instanceof Map) { Map map = (Map) currentObject; Object val = map.get(propertyName); - if (val == null && SIZE == propertyNameHash) { + if (val == null && (SIZE == propertyNameHash || LENGTH == propertyNameHash)) { val = map.size(); } @@ -2304,19 +3879,69 @@ protected Object getPropertyValue(Object currentObject, String propertyName, lon if (currentObject instanceof List) { List list = (List) currentObject; - if (SIZE == propertyNameHash) { + if (SIZE == propertyNameHash || LENGTH == propertyNameHash) { return list.size(); } - List fieldValues = new JSONArray(list.size()); + List fieldValues = null; for (int i = 0; i < list.size(); ++i) { Object obj = list.get(i); + + // + if (obj == list) { + if (fieldValues == null) { + fieldValues = new JSONArray(list.size()); + } + fieldValues.add(obj); + continue; + } + + Object itemValue = getPropertyValue(obj, propertyName, propertyNameHash); + if (itemValue instanceof Collection) { + Collection collection = (Collection) itemValue; + if (fieldValues == null) { + fieldValues = new JSONArray(list.size()); + } + fieldValues.addAll(collection); + } else if (itemValue != null || !ignoreNullValue) { + if (fieldValues == null) { + fieldValues = new JSONArray(list.size()); + } + fieldValues.add(itemValue); + } + } + + if (fieldValues == null) { + fieldValues = Collections.emptyList(); + } + + return fieldValues; + } + + if (currentObject instanceof Object[]) { + Object[] array = (Object[]) currentObject; + + if (SIZE == propertyNameHash || LENGTH == propertyNameHash) { + return array.length; + } + + List fieldValues = new JSONArray(array.length); + + for (int i = 0; i < array.length; ++i) { + Object obj = array[i]; + + // + if (obj == array) { + fieldValues.add(obj); + continue; + } + Object itemValue = getPropertyValue(obj, propertyName, propertyNameHash); if (itemValue instanceof Collection) { Collection collection = (Collection) itemValue; fieldValues.addAll(collection); - } else if (itemValue != null) { + } else if (itemValue != null || !ignoreNullValue) { fieldValues.add(itemValue); } } @@ -2379,16 +4004,38 @@ protected void deepScan(final Object currentObject, final String propertyName, L if (currentObject instanceof Map) { Map map = (Map) currentObject; - - if (map.containsKey(propertyName)) { - Object val = map.get(propertyName); - results.add(val); - return; - } - - for (Object val : map.values()) { + + for (Map.Entry entry : map.entrySet()) { + Object val = entry.getValue(); + + if (propertyName.equals(entry.getKey())) { + if (val instanceof Collection) { + results.addAll((Collection) val); + } else { + results.add(val); + } + continue; + } + + if (val == null || ParserConfig.isPrimitive2(val.getClass())) { + continue; + } + deepScan(val, propertyName, results); } + + return; + } + + if (currentObject instanceof Collection) { + Iterator iterator = ((Collection) currentObject).iterator(); + while (iterator.hasNext()) { + Object next = iterator.next(); + if (ParserConfig.isPrimitive2(next.getClass())) { + continue; + } + deepScan(next, propertyName, results); + } return; } @@ -2500,19 +4147,23 @@ protected boolean setPropertyValue(Object parent, String name, long propertyName return true; } - ObjectDeserializer derializer = parserConfig.getDeserializer(parent.getClass()); + ObjectDeserializer deserializer = parserConfig.getDeserializer(parent.getClass()); - JavaBeanDeserializer beanDerializer = null; - if (derializer instanceof JavaBeanDeserializer) { - beanDerializer = (JavaBeanDeserializer) derializer; + JavaBeanDeserializer beanDeserializer = null; + if (deserializer instanceof JavaBeanDeserializer) { + beanDeserializer = (JavaBeanDeserializer) deserializer; } - if (beanDerializer != null) { - FieldDeserializer fieldDeserializer = beanDerializer.getFieldDeserializer(propertyNameHash); + if (beanDeserializer != null) { + FieldDeserializer fieldDeserializer = beanDeserializer.getFieldDeserializer(propertyNameHash); if (fieldDeserializer == null) { return false; } + if (value != null && value.getClass() != fieldDeserializer.fieldInfo.fieldClass) { + value = TypeUtils.cast(value, fieldDeserializer.fieldInfo.fieldType, parserConfig); + } + fieldDeserializer.setValue(parent, value); return true; } @@ -2521,27 +4172,51 @@ protected boolean setPropertyValue(Object parent, String name, long propertyName } @SuppressWarnings({"rawtypes" }) - protected boolean removePropertyValue(Object parent, String name) { + protected boolean removePropertyValue(Object parent, String name, boolean deep) { if (parent instanceof Map) { Object origin = ((Map) parent).remove(name); - return origin != null; + boolean found = origin != null; + + if (deep) { + for (Object item : ((Map) parent).values()) { + removePropertyValue(item, name, deep); + } + } + + return found; } - ObjectDeserializer derializer = parserConfig.getDeserializer(parent.getClass()); + ObjectDeserializer deserializer = parserConfig.getDeserializer(parent.getClass()); - JavaBeanDeserializer beanDerializer = null; - if (derializer instanceof JavaBeanDeserializer) { - beanDerializer = (JavaBeanDeserializer) derializer; + JavaBeanDeserializer beanDeserializer = null; + if (deserializer instanceof JavaBeanDeserializer) { + beanDeserializer = (JavaBeanDeserializer) deserializer; } - if (beanDerializer != null) { - FieldDeserializer fieldDeserializer = beanDerializer.getFieldDeserializer(name); - if (fieldDeserializer == null) { - return false; + if (beanDeserializer != null) { + FieldDeserializer fieldDeserializer = beanDeserializer.getFieldDeserializer(name); + + boolean found = false; + if (fieldDeserializer != null) { + fieldDeserializer.setValue(parent, null); + found = true; } - fieldDeserializer.setValue(parent, null); - return true; + if (deep) { + Collection propertyValues = this.getPropertyValues(parent); + for (Object item : propertyValues) { + if (item == null) { + continue; + } + removePropertyValue(item, name, deep); + } + } + + return found; + } + + if (deep) { + return false; } throw new UnsupportedOperationException(); @@ -2611,7 +4286,77 @@ int evalSize(Object currentObject) { } } + @SuppressWarnings({"rawtypes", "unchecked"}) + Set evalKeySet(Object currentObject) { + if (currentObject == null) { + return null; + } + + if (currentObject instanceof Map) { + // For performance reasons return keySet directly, without filtering null-value key. + return ((Map)currentObject).keySet(); + } + + if (currentObject instanceof Collection || currentObject instanceof Object[] + || currentObject.getClass().isArray()) { + return null; + } + + JavaBeanSerializer beanSerializer = getJavaBeanSerializer(currentObject.getClass()); + if (beanSerializer == null) { + return null; + } + + try { + return beanSerializer.getFieldNames(currentObject); + } catch (Exception e) { + throw new JSONPathException("evalKeySet error : " + path, e); + } + } + public String toJSONString() { return JSON.toJSONString(path); } + + public static Object reserveToArray(Object object, String... paths) { + JSONArray reserved = new JSONArray(); + + if (paths == null || paths.length == 0) { + return reserved; + } + + for (String item : paths) { + JSONPath path = JSONPath.compile(item); + path.init(); + + Object value = path.eval(object); + reserved.add(value); + } + + return reserved; + } + + public static Object reserveToObject(Object object, String... paths) { + if (paths == null || paths.length == 0) { + return object; + } + + JSONObject reserved = new JSONObject(true); + for (String item : paths) { + JSONPath path = JSONPath.compile(item); + path.init(); + Segment lastSegement = path.segments[path.segments.length - 1]; + if (lastSegement instanceof PropertySegment) { + Object value = path.eval(object); + if (value == null) { + continue; + } + path.set(reserved, value); + } else { + // skip + } + } + + return reserved; + } } diff --git a/src/main/java/com/alibaba/fastjson/JSONReader.java b/src/main/java/com/alibaba/fastjson/JSONReader.java index ff009b7d2e..276ec180d6 100644 --- a/src/main/java/com/alibaba/fastjson/JSONReader.java +++ b/src/main/java/com/alibaba/fastjson/JSONReader.java @@ -24,6 +24,7 @@ public class JSONReader implements Closeable { private final DefaultJSONParser parser; private JSONStreamContext context; + private transient JSONStreamContext lastContext; public JSONReader(Reader reader){ this(reader, new Feature[0]); @@ -69,7 +70,15 @@ public void startObject() { context = new JSONStreamContext(null, JSONStreamContext.StartObject); } else { startStructure(); - context = new JSONStreamContext(context, JSONStreamContext.StartObject); + if (lastContext != null + && lastContext.parent == context) { + context = lastContext; + if (context.state != JSONStreamContext.StartObject) { + context.state = JSONStreamContext.StartObject; + } + } else { + context = new JSONStreamContext(context, JSONStreamContext.StartObject); + } } this.parser.accept(JSONToken.LBRACE, JSONToken.IDENTIFIER); @@ -115,6 +124,7 @@ private void startStructure() { } private void endStructure() { + lastContext = context; context = context.parent; if (context == null) { @@ -236,6 +246,7 @@ public T readObject(Class type) { readBefore(); T object = parser.parseObject(type); + parser.handleResovleTask(object); readAfter(); return object; } diff --git a/src/main/java/com/alibaba/fastjson/JSONStreamAware.java b/src/main/java/com/alibaba/fastjson/JSONStreamAware.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/JSONValidator.java b/src/main/java/com/alibaba/fastjson/JSONValidator.java new file mode 100644 index 0000000000..2466e613f1 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONValidator.java @@ -0,0 +1,617 @@ +package com.alibaba.fastjson; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; + +public abstract class JSONValidator implements Cloneable, Closeable { + public enum Type { + Object, Array, Value + } + + protected boolean eof; + protected int pos = -1; + protected char ch; + protected Type type; + private Boolean validateResult; + + protected int count = 0; + protected boolean supportMultiValue = false; + + public static JSONValidator fromUtf8(byte[] jsonBytes) { + return new UTF8Validator(jsonBytes); + } + + public static JSONValidator fromUtf8(InputStream is) { + return new UTF8InputStreamValidator(is); + } + + public static JSONValidator from(String jsonStr) { + return new UTF16Validator(jsonStr); + } + + public static JSONValidator from(Reader r) { + return new ReaderValidator(r); + } + + public boolean isSupportMultiValue() { + return supportMultiValue; + } + + public JSONValidator setSupportMultiValue(boolean supportMultiValue) { + this.supportMultiValue = supportMultiValue; + return this; + } + + public Type getType() { + if (type == null) { + validate(); + } + + return type; + } + + abstract void next(); + + public boolean validate() { + if (validateResult != null) { + return validateResult; + } + + for (;;) { + if (!any()) { + validateResult = false; + return false; + } + skipWhiteSpace(); + + count++; + if (eof) { + validateResult = true; + return true; + } + + if (supportMultiValue) { + skipWhiteSpace(); + if (eof) { + break; + } + continue; + } else { + validateResult = false; + return false; + } + } + + validateResult = true; + return true; + } + + public void close() throws IOException { + + } + + private boolean any() { + switch (ch) { + case '{': + next(); + + while (isWhiteSpace(ch)) { + next(); + } + + if (ch == '}') { + next(); + type = Type.Object; + return true; + } + + for (;;) { + if (ch == '"') { + fieldName(); + } else { + return false; + } + + skipWhiteSpace(); + if (ch == ':') { + next(); + } else { + return false; + } + skipWhiteSpace(); + + if (!any()) { + return false; + } + + // kv 结束时,只能是 "," 或 "}" + skipWhiteSpace(); + if (ch == ',') { + next(); + skipWhiteSpace(); + } else if (ch == '}') { + next(); + type = Type.Object; + return true; + } else { + return false; + } + } + case '[': + next(); + skipWhiteSpace(); + + if (ch == ']') { + next(); + type = Type.Array; + return true; + } + + for (;;) { + if (!any()) { + return false; + } + + skipWhiteSpace(); + if (ch == ',') { + next(); + skipWhiteSpace(); + } else if (ch == ']') { + next(); + type = Type.Array; + return true; + } + else { + return false; + } + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + if (ch == '-' || ch == '+') { + next(); + skipWhiteSpace(); + if (ch < '0' || ch > '9') { + return false; + } + } + + do { + next(); + } while (ch >= '0' && ch <= '9'); + + if (ch == '.') { + next(); + // bug fix: 0.e7 should not pass the test + if (ch < '0' || ch > '9') { + return false; + } + while (ch >= '0' && ch <= '9') { + next(); + } + } + + if (ch == 'e' || ch == 'E') { + next(); + if (ch == '-' || ch == '+') { + next(); + } + + if (ch >= '0' && ch <= '9') { + next(); + } + else { + return false; + } + + while (ch >= '0' && ch <= '9') { + next(); + } + } + + type = Type.Value; + break; + case '"': + next(); + for (;;) { + if (eof) { + return false; + } + + if (ch == '\\') { + next(); + if (ch == 'u') { + next(); + + next(); + next(); + next(); + next(); + } else { + next(); + } + } else if (ch == '"') { + next(); + type = Type.Value; + return true; + } else { + next(); + } + } + case 't': + next(); + + if (ch != 'r') { + return false; + } + next(); + + if (ch != 'u') { + return false; + } + next(); + + if (ch != 'e') { + return false; + } + next(); + + if (isWhiteSpace(ch) || ch == ',' || ch == ']' || ch == '}' || ch == '\0') { + type = Type.Value; + return true; + } + return false; + case 'f': + next(); + + if (ch != 'a') { + return false; + } + next(); + + if (ch != 'l') { + return false; + } + next(); + + if (ch != 's') { + return false; + } + next(); + + if (ch != 'e') { + return false; + } + next(); + + if (isWhiteSpace(ch) || ch == ',' || ch == ']' || ch == '}' || ch == '\0') { + type = Type.Value; + return true; + } + return false; + case 'n': + next(); + + if (ch != 'u') { + return false; + } + next(); + + if (ch != 'l') { + return false; + } + next(); + + if (ch != 'l') { + return false; + } + next(); + + if (isWhiteSpace(ch) || ch == ',' || ch == ']' || ch == '}' || ch == '\0') { + type = Type.Value; + return true; + } + return false; + default: + return false; + } + return true; + } + + protected void fieldName() + { + next(); + for (; ; ) { + if (ch == '\\') { + next(); + + if (ch == 'u') { + next(); + + next(); + next(); + next(); + next(); + } else { + next(); + } + } + else if (ch == '"') { + next(); + break; + } + else { + next(); + } + } + } + + protected boolean string() + { + next(); + for (; !eof; ) { + if (ch == '\\') { + next(); + + if (ch == 'u') { + next(); + + next(); + next(); + next(); + next(); + } else { + next(); + } + } + else if (ch == '"') { + next(); + return true; + } + else { + next(); + } + } + + return false; + } + + void skipWhiteSpace() { + while (isWhiteSpace(ch)) { + next(); + } + } + + static final boolean isWhiteSpace(char ch) { + return ch == ' ' + || ch == '\t' + || ch == '\r' + || ch == '\n' + || ch == '\f' + || ch == '\b' + ; + } + + static class UTF8Validator extends JSONValidator { + private final byte[] bytes; + + public UTF8Validator(byte[] bytes) { + this.bytes = bytes; + next(); + skipWhiteSpace(); + } + + void next() { + ++pos; + + if (pos >= bytes.length) { + ch = '\0'; + eof = true; + } else { + ch = (char) bytes[pos]; + } + } + } + + static class UTF8InputStreamValidator extends JSONValidator { + private final static ThreadLocal bufLocal = new ThreadLocal(); + + private final InputStream is; + private byte[] buf; + private int end = -1; + private int readCount = 0; + + public UTF8InputStreamValidator(InputStream is) { + this.is = is; + buf = bufLocal.get(); + if (buf != null) { + bufLocal.set(null); + } else { + buf = new byte[1024 * 8]; + } + + next(); + skipWhiteSpace(); + } + + void next() { + if (pos < end) { + ch = (char) buf[++pos]; + } else { + if (!eof) { + int len; + try { + len = is.read(buf, 0, buf.length); + readCount++; + } catch (IOException ex) { + throw new JSONException("read error"); + } + + if (len > 0) { + ch = (char) buf[0]; + pos = 0; + end = len - 1; + } + else if (len == -1) { + pos = 0; + end = 0; + buf = null; + ch = '\0'; + eof = true; + } else { + pos = 0; + end = 0; + buf = null; + ch = '\0'; + eof = true; + throw new JSONException("read error"); + } + } + } + } + + public void close() throws IOException { + bufLocal.set(buf); + is.close(); + } + } + + static class UTF16Validator extends JSONValidator { + private final String str; + + public UTF16Validator(String str) { + this.str = str; + next(); + skipWhiteSpace(); + } + + void next() { + ++pos; + + if (pos >= str.length()) { + ch = '\0'; + eof = true; + } else { + ch = str.charAt(pos); + } + } + + protected final void fieldName() + { + for (int i = pos + 1; i < str.length(); ++i) { + char ch = str.charAt(i); + if (ch == '\\') { + break; + } + if (ch == '\"') { + this.ch = str.charAt(i + 1); + pos = i + 1; + return; + } + } + + next(); + for (; ; ) { + if (ch == '\\') { + next(); + + if (ch == 'u') { + next(); + + next(); + next(); + next(); + next(); + } else { + next(); + } + } + else if (ch == '"') { + next(); + break; + } + else if(eof){ + break; + }else { + next(); + } + } + } + + } + + static class ReaderValidator extends JSONValidator { + private final static ThreadLocal bufLocal = new ThreadLocal(); + + final Reader r; + + private char[] buf; + private int end = -1; + private int readCount = 0; + + ReaderValidator(Reader r) { + this.r = r; + buf = bufLocal.get(); + if (buf != null) { + bufLocal.set(null); + } else { + buf = new char[1024 * 8]; + } + + next(); + skipWhiteSpace(); + } + + void next() { + if (pos < end) { + ch = buf[++pos]; + } else { + if (!eof) { + int len; + try { + len = r.read(buf, 0, buf.length); + readCount++; + } catch (IOException ex) { + throw new JSONException("read error"); + } + + if (len > 0) { + ch = buf[0]; + pos = 0; + end = len - 1; + } + else if (len == -1) { + pos = 0; + end = 0; + buf = null; + ch = '\0'; + eof = true; + } else { + pos = 0; + end = 0; + buf = null; + ch = '\0'; + eof = true; + throw new JSONException("read error"); + } + } + } + } + + public void close() throws IOException { + bufLocal.set(buf); + r.close(); + } + } +} diff --git a/src/main/java/com/alibaba/fastjson/JSONWriter.java b/src/main/java/com/alibaba/fastjson/JSONWriter.java old mode 100755 new mode 100644 index 7cb288dd8e..d5d72f6d6d --- a/src/main/java/com/alibaba/fastjson/JSONWriter.java +++ b/src/main/java/com/alibaba/fastjson/JSONWriter.java @@ -53,13 +53,13 @@ public void writeObject(String object) { serializer.write(object); - afterWriter(); + afterWrite(); } public void writeObject(Object object) { beforeWrite(); serializer.write(object); - afterWriter(); + afterWrite(); } public void startArray() { @@ -145,7 +145,7 @@ private void beforeWrite() { } } - private void afterWriter() { + private void afterWrite() { if (context == null) { return; } diff --git a/src/main/java/com/alibaba/fastjson/PropertyNamingStrategy.java b/src/main/java/com/alibaba/fastjson/PropertyNamingStrategy.java index adfa285bbe..7d7f416f23 100644 --- a/src/main/java/com/alibaba/fastjson/PropertyNamingStrategy.java +++ b/src/main/java/com/alibaba/fastjson/PropertyNamingStrategy.java @@ -4,10 +4,12 @@ * @since 1.2.15 */ public enum PropertyNamingStrategy { - CamelCase, // - PascalCase, // - SnakeCase, // - KebabCase; + CamelCase, // camelCase + PascalCase, // PascalCase + SnakeCase, // snake_case + KebabCase, // kebab-case + NoChange, // + NeverUseThisValueExceptDefaultValue; public String translate(String propertyName) { switch (this) { @@ -63,6 +65,8 @@ public String translate(String propertyName) { return propertyName; } + case NoChange: + case NeverUseThisValueExceptDefaultValue: default: return propertyName; } diff --git a/src/main/java/com/alibaba/fastjson/TypeReference.java b/src/main/java/com/alibaba/fastjson/TypeReference.java old mode 100755 new mode 100644 index 11b09809b5..bf21cb5d75 --- a/src/main/java/com/alibaba/fastjson/TypeReference.java +++ b/src/main/java/com/alibaba/fastjson/TypeReference.java @@ -77,6 +77,11 @@ protected TypeReference(Type... actualTypeArguments){ argTypes[i] = TypeUtils.checkPrimitiveArray( (GenericArrayType) argTypes[i]); } + + // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型 + if(argTypes[i] instanceof ParameterizedType) { + argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); + } } Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); @@ -87,7 +92,42 @@ protected TypeReference(Type... actualTypeArguments){ } type = cachedType; + } + + public static Type intern(ParameterizedTypeImpl type) { + Type cachedType = classTypeCache.get(type); + if (cachedType == null) { + classTypeCache.putIfAbsent(type, type); + cachedType = classTypeCache.get(type); + } + + return cachedType; + } + + private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) { + Class thisClass = this.getClass(); + Type rawType = type.getRawType(); + Type[] argTypes = type.getActualTypeArguments(); + for(int i = 0; i < argTypes.length; ++i) { + if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) { + argTypes[i] = actualTypeArguments[actualIndex++]; + } + + // fix for openjdk and android env + if (argTypes[i] instanceof GenericArrayType) { + argTypes[i] = TypeUtils.checkPrimitiveArray( + (GenericArrayType) argTypes[i]); + } + + // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型 + if(argTypes[i] instanceof ParameterizedType) { + argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); + } + } + + Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); + return key; } /** diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONCreator.java b/src/main/java/com/alibaba/fastjson/annotation/JSONCreator.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONField.java b/src/main/java/com/alibaba/fastjson/annotation/JSONField.java old mode 100755 new mode 100644 index 9907c9ea86..e859d76924 --- a/src/main/java/com/alibaba/fastjson/annotation/JSONField.java +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONField.java @@ -79,4 +79,11 @@ * @since 1.2.31 */ boolean unwrapped() default false; + + /** + * Only support Object + * + * @since 1.2.61 + */ + String defaultValue() default ""; } diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONPOJOBuilder.java b/src/main/java/com/alibaba/fastjson/annotation/JSONPOJOBuilder.java index 648065dbc0..7e708294dd 100644 --- a/src/main/java/com/alibaba/fastjson/annotation/JSONPOJOBuilder.java +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONPOJOBuilder.java @@ -21,7 +21,7 @@ *

* Default value is "build". */ - public String buildMethod() default "build"; + String buildMethod() default "build"; /** * Property used for (re)defining name prefix to use for @@ -37,6 +37,6 @@ * would be used for binding JSON property "value" (using type * indicated by the argument; or one defined with annotations. */ - public String withPrefix() default "with"; + String withPrefix() default "with"; } diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONType.java b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java old mode 100755 new mode 100644 index fd179447e0..39f1fe6e04 --- a/src/main/java/com/alibaba/fastjson/annotation/JSONType.java +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java @@ -7,6 +7,8 @@ import com.alibaba.fastjson.PropertyNamingStrategy; import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson.serializer.SerializerFeature; /** @@ -63,5 +65,16 @@ boolean serializeEnumAsJavaBean() default false; - PropertyNamingStrategy naming() default PropertyNamingStrategy.CamelCase; + PropertyNamingStrategy naming() default PropertyNamingStrategy.NeverUseThisValueExceptDefaultValue; + + /** + * @since 1.2.49 + */ + Class[] serialzeFilters() default {}; + + /** + * @since 1.2.71 + * @return + */ + Class autoTypeCheckHandler() default ParserConfig.AutoTypeCheckHandler.class; } diff --git a/src/main/java/com/alibaba/fastjson/asm/ByteVector.java b/src/main/java/com/alibaba/fastjson/asm/ByteVector.java old mode 100755 new mode 100644 index 72d2b1519a..2d437ea92b --- a/src/main/java/com/alibaba/fastjson/asm/ByteVector.java +++ b/src/main/java/com/alibaba/fastjson/asm/ByteVector.java @@ -30,194 +30,203 @@ package com.alibaba.fastjson.asm; /** - * A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream on top of a - * ByteArrayOutputStream, but is more efficient. - * + * A dynamically extensible vector of bytes. This class is roughly equivalent to + * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. + * * @author Eric Bruneton */ public class ByteVector { - /** - * The content of this vector. - */ - byte[] data; + /** + * The content of this vector. + */ + public byte[] data; - /** - * Actual number of bytes in this vector. - */ - int length; + /** + * Actual number of bytes in this vector. + */ + public int length; - /** - * Constructs a new {@link ByteVector ByteVector} with a default initial size. - */ - public ByteVector(){ - data = new byte[64]; - } + /** + * Constructs a new {@link ByteVector ByteVector} with a default initial size. + */ + public ByteVector() { + data = new byte[64]; + } - /** - * Constructs a new {@link ByteVector ByteVector} with the given initial size. - * - * @param initialSize the initial size of the byte vector to be constructed. - */ - public ByteVector(final int initialSize){ - data = new byte[initialSize]; - } + /** + * Constructs a new {@link ByteVector ByteVector} with the given initial size. + * + * @param initialSize the initial size of the byte vector to be constructed. + */ + public ByteVector(final int initialSize) { + data = new byte[initialSize]; + } - /** - * Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary. - * - * @param b a byte. - * @return this byte vector. - */ - public ByteVector putByte(final int b) { - int length = this.length; - if (length + 1 > data.length) { - enlarge(1); - } - data[length++] = (byte) b; - this.length = length; - return this; - } + /** + * Puts a byte into this byte vector. The byte vector is automatically enlarged + * if necessary. + * + * @param b a byte. + * @return this byte vector. + */ + public ByteVector putByte(final int b) { + int length = this.length; + if (length + 1 > data.length) { + enlarge(1); + } + data[length++] = (byte) b; + this.length = length; + return this; + } - /** - * Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary. - * - * @param b1 a byte. - * @param b2 another byte. - * @return this byte vector. - */ - ByteVector put11(final int b1, final int b2) { - int length = this.length; - if (length + 2 > data.length) { - enlarge(2); - } - byte[] data = this.data; - data[length++] = (byte) b1; - data[length++] = (byte) b2; - this.length = length; - return this; - } + /** + * Puts two bytes into this byte vector. The byte vector is automatically + * enlarged if necessary. + * + * @param b1 a byte. + * @param b2 another byte. + * @return this byte vector. + */ + ByteVector put11(final int b1, final int b2) { + int length = this.length; + if (length + 2 > data.length) { + enlarge(2); + } + final byte[] data = this.data; + data[length++] = (byte) b1; + data[length++] = (byte) b2; + this.length = length; + return this; + } - /** - * Puts a short into this byte vector. The byte vector is automatically enlarged if necessary. - * - * @param s a short. - * @return this byte vector. - */ - public ByteVector putShort(final int s) { - int length = this.length; - if (length + 2 > data.length) { - enlarge(2); - } - byte[] data = this.data; - data[length++] = (byte) (s >>> 8); - data[length++] = (byte) s; - this.length = length; - return this; - } + /** + * Puts a short into this byte vector. The byte vector is automatically enlarged + * if necessary. + * + * @param s a short. + * @return this byte vector. + */ + public ByteVector putShort(final int s) { + int length = this.length; + if (length + 2 > data.length) { + enlarge(2); + } + final byte[] data = this.data; + data[length++] = (byte) (s >>> 8); + data[length++] = (byte) s; + this.length = length; + return this; + } - /** - * Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if necessary. - * - * @param b a byte. - * @param s a short. - * @return this byte vector. - */ - ByteVector put12(final int b, final int s) { - int length = this.length; - if (length + 3 > data.length) { - enlarge(3); - } - byte[] data = this.data; - data[length++] = (byte) b; - data[length++] = (byte) (s >>> 8); - data[length++] = (byte) s; - this.length = length; - return this; - } + /** + * Puts a byte and a short into this byte vector. The byte vector is + * automatically enlarged if necessary. + * + * @param b a byte. + * @param s a short. + * @return this byte vector. + */ + public ByteVector put12(final int b, final int s) { + int length = this.length; + if (length + 3 > data.length) { + enlarge(3); + } + final byte[] data = this.data; + data[length++] = (byte) b; + data[length++] = (byte) (s >>> 8); + data[length++] = (byte) s; + this.length = length; + return this; + } - /** - * Puts an int into this byte vector. The byte vector is automatically enlarged if necessary. - * - * @param i an int. - * @return this byte vector. - */ - public ByteVector putInt(final int i) { - int length = this.length; - if (length + 4 > data.length) { - enlarge(4); - } - byte[] data = this.data; - data[length++] = (byte) (i >>> 24); - data[length++] = (byte) (i >>> 16); - data[length++] = (byte) (i >>> 8); - data[length++] = (byte) i; - this.length = length; - return this; - } + /** + * Puts an int into this byte vector. The byte vector is automatically enlarged + * if necessary. + * + * @param i an int. + * @return this byte vector. + */ + public ByteVector putInt(final int i) { + int length = this.length; + if (length + 4 > data.length) { + enlarge(4); + } + final byte[] data = this.data; + data[length++] = (byte) (i >>> 24); + data[length++] = (byte) (i >>> 16); + data[length++] = (byte) (i >>> 8); + data[length++] = (byte) i; + this.length = length; + return this; + } - /** - * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary. - * - * @param s a String. - * @return this byte vector. - */ - public ByteVector putUTF8(final String s) { - int charLength = s.length(); - int len = length; - if (len + 2 + charLength > data.length) { - enlarge(2 + charLength); - } - byte[] data = this.data; - // optimistic algorithm: instead of computing the byte length and then - // serializing the string (which requires two loops), we assume the byte - // length is equal to char length (which is the most frequent case), and - // we start serializing the string right away. During the serialization, - // if we find that this assumption is wrong, we continue with the - // general method. - data[len++] = (byte) (charLength >>> 8); - data[len++] = (byte) charLength; - for (int i = 0; i < charLength; ++i) { - char c = s.charAt(i); - if (c >= '\001' && c <= '\177') { - data[len++] = (byte) c; - } else { - throw new UnsupportedOperationException(); - } - } - length = len; - return this; - } + /** + * Puts an UTF8 string into this byte vector. The byte vector is automatically + * enlarged if necessary. + * + * @param s a String. + * @return this byte vector. + */ + public ByteVector putUTF8(final String s) { + final int charLength = s.length(); + int len = length; + if (len + 2 + charLength > data.length) { + enlarge(2 + charLength); + } + final byte[] data = this.data; + // optimistic algorithm: instead of computing the byte length and then + // serializing the string (which requires two loops), we assume the byte + // length is equal to char length (which is the most frequent case), and + // we start serializing the string right away. During the serialization, + // if we find that this assumption is wrong, we continue with the + // general method. + data[len++] = (byte) (charLength >>> 8); + data[len++] = (byte) charLength; + for (int i = 0; i < charLength; ++i) { + final char c = s.charAt(i); + if ((c >= '\001' && c <= '\177') || (c >= '\u4E00' && c <= '\u9FFF')) { + data[len++] = (byte) c; + } else { + throw new UnsupportedOperationException(); + } + } + length = len; + return this; + } - /** - * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary. - * - * @param b an array of bytes. May be null to put len null bytes into this byte vector. - * @param off index of the fist byte of b that must be copied. - * @param len number of bytes of b that must be copied. - * @return this byte vector. - */ - public ByteVector putByteArray(final byte[] b, final int off, final int len) { - if (length + len > data.length) { - enlarge(len); - } - if (b != null) { - System.arraycopy(b, off, data, length, len); - } - length += len; - return this; - } + /** + * Puts an array of bytes into this byte vector. The byte vector is + * automatically enlarged if necessary. + * + * @param b an array of bytes. May be null to put len null + * bytes into this byte vector. + * @param off index of the fist byte of b that must be copied. + * @param len number of bytes of b that must be copied. + * @return this byte vector. + */ + public ByteVector putByteArray(final byte[] b, final int off, final int len) { + if (length + len > data.length) { + enlarge(len); + } + if (b != null) { + System.arraycopy(b, off, data, length, len); + } + length += len; + return this; + } - /** - * Enlarge this byte vector so that it can receive n more bytes. - * - * @param size number of additional bytes that this byte vector should be able to receive. - */ - private void enlarge(final int size) { - int length1 = 2 * data.length; - int length2 = length + size; - byte[] newData = new byte[length1 > length2 ? length1 : length2]; - System.arraycopy(data, 0, newData, 0, length); - data = newData; - } + /** + * Enlarge this byte vector so that it can receive n more bytes. + * + * @param size number of additional bytes that this byte vector should be able + * to receive. + */ + private void enlarge(final int size) { + final int length1 = 2 * data.length; + final int length2 = length + size; + final byte[] newData = new byte[length1 > length2 ? length1 : length2]; + System.arraycopy(data, 0, newData, 0, length); + data = newData; + } } diff --git a/src/main/java/com/alibaba/fastjson/asm/ClassReader.java b/src/main/java/com/alibaba/fastjson/asm/ClassReader.java index fdab09f1a8..11cb6f3706 100644 --- a/src/main/java/com/alibaba/fastjson/asm/ClassReader.java +++ b/src/main/java/com/alibaba/fastjson/asm/ClassReader.java @@ -8,14 +8,16 @@ * Created by wenshao on 05/08/2017. */ public class ClassReader { - public final byte[] b; + public final byte[] b; private final int[] items; private final String[] strings; private final int maxStringLength; - public final int header; + public final int header; + private boolean readAnnotations; + public ClassReader(InputStream is, boolean readAnnotations) throws IOException { + this.readAnnotations = readAnnotations; - public ClassReader(final InputStream is) throws IOException { { ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; @@ -81,18 +83,26 @@ public ClassReader(final InputStream is) throws IOException { public void accept(final TypeCollector classVisitor) { char[] c = new char[maxStringLength]; // buffer used to read strings - int i, j, k; // loop variables - int u, v, w; // indexes in b - - String attrName; + int i, j; // loop variables + int u, v; // indexes in b int anns = 0; - int ianns = 0; + + //read annotations + if (readAnnotations) { + u = getAttributes(); + for (i = readUnsignedShort(u); i > 0; --i) { + String attrName = readUTF8(u + 2, c); + if ("RuntimeVisibleAnnotations".equals(attrName)) { + anns = u + 8; + break; + } + u += 6 + readInt(u + 4); + } + } // visits the header u = header; - v = items[readUnsignedShort(u + 4)]; int len = readUnsignedShort(u + 6); - w = 0; u += 8; for (i = 0; i < len; ++i) { u += 2; @@ -123,7 +133,12 @@ public void accept(final TypeCollector classVisitor) { v += 6 + readInt(v + 2); } - //annotations not needed. + if (anns != 0) { + for (i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { + String name = readUTF8(v, c); + classVisitor.visitAnnotation(name); + } + } // visits the fields i = readUnsignedShort(u); @@ -145,6 +160,27 @@ public void accept(final TypeCollector classVisitor) { } } + private int getAttributes() { + // skips the header + int u = header + 8 + readUnsignedShort(header + 6) * 2; + // skips fields and methods + for (int i = readUnsignedShort(u); i > 0; --i) { + for (int j = readUnsignedShort(u + 8); j > 0; --j) { + u += 6 + readInt(u + 12); + } + u += 8; + } + u += 2; + for (int i = readUnsignedShort(u); i > 0; --i) { + for (int j = readUnsignedShort(u + 8); j > 0; --j) { + u += 6 + readInt(u + 12); + } + u += 8; + } + // the attribute_info structure starts just after the methods + return u + 2; + } + private int readMethod(TypeCollector classVisitor, char[] c, int u) { int v; int w; @@ -295,5 +331,4 @@ private String readUTF(int index, final int utfLen, final char[] buf) { } return new String(buf, 0, strLen); } - } diff --git a/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java b/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java b/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/asm/Item.java b/src/main/java/com/alibaba/fastjson/asm/Item.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/asm/Label.java b/src/main/java/com/alibaba/fastjson/asm/Label.java old mode 100755 new mode 100644 index f37786b623..ccdf3111be --- a/src/main/java/com/alibaba/fastjson/asm/Label.java +++ b/src/main/java/com/alibaba/fastjson/asm/Label.java @@ -34,7 +34,7 @@ * and for try catch blocks. A label designates the instruction that is just after. Note however that there can * be other elements between a label and the instruction it designates (such as other labels, stack map frames, line * numbers, etc.). - * + * * @author Eric Bruneton */ public class Label { @@ -61,6 +61,31 @@ public class Label { */ private int[] srcAndRefPositions; + /** + * The bit mask to extract the type of a forward reference to this label. The extracted type is + * either {@link #FORWARD_REFERENCE_TYPE_SHORT} or {@link #FORWARD_REFERENCE_TYPE_WIDE}. + */ + static final int FORWARD_REFERENCE_TYPE_MASK = 0xF0000000; + + /** + * The bit mask to extract the 'handle' of a forward reference to this label. The extracted handle + * is the bytecode offset where the forward reference value is stored (using either 2 or 4 bytes, + * as indicated by the {@link #FORWARD_REFERENCE_TYPE_MASK}). + */ + static final int FORWARD_REFERENCE_HANDLE_MASK = 0x0FFFFFFF; + + /** + * The type of forward references stored with two bytes in the bytecode. This is the case, for + * instance, of a forward reference from an ifnull instruction. + */ + static final int FORWARD_REFERENCE_TYPE_SHORT = 0x10000000; + + /** + * The type of forward references stored in four bytes in the bytecode. This is the case, for + * instance, of a forward reference from a lookupswitch instruction. + */ + static final int FORWARD_REFERENCE_TYPE_WIDE = 0x20000000; + // ------------------------------------------------------------------------ /* @@ -109,7 +134,7 @@ public class Label { * The next basic block in the basic block stack. This stack is used in the main loop of the fix point algorithm * used in the second step of the control flow analysis algorithms. It is also used in {@link #visitSubroutine} to * avoid using a recursive method. - * + * * @see MethodWriter#visitMaxs */ Label next; @@ -132,7 +157,7 @@ public Label(){ * Puts a reference to this label in the bytecode of a method. If the position of the label is known, the offset is * computed and written directly. Otherwise, a null offset is written and a new forward reference is declared for * this label. - * + * * @param owner the code writer that calls this method. * @param out the bytecode of the method. * @param source the position of first byte of the bytecode instruction that contains this label. @@ -140,12 +165,21 @@ public Label(){ * stored with 2 bytes. * @throws IllegalArgumentException if this label has not been created by the given code writer. */ - void put(final MethodWriter owner, final ByteVector out, final int source) { - if ((status & 2 /* RESOLVED */ ) == 0) { - addReference(source, out.length); - out.putShort(-1); + void put(final MethodWriter owner, final ByteVector out, final int source, boolean wideOffset) { + if ((status & 2 /* RESOLVED */) == 0) { + if (wideOffset) { + addReference(source, out.length, FORWARD_REFERENCE_TYPE_WIDE); + out.putInt(-1); + } else { + addReference(source, out.length, FORWARD_REFERENCE_TYPE_SHORT); + out.putShort(-1); + } } else { - out.putShort(position - source); + if (wideOffset) { + out.putInt(position - source); + } else { + out.putShort(position - source); + } } } @@ -153,12 +187,12 @@ void put(final MethodWriter owner, final ByteVector out, final int source) { * Adds a forward reference to this label. This method must be called only for a true forward reference, i.e. only * if this label is not resolved yet. For backward references, the offset of the reference can be, and must be, * computed and stored directly. - * + * * @param sourcePosition the position of the referencing instruction. This position will be used to compute the * offset of this forward reference. * @param referencePosition the position where the offset for this forward reference must be stored. */ - private void addReference(final int sourcePosition, final int referencePosition) { + private void addReference(final int sourcePosition, final int referencePosition, final int referenceType) { if (srcAndRefPositions == null) { srcAndRefPositions = new int[6]; } @@ -168,14 +202,14 @@ private void addReference(final int sourcePosition, final int referencePosition) srcAndRefPositions = a; } srcAndRefPositions[referenceCount++] = sourcePosition; - srcAndRefPositions[referenceCount++] = referencePosition; + srcAndRefPositions[referenceCount++] = referencePosition | referenceType; } /** * Resolves all forward references to this label. This method must be called when this label is added to the * bytecode of the method, i.e. when its position becomes known. This method fills in the blanks that where left in * the bytecode by each forward reference previously added to this label. - * + * * @param owner the code writer that calls this method. * @param position the position of this label in the bytecode. * @param data the bytecode of the method. @@ -193,10 +227,17 @@ void resolve(final MethodWriter owner, final int position, final byte[] data) { while (i < referenceCount) { int source = srcAndRefPositions[i++]; int reference = srcAndRefPositions[i++]; + int handle = reference & FORWARD_REFERENCE_HANDLE_MASK; int offset = position - source; - data[reference++] = (byte) (offset >>> 8); - data[reference] = (byte) offset; - + if ((reference & FORWARD_REFERENCE_TYPE_MASK) == FORWARD_REFERENCE_TYPE_SHORT) { + data[handle++] = (byte) (offset >>> 8); + data[handle] = (byte) offset; + } else { + data[handle++] = (byte) (offset >>> 24); + data[handle++] = (byte) (offset >>> 16); + data[handle++] = (byte) (offset >>> 8); + data[handle] = (byte) offset; + } } } diff --git a/src/main/java/com/alibaba/fastjson/asm/MethodCollector.java b/src/main/java/com/alibaba/fastjson/asm/MethodCollector.java index 4af294edf0..9f04b8f46b 100644 --- a/src/main/java/com/alibaba/fastjson/asm/MethodCollector.java +++ b/src/main/java/com/alibaba/fastjson/asm/MethodCollector.java @@ -11,14 +11,14 @@ public class MethodCollector { private int currentParameter; - private final StringBuffer result; + private final StringBuilder result; protected boolean debugInfoPresent; protected MethodCollector(int ignoreCount, int paramCount) { this.ignoreCount = ignoreCount; this.paramCount = paramCount; - this.result = new StringBuffer(); + this.result = new StringBuilder(); this.currentParameter = 0; // if there are 0 parameters, there is no need for debug info this.debugInfoPresent = paramCount == 0; diff --git a/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java b/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java b/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java old mode 100755 new mode 100644 index 1cd633d2e0..743f63479e --- a/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java +++ b/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java @@ -204,7 +204,8 @@ public void visitJumpInsn(final int opcode, final Label label) { * needed). */ code.putByte(opcode); - label.put(this, code, code.length - 1); + // Currently, GOTO_W is the only supported wide reference + label.put(this, code, code.length - 1, opcode == Opcodes.GOTO_W); } } diff --git a/src/main/java/com/alibaba/fastjson/asm/Opcodes.java b/src/main/java/com/alibaba/fastjson/asm/Opcodes.java old mode 100755 new mode 100644 index 3440da9804..4433068900 --- a/src/main/java/com/alibaba/fastjson/asm/Opcodes.java +++ b/src/main/java/com/alibaba/fastjson/asm/Opcodes.java @@ -134,6 +134,6 @@ public interface Opcodes { int IFNULL = 198; // visitJumpInsn int IFNONNULL = 199; // - - // int GOTO_W = 200; // - + int GOTO_W = 200; // visitJumpInsn // int JSR_W = 201; // - } diff --git a/src/main/java/com/alibaba/fastjson/asm/Type.java b/src/main/java/com/alibaba/fastjson/asm/Type.java old mode 100755 new mode 100644 index 4a5da99996..8c9c804450 --- a/src/main/java/com/alibaba/fastjson/asm/Type.java +++ b/src/main/java/com/alibaba/fastjson/asm/Type.java @@ -280,7 +280,7 @@ protected String getClassName() { return "double"; case 9: //ARRAY: Type elementType = getType(buf, off + getDimensions()); - StringBuffer b = new StringBuffer(elementType.getClassName()); + StringBuilder b = new StringBuilder(elementType.getClassName()); for (int i = getDimensions(); i > 0; --i) { b.append("[]"); } diff --git a/src/main/java/com/alibaba/fastjson/asm/TypeCollector.java b/src/main/java/com/alibaba/fastjson/asm/TypeCollector.java index 32f82b94d4..16d38417e2 100644 --- a/src/main/java/com/alibaba/fastjson/asm/TypeCollector.java +++ b/src/main/java/com/alibaba/fastjson/asm/TypeCollector.java @@ -1,10 +1,14 @@ package com.alibaba.fastjson.asm; +import com.alibaba.fastjson.util.ASMUtils; + import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; public class TypeCollector { + private static String JSONType = ASMUtils.desc(com.alibaba.fastjson.annotation.JSONType.class); + private static final Map primitives = new HashMap() { { put("int","I"); @@ -24,6 +28,8 @@ public class TypeCollector { protected MethodCollector collector; + protected boolean jsonType; + public TypeCollector(String methodName, Class[] parameterTypes) { this.methodName = methodName; this.parameterTypes = parameterTypes; @@ -62,19 +68,25 @@ protected MethodCollector visitMethod(int access, String name, String desc) { argTypes.length + longOrDoubleQuantity); } + public void visitAnnotation(String desc) { + if (JSONType.equals(desc)) { + jsonType = true; + } + } + private boolean correctTypeName(Type type, String paramTypeName) { String s = type.getClassName(); // array notation needs cleanup. - String braces = ""; + StringBuilder braces = new StringBuilder(); while (s.endsWith("[]")) { - braces = braces + "["; + braces.append('['); s = s.substring(0, s.length() - 2); } - if (!braces.equals("")) { + if (braces.length() != 0) { if (primitives.containsKey(s)) { - s = braces + primitives.get(s); + s = braces.append(primitives.get(s)).toString(); } else { - s = braces + "L" + s + ";"; + s = braces.append('L').append(s).append(';').toString(); } } return s.equals(paramTypeName); @@ -86,4 +98,12 @@ public String[] getParameterNamesForMethod() { } return collector.getResult().split(","); } + + public boolean matched() { + return collector != null; + } + + public boolean hasJsonType() { + return jsonType; + } } \ No newline at end of file diff --git a/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java b/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java old mode 100755 new mode 100644 index 164487f5dc..210a952dea --- a/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java +++ b/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2019 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,10 @@ */ package com.alibaba.fastjson.parser; -import static com.alibaba.fastjson.parser.JSONLexer.EOI; -import static com.alibaba.fastjson.parser.JSONToken.*; +import com.alibaba.fastjson.*; +import com.alibaba.fastjson.parser.deserializer.*; +import com.alibaba.fastjson.serializer.*; +import com.alibaba.fastjson.util.TypeUtils; import java.io.Closeable; import java.lang.reflect.ParameterizedType; @@ -29,10 +31,8 @@ import java.text.SimpleDateFormat; import java.util.*; -import com.alibaba.fastjson.*; -import com.alibaba.fastjson.parser.deserializer.*; -import com.alibaba.fastjson.serializer.*; -import com.alibaba.fastjson.util.TypeUtils; +import static com.alibaba.fastjson.parser.JSONLexer.EOI; +import static com.alibaba.fastjson.parser.JSONToken.*; /** * @author wenshao[szujobs@hotmail.com] @@ -67,6 +67,8 @@ public class DefaultJSONParser implements Closeable { private List extraProcessors = null; protected FieldTypeResolver fieldTypeResolver = null; + private int objectKeyLevel = 0; + private boolean autoTypeEnable; private String[] autoTypeAccept = null; @@ -95,9 +97,7 @@ public class DefaultJSONParser implements Closeable { String.class }; - for (Class clazz : classes) { - primitiveClasses.add(clazz); - } + primitiveClasses.addAll(Arrays.asList(classes)); } public String getDateFomartPattern() { @@ -117,7 +117,15 @@ public void setDateFormat(String dateFormat) { this.dateFormat = null; } + /** + * @deprecated + * @see setDateFormat + */ public void setDateFomrat(DateFormat dateFormat) { + this.setDateFormat(dateFormat); + } + + public void setDateFormat(DateFormat dateFormat) { this.dateFormat = dateFormat; } @@ -177,24 +185,30 @@ public String getInput() { @SuppressWarnings({ "unchecked", "rawtypes" }) public final Object parseObject(final Map object, Object fieldName) { final JSONLexer lexer = this.lexer; - + if (lexer.token() == JSONToken.NULL) { lexer.nextToken(); return null; } - + if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(); return object; } + if (lexer.token() == JSONToken.LITERAL_STRING && lexer.stringVal().length() == 0) { + lexer.nextToken(); + return object; + } + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { throw new JSONException("syntax error, expect {, actual " + lexer.tokenName() + ", " + lexer.info()); } ParseContext context = this.context; try { - Map map = object instanceof JSONObject ? ((JSONObject) object).getInnerMap() : object; + boolean isJsonObjectMap = object instanceof JSONObject; + Map map = isJsonObjectMap ? ((JSONObject) object).getInnerMap() : object; boolean setContextFlag = false; for (;;) { @@ -254,11 +268,14 @@ public final Object parseObject(final Map object, Object fieldName) { lexer.resetStringPosition(); lexer.scanNumber(); try { - if (lexer.token() == JSONToken.LITERAL_INT) { - key = lexer.integerValue(); - } else { - key = lexer.decimalValue(true); - } + if (lexer.token() == JSONToken.LITERAL_INT) { + key = lexer.integerValue(); + } else { + key = lexer.decimalValue(true); + } + if (lexer.isEnabled(Feature.NonStringKeyAsString) || isJsonObjectMap) { + key = key.toString(); + } } catch (NumberFormatException e) { throw new JSONException("parse number key error" + lexer.info()); } @@ -267,6 +284,9 @@ public final Object parseObject(final Map object, Object fieldName) { throw new JSONException("parse number key error" + lexer.info()); } } else if (ch == '{' || ch == '[') { + if (objectKeyLevel++ > 512) { + throw new JSONException("object key level > 512"); + } lexer.nextToken(); key = parse(); isObjectKey = true; @@ -304,8 +324,24 @@ public final Object parseObject(final Map object, Object fieldName) { if (object != null && object.getClass().getName().equals(typeName)) { clazz = object.getClass(); + } else if ("java.util.HashMap".equals(typeName)) { + clazz = java.util.HashMap.class; + } else if ("java.util.LinkedHashMap".equals(typeName)) { + clazz = java.util.LinkedHashMap.class; } else { - clazz = config.checkAutoType(typeName, null, lexer.getFeatures()); + + boolean allDigits = true; + for (int i = 0; i < typeName.length(); ++i) { + char c = typeName.charAt(i); + if (c < '0' || c > '9') { + allDigits = false; + break; + } + } + + if (!allDigits) { + clazz = config.checkAutoType(typeName, null, lexer.getFeatures()); + } } if (clazz == null) { @@ -320,19 +356,7 @@ public final Object parseObject(final Map object, Object fieldName) { Object instance = null; ObjectDeserializer deserializer = this.config.getDeserializer(clazz); if (deserializer instanceof JavaBeanDeserializer) { - JavaBeanDeserializer javaBeanDeserializer = (JavaBeanDeserializer) deserializer; - instance = javaBeanDeserializer.createInstance(this, clazz); - - for (Object o : map.entrySet()) { - Map.Entry entry = (Map.Entry) o; - Object entryKey = entry.getKey(); - if (entryKey instanceof String) { - FieldDeserializer fieldDeserializer = javaBeanDeserializer.getFieldDeserializer((String) entryKey); - if (fieldDeserializer != null) { - fieldDeserializer.setValue(instance, entry.getValue()); - } - } - } + instance = TypeUtils.cast(object, clazz, this.config); } if (instance == null) { @@ -340,6 +364,8 @@ public final Object parseObject(final Map object, Object fieldName) { instance = new HashMap(); } else if ("java.util.Collections$EmptyMap".equals(typeName)) { instance = Collections.emptyMap(); + } else if ("java.util.Collections$UnmodifiableMap".equals(typeName)) { + instance = Collections.unmodifiableMap(new HashMap()); } else { instance = clazz.newInstance(); } @@ -350,7 +376,7 @@ public final Object parseObject(final Map object, Object fieldName) { throw new JSONException("create instance error", e); } } - + this.setResolveStatus(TypeNameRedirect); if (this.context != null @@ -359,25 +385,41 @@ public final Object parseObject(final Map object, Object fieldName) { && !(this.context.fieldName instanceof Integer)) { this.popContext(); } - + if (object.size() > 0) { Object newObj = TypeUtils.cast(object, clazz, this.config); + this.setResolveStatus(NONE); this.parseObject(newObj); return newObj; } ObjectDeserializer deserializer = config.getDeserializer(clazz); - return deserializer.deserialze(this, clazz, fieldName); + Class deserClass = deserializer.getClass(); + if (JavaBeanDeserializer.class.isAssignableFrom(deserClass) + && deserClass != JavaBeanDeserializer.class + && deserClass != ThrowableDeserializer.class) { + this.setResolveStatus(NONE); + } else if (deserializer instanceof MapDeserializer) { + this.setResolveStatus(NONE); + } + Object obj = deserializer.deserialze(this, clazz, fieldName); + return obj; } if (key == "$ref" && context != null + && (object == null || object.size() == 0) && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) { lexer.nextToken(JSONToken.LITERAL_STRING); if (lexer.token() == JSONToken.LITERAL_STRING) { String ref = lexer.stringVal(); lexer.nextToken(JSONToken.RBRACE); + if (lexer.token() == JSONToken.COMMA) { + map.put(key, ref); + continue; + } + Object refValue = null; if ("@".equals(ref)) { if (this.context != null) { @@ -409,12 +451,18 @@ public final Object parseObject(final Map object, Object fieldName) { setResolveStatus(DefaultJSONParser.NeedToResolve); } } else { - addResolveTask(new ResolveTask(context, ref)); - setResolveStatus(DefaultJSONParser.NeedToResolve); + JSONPath jsonpath = JSONPath.compile(ref); + if (jsonpath.isRef()) { + addResolveTask(new ResolveTask(context, ref)); + setResolveStatus(DefaultJSONParser.NeedToResolve); + } else { + refValue = new JSONObject() + .fluentPut("$ref", ref); + } } if (lexer.token() != JSONToken.RBRACE) { - throw new JSONException("syntax error"); + throw new JSONException("syntax error, " + lexer.info()); } lexer.nextToken(JSONToken.COMMA); @@ -480,7 +528,7 @@ public final Object parseObject(final Map object, Object fieldName) { } this.parseArray(list, key); - + if (lexer.isEnabled(Feature.UseObjectArray)) { value = list.toArray(); } else { @@ -496,16 +544,26 @@ public final Object parseObject(final Map object, Object fieldName) { } else { throw new JSONException("syntax error"); } - } else if (ch == '{') { // 减少嵌套,兼容android + } else if (ch == '{') { // 减少嵌套,兼容 Android lexer.nextToken(); final boolean parentIsArray = fieldName != null && fieldName.getClass() == Integer.class; - JSONObject input = new JSONObject(lexer.isEnabled(Feature.OrderedField)); + Map input; + if (lexer.isEnabled(Feature.CustomMapDeserializer)) { + MapDeserializer mapDeserializer = (MapDeserializer) config.getDeserializer(Map.class); + + + input = (lexer.getFeatures() & Feature.OrderedField.mask) != 0 + ? mapDeserializer.createMap(Map.class, lexer.getFeatures()) + : mapDeserializer.createMap(Map.class); + } else { + input = new JSONObject(lexer.isEnabled(Feature.OrderedField)); + } ParseContext ctxLocal = null; if (!parentIsArray) { - ctxLocal = setContext(context, input, key); + ctxLocal = setContext(this.context, input, key); } Object obj = null; @@ -522,7 +580,7 @@ public final Object parseObject(final Map object, Object fieldName) { if (!objParsed) { obj = this.parseObject(input, key); } - + if (ctxLocal != null && input != obj) { ctxLocal.object = object; } @@ -530,7 +588,7 @@ public final Object parseObject(final Map object, Object fieldName) { if (key != null) { checkMapResolve(object, key.toString()); } - + map.put(key, obj); if (parentIsArray) { @@ -607,7 +665,7 @@ public void setConfig(ParserConfig config) { public T parseObject(Class clazz) { return (T) parseObject(clazz, null); } - + public T parseObject(Type type) { return parseObject(type, null); } @@ -617,7 +675,8 @@ public T parseObject(Type type, Object fieldName) { int token = lexer.token(); if (token == JSONToken.NULL) { lexer.nextToken(); - return null; + + return (T) TypeUtils.optionalEmpty(type); } if (token == JSONToken.LITERAL_STRING) { @@ -634,10 +693,17 @@ public T parseObject(Type type, Object fieldName) { } } - ObjectDeserializer derializer = config.getDeserializer(type); + ObjectDeserializer deserializer = config.getDeserializer(type); try { - return (T) derializer.deserialze(this, type, fieldName); + if (deserializer.getClass() == JavaBeanDeserializer.class) { + if (lexer.token()!= JSONToken.LBRACE && lexer.token()!=JSONToken.LBRACKET) { + throw new JSONException("syntax error,expect start with { or [,but actually start with "+ lexer.tokenName()); + } + return (T) ((JavaBeanDeserializer) deserializer).deserialze(this, type, fieldName, 0); + } else { + return (T) deserializer.deserialze(this, type, fieldName); + } } catch (JSONException e) { throw e; } catch (Throwable e) { @@ -669,7 +735,7 @@ public void parseArray(Type type, Collection array, Object fieldName) { } if (token != JSONToken.LBRACKET) { - throw new JSONException("exepct '[', but " + JSONToken.name(token) + ", " + lexer.info()); + throw new JSONException("field " + fieldName + " expect '[', but " + JSONToken.name(token) + ", " + lexer.info()); } ObjectDeserializer deserializer = null; @@ -795,8 +861,12 @@ public Object[] parseArray(Type[] types) { if (i == types.length - 1) { if (type instanceof Class) { Class clazz = (Class) type; - isArray = clazz.isArray(); - componentType = clazz.getComponentType(); + //如果最后一个type是字节数组,且当前token为字符串类型,不应该当作可变长参数进行处理 + //而是作为一个整体的Base64字符串进行反序列化 + if (!((clazz == byte[].class || clazz == char[].class) && lexer.token() == LITERAL_STRING)) { + isArray = clazz.isArray(); + componentType = clazz.getComponentType(); + } } } @@ -804,12 +874,12 @@ public Object[] parseArray(Type[] types) { if (isArray && lexer.token() != JSONToken.LBRACKET) { List varList = new ArrayList(); - ObjectDeserializer derializer = config.getDeserializer(componentType); - int fastMatch = derializer.getFastMatchToken(); + ObjectDeserializer deserializer = config.getDeserializer(componentType); + int fastMatch = deserializer.getFastMatchToken(); if (lexer.token() != JSONToken.RBRACKET) { for (;;) { - Object item = derializer.deserialze(this, type, null); + Object item = deserializer.deserialze(this, type, null); varList.add(item); if (lexer.token() == JSONToken.COMMA) { @@ -824,8 +894,8 @@ public Object[] parseArray(Type[] types) { value = TypeUtils.cast(varList, type, config); } else { - ObjectDeserializer derializer = config.getDeserializer(type); - value = derializer.deserialze(this, type, i); + ObjectDeserializer deserializer = config.getDeserializer(type); + value = deserializer.deserialze(this, type, i); } } } @@ -858,9 +928,9 @@ public Object[] parseArray(Type[] types) { public void parseObject(Object object) { Class clazz = object.getClass(); JavaBeanDeserializer beanDeser = null; - ObjectDeserializer deserizer = config.getDeserializer(clazz); - if (deserizer instanceof JavaBeanDeserializer) { - beanDeser = (JavaBeanDeserializer) deserizer; + ObjectDeserializer deserializer = config.getDeserializer(clazz); + if (deserializer instanceof JavaBeanDeserializer) { + beanDeser = (JavaBeanDeserializer) deserializer; } if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { @@ -887,7 +957,7 @@ public void parseObject(Object object) { if (beanDeser != null) { fieldDeser = beanDeser.getFieldDeserializer(key); } - + if (fieldDeser == null) { if (!lexer.isEnabled(Feature.IgnoreNotMatch)) { throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key); @@ -1081,8 +1151,17 @@ public Object parseObject(final Map object) { public JSONObject parseObject() { JSONObject object = new JSONObject(lexer.isEnabled(Feature.OrderedField)); - object = (JSONObject) parseObject(object); - return object; + Object parsedObject = parseObject(object); + + if (parsedObject instanceof JSONObject) { + return (JSONObject) parsedObject; + } + + if (parsedObject == null) { + return null; + } + + return new JSONObject((Map) parsedObject); } @SuppressWarnings("rawtypes") @@ -1105,10 +1184,14 @@ public final void parseArray(final Collection array, Object fieldName) { lexer.nextToken(JSONToken.LITERAL_STRING); + if (this.context != null && this.context.level > 512) { + throw new JSONException("array level > 512"); + } + ParseContext context = this.context; this.setContext(array, fieldName); try { - for (int i = 0;; ++i) { + for (int i = 0; ; ++i) { if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { while (lexer.token() == JSONToken.COMMA) { lexer.nextToken(); @@ -1194,6 +1277,8 @@ public final void parseArray(final Collection array, Object fieldName) { continue; } } + } catch (ClassCastException e) { + throw new JSONException("unkown error", e); } finally { this.setContext(context); } @@ -1203,6 +1288,10 @@ public ParseContext getContext() { return context; } + public ParseContext getOwnerContext() { + return context.parent; + } + public List getResolveTaskList() { if (resolveTaskList == null) { resolveTaskList = new ArrayList(2); @@ -1238,7 +1327,7 @@ public List getExtraTypeProviders() { public FieldTypeResolver getFieldTypeResolver() { return fieldTypeResolver; } - + public void setFieldTypeResolver(FieldTypeResolver fieldTypeResolver) { this.fieldTypeResolver = fieldTypeResolver; } @@ -1324,14 +1413,20 @@ public Object parse(Object fieldName) { parseArray(treeSet, fieldName); return treeSet; case LBRACKET: - JSONArray array = new JSONArray(); + Collection array = isEnabled(Feature.UseNativeJavaObject) + ? new ArrayList() + : new JSONArray(); parseArray(array, fieldName); if (lexer.isEnabled(Feature.UseObjectArray)) { return array.toArray(); } return array; case LBRACE: - JSONObject object = new JSONObject(lexer.isEnabled(Feature.OrderedField)); + Map object = isEnabled(Feature.UseNativeJavaObject) + ? lexer.isEnabled(Feature.OrderedField) + ? new HashMap() + : new LinkedHashMap() + : new JSONObject(lexer.isEnabled(Feature.OrderedField)); return parseObject(object, fieldName); // case LBRACE: { // Map map = lexer.isEnabled(Feature.OrderedField) @@ -1388,7 +1483,7 @@ public Object parse(Object fieldName) { lexer.nextToken(JSONToken.LPAREN); accept(JSONToken.LPAREN); - long time = ((Number) lexer.integerValue()).longValue(); + long time = lexer.integerValue().longValue(); accept(JSONToken.LITERAL_INT); accept(JSONToken.RPAREN); @@ -1446,12 +1541,12 @@ public final void accept(final int token, int nextExpectToken) { throwException(token); } } - + public void throwException(int token) { throw new JSONException("syntax error, expect " + JSONToken.name(token) + ", actual " + JSONToken.name(lexer.token())); } - + public void close() { final JSONLexer lexer = this.lexer; @@ -1499,7 +1594,10 @@ public void handleResovleTask(Object value) { refValue = getObject(ref); if (refValue == null) { try { - refValue = JSONPath.eval(value, ref); + JSONPath jsonpath = new JSONPath(ref, SerializeConfig.getGlobalInstance(), config, true); + if (jsonpath.isRef()) { + refValue = jsonpath.eval(value); + } } catch (JSONPathException ex) { // skip } @@ -1516,7 +1614,23 @@ public void handleResovleTask(Object value) { && fieldDeser.fieldInfo != null && !Map.class.isAssignableFrom(fieldDeser.fieldInfo.fieldClass)) { Object root = this.contextArray[0].object; - refValue = JSONPath.eval(root, ref); + JSONPath jsonpath = JSONPath.compile(ref); + if (jsonpath.isRef()) { + refValue = jsonpath.eval(root); + } + } + + // workaround for bug + if (fieldDeser.getOwnerClass() != null + && (!fieldDeser.getOwnerClass().isInstance(object)) + && task.ownerContext.parent != null + ) { + for (ParseContext ctx = task.ownerContext.parent;ctx != null;ctx = ctx.parent) { + if (fieldDeser.getOwnerClass().isInstance(ctx.object)) { + object = ctx.object; + break; + } + } } fieldDeser.setValue(object, refValue); @@ -1536,12 +1650,12 @@ public ResolveTask(ParseContext context, String referenceValue){ this.referenceValue = referenceValue; } } - + public void parseExtra(Object object, String key) { final JSONLexer lexer = this.lexer; // xxx lexer.nextTokenWithColon(); Type type = null; - + if (extraTypeProviders != null) { for (ExtraTypeProvider extraProvider : extraTypeProviders) { type = extraProvider.getExtraType(object, key); @@ -1550,7 +1664,7 @@ public void parseExtra(Object object, String key) { Object value = type == null // ? parse() // skip : parseObject(type); - + if (object instanceof ExtraProcessable) { ExtraProcessable extraProcessable = ((ExtraProcessable) object); extraProcessable.processExtra(key, value); @@ -1709,4 +1823,5 @@ public Object parse(PropertyProcessable object, Object fieldName) { setContext(context); } } + } diff --git a/src/main/java/com/alibaba/fastjson/parser/Feature.java b/src/main/java/com/alibaba/fastjson/parser/Feature.java old mode 100755 new mode 100644 index ffea390d40..fc971d6c35 --- a/src/main/java/com/alibaba/fastjson/parser/Feature.java +++ b/src/main/java/com/alibaba/fastjson/parser/Feature.java @@ -125,7 +125,38 @@ public enum Feature { /** * @since 1.2.41, backport to 1.1.66.android */ - SupportAutoType + SupportAutoType, + + /** + * @since 1.2.42 + */ + NonStringKeyAsString, + + /** + * @since 1.2.45 + */ + CustomMapDeserializer, + + /** + * @since 1.2.55 + */ + ErrorOnEnumNotMatch, + + /** + * @since 1.2.68 + */ + SafeMode, + + /** + * @since 1.2.72 + */ + TrimStringFieldValue, + + /** + * @since 1.2.77 + * use HashMap instead of JSONObject, ArrayList instead of JSONArray + */ + UseNativeJavaObject ; Feature(){ diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java b/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java index 248eac66ec..4cb954556f 100644 --- a/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2019 Alibaba Group. + * + * 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. + */ package com.alibaba.fastjson.parser; import java.math.BigDecimal; @@ -10,7 +25,7 @@ public interface JSONLexer { char EOI = 0x1A; int NOT_MATCH = -1; int NOT_MATCH_NAME = -2; - int UNKNOWN = 0; + int UNKNOWN = 0; int OBJECT = 1; int ARRAY = 2; int VALUE = 3; @@ -52,7 +67,7 @@ public interface JSONLexer { String stringVal(); boolean isEnabled(int feature); - + boolean isEnabled(Feature feature); void config(Feature feature, boolean state); @@ -73,6 +88,8 @@ public interface JSONLexer { boolean isRef(); + String scanTypeName(SymbolTable symbolTable); + String numberString(); byte[] bytesValue(); @@ -95,14 +112,15 @@ public interface JSONLexer { void scanStringArray(Collection collection, char seperator); TimeZone getTimeZone(); - + void setTimeZone(TimeZone timeZone); - + Locale getLocale(); - + void setLocale(Locale locale); - + String info(); int getFeatures(); + void setFeatures(int features); } diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java b/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java old mode 100755 new mode 100644 index 28efd2c3f2..ca70c87ffa --- a/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2019 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.alibaba.fastjson.parser; import java.io.Closeable; -import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.math.MathContext; @@ -24,11 +23,11 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.util.IOUtils; -import com.alibaba.fastjson.util.TypeUtils; import static com.alibaba.fastjson.parser.JSONToken.*; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime; /** * @author wenshao[szujobs@hotmail.com] @@ -70,6 +69,7 @@ protected void lexError(String key, Object... args) { private final static ThreadLocal SBUF_LOCAL = new ThreadLocal(); protected String stringDefaultValue = null; + protected int nanos = 0; public JSONLexerBase(int features){ this.features = features; @@ -209,7 +209,7 @@ public final void nextToken() { } token = EOF; - pos = bp = eofPos; + eofPos = pos = bp; } else { if (ch <= 31 || ch == 127) { next(); @@ -266,6 +266,11 @@ public final void nextToken(int expect) { token = JSONToken.EOF; return; } + + if (ch == 'n') { + scanNullOrNew(false); + return; + } break; case JSONToken.LITERAL_INT: if (ch >= '0' && ch <= '9') { @@ -456,11 +461,11 @@ public final Number integerValue() throws NumberFormatException { // Accumulating negatively avoids surprises near MAX_VALUE digit = charAt(i++) - '0'; if (result < multmin) { - return new BigInteger(numberString()); + return new BigInteger(numberString(), 10); } result *= 10; if (result < limit + digit) { - return new BigInteger(numberString()); + return new BigInteger(numberString(), 10); } result -= digit; } @@ -480,7 +485,7 @@ public final Number integerValue() throws NumberFormatException { } return result; } else { /* Only got "-" */ - throw new NumberFormatException(numberString()); + throw new JSONException("illegal number format : " + numberString()); } } else { result = -result; @@ -969,18 +974,27 @@ public final void scanString() { putChar('\\'); break; case 'x': - char x1 = ch = next(); - char x2 = ch = next(); + char x1 = next(); + char x2 = next(); + + boolean hex1 = (x1 >= '0' && x1 <= '9') + || (x1 >= 'a' && x1 <= 'f') + || (x1 >= 'A' && x1 <= 'F'); + boolean hex2 = (x2 >= '0' && x2 <= '9') + || (x2 >= 'a' && x2 <= 'f') + || (x2 >= 'A' && x2 <= 'F'); + if (!hex1 || !hex2) { + throw new JSONException("invalid escape character \\x" + x1 + x2); + } - int x_val = digits[x1] * 16 + digits[x2]; - char x_char = (char) x_val; + char x_char = (char) (digits[x1] * 16 + digits[x2]); putChar(x_char); break; case 'u': - char u1 = ch = next(); - char u2 = ch = next(); - char u3 = ch = next(); - char u4 = ch = next(); + char u1 = next(); + char u2 = next(); + char u3 = next(); + char u4 = next(); int val = Integer.parseInt(new String(new char[] { u1, u2, u3, u4 }), 16); putChar((char) val); break; @@ -1101,6 +1115,10 @@ && charAt(np + 3) == 'e' // && charAt(np + 4) == 'f'; } + public String scanTypeName(SymbolTable symbolTable) { + return null; + } + protected final static char[] typeFieldName = ("\"" + JSON.DEFAULT_TYPE_KEY + "\":\"").toCharArray(); public final int scanType(String type) { @@ -1186,6 +1204,38 @@ public final boolean matchField(char[] fieldName) { return true; } + public int matchField(long fieldNameHash) { + throw new UnsupportedOperationException(); + } + + public boolean seekArrayToItem(int index) { + throw new UnsupportedOperationException(); + } + + public int seekObjectToField(long fieldNameHash, boolean deepScan) { + throw new UnsupportedOperationException(); + } + + public int seekObjectToField(long[] fieldNameHash) { + throw new UnsupportedOperationException(); + } + + public int seekObjectToFieldDeepScan(long fieldNameHash) { + throw new UnsupportedOperationException(); + } + + public void skipObject() { + throw new UnsupportedOperationException(); + } + + public void skipObject(boolean valid) { + throw new UnsupportedOperationException(); + } + + public void skipArray() { + throw new UnsupportedOperationException(); + } + public abstract int indexOf(char ch, int startIndex); public abstract String addSymbol(int offset, int len, int hash, final SymbolTable symbolTable); @@ -1310,8 +1360,6 @@ public String scanString(char expectNextChar) { } } - - final String strVal; for (;;) { if (chLocal == '"') { @@ -1363,12 +1411,17 @@ public String scanString(char expectNextChar) { bp += offset; this.ch = charAt(bp); matchStat = VALUE; + token = JSONToken.COMMA; return strVal; } else if (isWhitespace(chLocal)) { chLocal = charAt(bp + (offset++)); continue; } else { - matchStat = NOT_MATCH; + if (chLocal == ']') { + bp += offset; + this.ch = charAt(bp); + matchStat = NOT_MATCH; + } return strVal; } } @@ -1390,7 +1443,7 @@ public long scanFieldSymbol(char[] fieldName) { return 0; } - long hash = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; for (;;) { chLocal = charAt(bp + (offset++)); if (chLocal == '\"') { @@ -1399,7 +1452,78 @@ public long scanFieldSymbol(char[] fieldName) { } hash ^= chLocal; - hash *= 0x100000001b3L; + hash *= fnv1a_64_magic_prime; + + if (chLocal == '\\') { + matchStat = NOT_MATCH; + return 0; + } + } + + if (chLocal == ',') { + bp += offset; + this.ch = this.charAt(bp); + matchStat = VALUE; + return hash; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += offset; + this.ch = this.charAt(bp); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += offset; + this.ch = this.charAt(bp); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += offset; + this.ch = this.charAt(bp); + } else if (chLocal == EOI) { + token = JSONToken.EOF; + bp += (offset - 1); + ch = EOI; + } else { + matchStat = NOT_MATCH; + return 0; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return 0; + } + + return hash; + } + + public long scanEnumSymbol(char[] fieldName) { + matchStat = UNKNOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return 0; + } + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + if (chLocal != '"') { + matchStat = NOT_MATCH; + return 0; + } + + long hash = fnv1a_64_magic_hashcode; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal == '\"') { + chLocal = charAt(bp + (offset++)); + break; + } + + hash ^= ((chLocal >= 'A' && chLocal <= 'Z') ? (chLocal + 32) : chLocal); + hash *= fnv1a_64_magic_prime; if (chLocal == '\\') { matchStat = NOT_MATCH; @@ -1528,15 +1652,14 @@ public String scanSymbolWithSeperator(final SymbolTable symbolTable, char serper public Collection newCollectionByType(Class type){ if (type.isAssignableFrom(HashSet.class)) { - HashSet list = new HashSet(); - return list; + return new HashSet(); } else if (type.isAssignableFrom(ArrayList.class)) { - ArrayList list2 = new ArrayList(); - return list2; + return new ArrayList(); + } else if (type.isAssignableFrom(LinkedList.class)) { + return new LinkedList(); } else { try { - Collection list = (Collection) type.newInstance(); - return list; + return (Collection) type.newInstance(); } catch (Exception e) { throw new JSONException(e.getMessage(), e); } @@ -1692,7 +1815,7 @@ && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l' && charAt(bp + offset + 3) == seperator - ) { + ) { bp += 5; ch = charAt(bp); matchStat = VALUE_NULL; @@ -2408,7 +2531,7 @@ public final float scanFieldFloat(char[] fieldName) { float value; if (chLocal >= '0' && chLocal <= '9') { - int intVal = chLocal - '0'; + long intVal = chLocal - '0'; for (;;) { chLocal = charAt(bp + (offset++)); if (chLocal >= '0' && chLocal <= '9') { @@ -2419,7 +2542,7 @@ public final float scanFieldFloat(char[] fieldName) { } } - int power = 1; + long power = 1; boolean small = (chLocal == '.'); if (small) { chLocal = charAt(bp + (offset++)); @@ -2472,8 +2595,8 @@ public final float scanFieldFloat(char[] fieldName) { count = bp + offset - start - 1; } - if (!exp && count < 20) { - value = ((float) intVal) / power; + if ((!exp) && count < 17) { + value = (float) (((double) intVal) / power); if (negative) { value = -value; } @@ -2652,8 +2775,8 @@ public final float scanFloat(char seperator) { count = bp + offset - start - 1; } - if (!exp && count < 20) { - value = ((float) intVal) / power; + if ((!exp) && count < 17) { + value = (float) (((double) intVal) / power); if (negative) { value = -value; } @@ -2790,7 +2913,7 @@ public double scanDouble(char seperator) { count = bp + offset - start - 1; } - if (!exp && count < 20) { + if (!exp && count < 17) { value = ((double) intVal) / power; if (negative) { value = -value; @@ -2921,8 +3044,11 @@ public BigDecimal scanDecimal(char seperator) { count = bp + offset - start - 1; } + if (count > 65535) { + throw new JSONException("decimal overflow"); + } char[] chars = this.sub_chars(start, count); - value = new BigDecimal(chars); + value = new BigDecimal(chars, 0, chars.length, MathContext.UNLIMITED); } else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { matchStat = VALUE_NULL; value = null; @@ -3291,6 +3417,8 @@ public final float[][] scanFieldFloatArray2(char[] fieldName) { chLocal = charAt(bp + (offset++)); break; } + } else { + break; } } @@ -3427,7 +3555,7 @@ public final double scanFieldDouble(char[] fieldName) { count = bp + offset - start - 1; } - if (!exp && count < 20) { + if (!exp && count < 17) { value = ((double) intVal) / power; if (negative) { value = -value; @@ -3436,7 +3564,10 @@ public final double scanFieldDouble(char[] fieldName) { String text = this.subString(start, count); value = Double.parseDouble(text); } - } else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + } else if (chLocal == 'n' && + charAt(bp + offset) == 'u' && + charAt(bp + offset + 1) == 'l' && + charAt(bp + offset + 2) == 'l') { matchStat = VALUE_NULL; value = 0; offset += 3; @@ -3590,9 +3721,16 @@ public BigDecimal scanFieldDecimal(char[] fieldName) { count = bp + offset - start - 1; } + if (count > 65535) { + throw new JSONException("scan decimal overflow"); + } + char[] chars = this.sub_chars(start, count); - value = new BigDecimal(chars); - } else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + value = new BigDecimal(chars, 0, chars.length, MathContext.UNLIMITED); + } else if (chLocal == 'n' && + charAt(bp + offset) == 'u' && + charAt(bp + offset + 1) == 'l' && + charAt(bp + offset + 2) == 'l') { matchStat = VALUE_NULL; value = null; offset += 3; @@ -3690,10 +3828,17 @@ public BigInteger scanFieldBigInteger(char[] fieldName) { BigInteger value; if (chLocal >= '0' && chLocal <= '9') { long intVal = chLocal - '0'; + boolean overflow = false; + long temp; for (;;) { chLocal = charAt(bp + (offset++)); if (chLocal >= '0' && chLocal <= '9') { - intVal = intVal * 10 + (chLocal - '0'); + temp = intVal * 10 + (chLocal - '0'); + if (temp < intVal) { + overflow = true; + break; + } + intVal = temp; continue; } else { break; @@ -3715,16 +3860,23 @@ public BigInteger scanFieldBigInteger(char[] fieldName) { count = bp + offset - start - 1; } - if (count < 20 || (negative && count < 21)) { + if (!overflow && (count < 20 || (negative && count < 21))) { value = BigInteger.valueOf(negative ? -intVal : intVal); } else { // char[] chars = this.sub_chars(negative ? start + 1 : start, count); // value = new BigInteger(chars, ) + if (count > 65535) { + throw new JSONException("scanInteger overflow"); + } + String strVal = this.subString(start, count); - value = new BigInteger(strVal); + value = new BigInteger(strVal, 10); } - } else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + } else if (chLocal == 'n' && + charAt(bp + offset) == 'u' && + charAt(bp + offset + 1) == 'l' && + charAt(bp + offset + 2) == 'l') { matchStat = VALUE_NULL; value = null; offset += 3; @@ -4017,7 +4169,10 @@ public java.util.Date scanDate(char seperator) { } dateVal = new java.util.Date(millis); - } else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + } else if (chLocal == 'n' && + charAt(bp + offset) == 'u' && + charAt(bp + offset + 1) == 'l' && + charAt(bp + offset + 2) == 'l') { matchStat = VALUE_NULL; dateVal = null; offset += 3; @@ -4498,8 +4653,18 @@ public final void scanTrue() { } next(); - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI - || ch == '\f' || ch == '\b' || ch == ':' || ch == '/') { + if (ch == ' ' || + ch == ',' || + ch == '}' || + ch == ']' || + ch == '\n' || + ch == '\r' || + ch == '\t' || + ch == EOI || + ch == '\f' || + ch == '\b' || + ch == ':' || + ch == '/') { token = JSONToken.TRUE; } else { throw new JSONException("scan true error"); @@ -4507,6 +4672,10 @@ public final void scanTrue() { } public final void scanNullOrNew() { + scanNullOrNew(true); + } + + public final void scanNullOrNew(boolean acceptColon) { if (ch != 'n') { throw new JSONException("error parse null or new"); } @@ -4524,8 +4693,19 @@ public final void scanNullOrNew() { } next(); - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI - || ch == '\f' || ch == '\b') { + + if (ch == ' ' + || ch == ',' + || ch == '}' + || ch == ']' + || ch == '\n' + || ch == '\r' + || ch == '\t' + || ch == EOI + || (ch == ':' && acceptColon) + || ch == '\f' + || ch == '\b') { + token = JSONToken.NULL; } else { throw new JSONException("scan null error"); @@ -4543,8 +4723,16 @@ public final void scanNullOrNew() { } next(); - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI - || ch == '\f' || ch == '\b') { + if (ch == ' ' || + ch == ',' || + ch == '}' || + ch == ']' || + ch == '\n' || + ch == '\r' || + ch == '\t' || + ch == EOI || + ch == '\f' || + ch == '\b') { token = JSONToken.NEW; } else { throw new JSONException("scan new error"); @@ -4577,8 +4765,18 @@ public final void scanFalse() { } next(); - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI - || ch == '\f' || ch == '\b' || ch == ':' || ch == '/') { + if (ch == ' ' || + ch == ',' || + ch == '}' || + ch == ']' || + ch == '\n' || + ch == '\r' || + ch == '\t' || + ch == EOI || + ch == '\f' || + ch == '\b' || + ch == ':' || + ch == '/') { token = JSONToken.FALSE; } else { throw new JSONException("scan false error"); @@ -4732,7 +4930,12 @@ public boolean isBlankInput() { public final void skipWhitespace() { for (;;) { if (ch <= '/') { - if (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t' || ch == '\f' || ch == '\b') { + if (ch == ' ' || + ch == '\r' || + ch == '\n' || + ch == '\t' || + ch == '\f' || + ch == '\b') { next(); continue; } else if (ch == '/') { @@ -4840,7 +5043,20 @@ private void scanStringSingleQuote() { putChar('\\'); break; case 'x': - putChar((char) (digits[next()] * 16 + digits[next()])); + char x1 = next(); + char x2 = next(); + + boolean hex1 = (x1 >= '0' && x1 <= '9') + || (x1 >= 'a' && x1 <= 'f') + || (x1 >= 'A' && x1 <= 'F'); + boolean hex2 = (x2 >= '0' && x2 <= '9') + || (x2 >= 'a' && x2 <= 'f') + || (x2 >= 'A' && x2 <= 'F'); + if (!hex1 || !hex2) { + throw new JSONException("invalid escape character \\x" + x1 + x2); + } + + putChar((char) (digits[x1] * 16 + digits[x2])); break; case 'u': putChar((char) Integer.parseInt(new String(new char[] { next(), next(), next(), next() }), 16)); @@ -4872,8 +5088,12 @@ private void scanStringSingleQuote() { * Append a character to sbuf. */ protected final void putChar(char ch) { - if (sp == sbuf.length) { - char[] newsbuf = new char[sbuf.length * 2]; + if (sp >= sbuf.length) { + int len = sbuf.length * 2; + if (len < sp) { + len = sp + 1; + } + char[] newsbuf = new char[len]; System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); sbuf = newsbuf; } @@ -4892,6 +5112,12 @@ public final void scanHex() { np = bp; next(); + if (ch == '\'') { + next(); + token = JSONToken.HEX; + return; + } + for (int i = 0;;++i) { char ch = next(); if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) { @@ -4942,6 +5168,10 @@ public final void scanNumber() { } } + if (sp > 65535) { + throw new JSONException("scanNumber overflow"); + } + if (ch == 'L') { sp++; next(); @@ -5071,7 +5301,13 @@ public final Number decimalValue(boolean decimal) { public static boolean isWhitespace(char ch) { // 专门调整了判断顺序 - return ch <= ' ' && (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b'); + return ch <= ' ' && + (ch == ' ' || + ch == '\n' || + ch == '\r' || + ch == '\t' || + ch == '\f' || + ch == '\b'); } protected static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10; @@ -5110,4 +5346,8 @@ public boolean matchField2(char[] fieldName) { public int getFeatures() { return this.features; } + + public void setFeatures(int features) { + this.features = features; + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONReaderScanner.java b/src/main/java/com/alibaba/fastjson/parser/JSONReaderScanner.java index 06165bb798..4781c9916a 100644 --- a/src/main/java/com/alibaba/fastjson/parser/JSONReaderScanner.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONReaderScanner.java @@ -20,6 +20,7 @@ import java.io.Reader; import java.io.StringReader; import java.math.BigDecimal; +import java.math.MathContext; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; @@ -296,7 +297,11 @@ public final BigDecimal decimalValue() { sp--; } - return new BigDecimal(buf, offset, sp); + if (sp > 65535) { + throw new JSONException("decimal overflow"); + } + + return new BigDecimal(buf, offset, sp, MathContext.UNLIMITED); } public void close() { @@ -312,7 +317,7 @@ public void close() { @Override public boolean isEOF() { - return bufLength == -1 || bp == buf.length || ch == EOI && bp + 1 == buf.length; + return bufLength == -1 || bp == buf.length || ch == EOI && bp + 1 >= buf.length; } public final boolean isBlankInput() { diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java b/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java index e1241901cc..c6b26e6be8 100644 --- a/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java @@ -15,20 +15,17 @@ */ package com.alibaba.fastjson.parser; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashSet; -import java.util.TimeZone; - import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.util.ASMUtils; import com.alibaba.fastjson.util.IOUtils; -import com.alibaba.fastjson.util.TypeUtils; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.*; + +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime; //这个类,为了性能优化做了很多特别处理,一切都是为了性能!!! @@ -131,7 +128,12 @@ public byte[] bytesValue() { return bytes; } - return IOUtils.decodeBase64(text, np + 1, sp); + if (!hasSpecial) { + return IOUtils.decodeBase64(text, np + 1, sp); + } else { + String escapedText = new String(sbuf, 0, sp); + return IOUtils.decodeBase64(escapedText); + } } /** @@ -190,14 +192,18 @@ public final BigDecimal decimalValue() { sp--; } + if (sp > 65535) { + throw new JSONException("decimal overflow"); + } + int offset = np, count = sp; if (count < sbuf.length) { text.getChars(offset, offset + count, sbuf, 0); - return new BigDecimal(sbuf, 0, count); + return new BigDecimal(sbuf, 0, count, MathContext.UNLIMITED); } else { char[] chars = new char[count]; text.getChars(offset, offset + count, chars, 0); - return new BigDecimal(chars); + return new BigDecimal(chars, 0, chars.length, MathContext.UNLIMITED); } } @@ -280,6 +286,15 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { M1 = c6; d0 = c8; d1 = charAt(bp + 9); + } else if (c4 == '-' && c6 == '-') { + y0 = c0; + y1 = c1; + y2 = c2; + y3 = c3; + M0 = '0'; + M1 = c5; + d0 = '0'; + d1 = c7; } else { y0 = c0; y1 = c1; @@ -378,17 +393,24 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { char y0, y1, y2, y3, M0, M1, d0, d1; if ((c4 == '-' && c7 == '-') // cn || (c4 == '/' && c7 == '/') // tw yyyy/mm/dd - ) { + ) { y0 = c0; y1 = c1; y2 = c2; y3 = c3; M0 = c5; M1 = c6; - d0 = c8; - d1 = c9; + + if (c9 == ' ') { + d0 = '0'; + d1 = c8; + date_len = 9; + } else { + d0 = c8; + d1 = c9; + } } else if ((c4 == '-' && c6 == '-') // cn yyyy-m-dd - ) { + ) { y0 = c0; y1 = c1; y2 = c2; @@ -407,7 +429,7 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { } } else if ((c2 == '.' && c5 == '.') // de dd.mm.yyyy || (c2 == '-' && c5 == '-') // in dd-mm-yyyy - ) { + ) { d0 = c0; d1 = c1; M0 = c3; @@ -416,6 +438,16 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { y1 = c7; y2 = c8; y3 = c9; + } else if (c8 == 'T') { + y0 = c0; + y1 = c1; + y2 = c2; + y3 = c3; + M0 = c4; + M1 = c5; + d0 = c6; + d1 = c7; + date_len = 8; } else { if (c4 == '年' || c4 == '년') { y0 = c0; @@ -463,7 +495,32 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { setCalendar(y0, y1, y2, y3, M0, M1, d0, d1); char t = charAt(bp + date_len); - if (t == 'T' || (t == ' ' && !strict)) { + if (t == 'T' && rest == 16 && date_len == 8 && charAt(bp + 15) == 'Z') { + char h0 = charAt(bp + date_len + 1); + char h1 = charAt(bp + date_len + 2); + char m0 = charAt(bp + date_len + 3); + char m1 = charAt(bp + date_len + 4); + char s0 = charAt(bp + date_len + 5); + char s1 = charAt(bp + date_len + 6); + + if (!checkTime(h0, h1, m0, m1, s0, s1)) { + return false; + } + + setTime(h0, h1, m0, m1, s0, s1); + calendar.set(Calendar.MILLISECOND, 0); + + if (calendar.getTimeZone().getRawOffset() != 0) { + String[] timeZoneIDs = TimeZone.getAvailableIDs(0); + if (timeZoneIDs.length > 0) { + TimeZone timeZone = TimeZone.getTimeZone(timeZoneIDs[0]); + calendar.setTimeZone(timeZone); + } + } + + token = JSONToken.LITERAL_ISO8601_DATE; + return true; + } else if (t == 'T' || (t == ' ' && !strict)) { if (rest < date_len + 9) { // "0000-00-00T00:00:00".length() return false; } @@ -516,57 +573,46 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { setTime(h0, h1, m0, m1, s0, s1); char dot = charAt(bp + date_len + 9); - if (dot == '.') { - if (rest < date_len + 11) { // // 0000-00-00T00:00:00.000 + int millisLen = -1; // 有可能没有毫秒区域,没有毫秒区域的时候下一个字符位置有可能是'Z'、'+'、'-' + int millis = 0; + if (dot == '.') { // 0000-00-00T00:00:00.000 + if (rest < date_len + 11) { return false; } - } else { - calendar.set(Calendar.MILLISECOND, 0); - - ch = charAt(bp += (date_len + 9)); - - token = JSONToken.LITERAL_ISO8601_DATE; - if (dot == 'Z') {// UTC - // bugfix https://github.com/alibaba/fastjson/issues/376 - if (calendar.getTimeZone().getRawOffset() != 0) { - String[] timeZoneIDs = TimeZone.getAvailableIDs(0);// 没有+ 和 - 默认相对0 - if (timeZoneIDs.length > 0) { - TimeZone timeZone = TimeZone.getTimeZone(timeZoneIDs[0]); - calendar.setTimeZone(timeZone); - } - } + char S0 = charAt(bp + date_len + 10); + if (S0 < '0' || S0 > '9') { + return false; } - return true; - } + millis = S0 - '0'; + millisLen = 1; - char S0 = charAt(bp + date_len + 10); - if (S0 < '0' || S0 > '9') { - return false; - } - int millis = S0 - '0'; - int millisLen = 1; - - if (rest > date_len + 11) { - char S1 = charAt(bp + date_len + 11); - if (S1 >= '0' && S1 <= '9') { - millis = millis * 10 + (S1 - '0'); - millisLen = 2; + if (rest > date_len + 11) { + char S1 = charAt(bp + date_len + 11); + if (S1 >= '0' && S1 <= '9') { + millis = millis * 10 + (S1 - '0'); + millisLen = 2; + } } - } - if (millisLen == 2) { - char S2 = charAt(bp + date_len + 12); - if (S2 >= '0' && S2 <= '9') { - millis = millis * 10 + (S2 - '0'); - millisLen = 3; + if (millisLen == 2) { + char S2 = charAt(bp + date_len + 12); + if (S2 >= '0' && S2 <= '9') { + millis = millis * 10 + (S2 - '0'); + millisLen = 3; + } } } - calendar.set(Calendar.MILLISECOND, millis); int timzeZoneLength = 0; char timeZoneFlag = charAt(bp + date_len + 10 + millisLen); + + if (timeZoneFlag == ' ') { + millisLen++; + timeZoneFlag = charAt(bp + date_len + 10 + millisLen); + } + if (timeZoneFlag == '+' || timeZoneFlag == '-') { char t0 = charAt(bp + date_len + 10 + millisLen + 1); if (t0 < '0' || t0 > '1') { @@ -582,14 +628,34 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { char t3 = '0', t4 = '0'; if (t2 == ':') { // ThreeLetterISO8601TimeZone t3 = charAt(bp + date_len + 10 + millisLen + 4); - if (t3 != '0' && t3 != '3') { - return false; - } - t4 = charAt(bp + date_len + 10 + millisLen + 5); - if (t4 != '0') { - return false; + + if(t3 == '4' && t4 == '5') { + // handle some special timezones like xx:45 + + if (t0 == '1' && (t1 == '2' || t1 == '3')) { + // NZ-CHAT => +12:45 + // Pacific/Chatham => +12:45 + // NZ-CHAT => +13:45 (DST) + // Pacific/Chatham => +13:45 (DST) + } else if (t0 == '0' && (t1 == '5' || t1 == '8')) { + // Asia/Kathmandu => +05:45 + // Asia/Katmandu => +05:45 + // Australia/Eucla => +08:45 + } else { + return false; + } + } else { + //handle normal timezone like xx:00 and xx:30 + if (t3 != '0' && t3 != '3') { + return false; + } + + if (t4 != '0') { + return false; + } } + timzeZoneLength = 6; } else if (t2 == '0') { // TwoLetterISO8601TimeZone t3 = charAt(bp + date_len + 10 + millisLen + 4); @@ -597,6 +663,14 @@ private boolean scanISO8601DateIfMatch(boolean strict, int rest) { return false; } timzeZoneLength = 5; + } else if (t2 == '3' && charAt(bp + date_len + 10 + millisLen + 4) == '0') { + t3 = '3'; + t4 = '0'; + timzeZoneLength = 5; + } else if (t2 == '4' && charAt(bp + date_len + 10 + millisLen + 4) == '5') { + t3 = '4'; + t4 = '5'; + timzeZoneLength = 5; } else { timzeZoneLength = 3; } @@ -647,11 +721,7 @@ protected void setTimeZone(char timeZoneFlag, char t0, char t1, char t3, char t4 } if (calendar.getTimeZone().getRawOffset() != timeZoneOffset) { - String[] timeZoneIDs = TimeZone.getAvailableIDs(timeZoneOffset); - if (timeZoneIDs.length > 0) { - TimeZone timeZone = TimeZone.getTimeZone(timeZoneIDs[0]); - calendar.setTimeZone(timeZone); - } + calendar.setTimeZone(new SimpleTimeZone(timeZoneOffset, Integer.toString(timeZoneOffset))); } } @@ -711,7 +781,7 @@ private void setCalendar(char y0, char y1, char y2, char y3, char M0, char M1, c } static boolean checkDate(char y0, char y1, char y2, char y3, char M0, char M1, int d0, int d1) { - if (y0 < '1' || y0 > '3') { + if (y0 < '0' || y0 > '9') { return false; } if (y1 < '0' || y1 > '9') { @@ -757,7 +827,7 @@ static boolean checkDate(char y0, char y1, char y2, char y3, char M0, char M1, i @Override public boolean isEOF() { - return bp == len || ch == EOI && bp + 1 == len; + return bp == len || (ch == EOI && bp + 1 >= len); } public int scanFieldInt(char[] fieldName) { @@ -791,7 +861,13 @@ public int scanFieldInt(char[] fieldName) { for (;;) { ch = charAt(index++); if (ch >= '0' && ch <= '9') { - value = value * 10 + (ch - '0'); + int value_10 = value * 10; + if (value_10 < value) { + matchStat = NOT_MATCH; + return 0; + } + + value = value_10 + (ch - '0'); } else if (ch == '.') { matchStat = NOT_MATCH; return 0; @@ -878,10 +954,15 @@ public String scanFieldString(char[] fieldName) { int startPos = this.bp; char startChar = this.ch; + for (;;) { if (!charArrayCompare(text, bp, fieldName)) { if (isWhitespace(ch)) { next(); + + while (isWhitespace(ch)) { + next(); + } continue; } matchStat = NOT_MATCH_NAME; @@ -893,11 +974,19 @@ public String scanFieldString(char[] fieldName) { int index = bp + fieldName.length; + int spaceCount = 0; char ch = charAt(index++); if (ch != '"') { - matchStat = NOT_MATCH; + while (isWhitespace(ch)) { + spaceCount++; + ch = charAt(index++); + } - return stringDefaultValue(); + if (ch != '"') { + matchStat = NOT_MATCH; + + return stringDefaultValue(); + } } final String strVal; @@ -925,12 +1014,16 @@ public String scanFieldString(char[] fieldName) { endIndex = indexOf('"', endIndex + 1); } - int chars_len = endIndex - (bp + fieldName.length + 1); - char[] chars = sub_chars(bp + fieldName.length + 1, chars_len); + int chars_len = endIndex - (bp + fieldName.length + 1 + spaceCount); + char[] chars = sub_chars(bp + fieldName.length + 1 + spaceCount, chars_len); stringVal = readString(chars, chars_len); } + if ((this.features & Feature.TrimStringFieldValue.mask) != 0) { + stringVal = stringVal.trim(); + } + ch = charAt(endIndex + 1); for (;;) { @@ -1100,20 +1193,40 @@ public java.util.Date scanFieldDate(char[] fieldName) { public long scanFieldSymbol(char[] fieldName) { matchStat = UNKNOWN; - if (!charArrayCompare(text, bp, fieldName)) { - matchStat = NOT_MATCH_NAME; - return 0; + for (;;) { + if (!charArrayCompare(text, bp, fieldName)) { + if (isWhitespace(ch)) { + next(); + + while (isWhitespace(ch)) { + next(); + } + continue; + } + matchStat = NOT_MATCH_NAME; + return 0; + } else { + break; + } } int index = bp + fieldName.length; - + int spaceCount = 0; char ch = charAt(index++); if (ch != '"') { - matchStat = NOT_MATCH; - return 0; + while (isWhitespace(ch)) { + ch = charAt(index++); + spaceCount++; + } + + if (ch != '"') { + matchStat = NOT_MATCH; + + return 0; + } } - long hash = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; for (;;) { ch = charAt(index++); if (ch == '\"') { @@ -1126,7 +1239,7 @@ public long scanFieldSymbol(char[] fieldName) { } hash ^= ch; - hash *= 0x100000001b3L; + hash *= fnv1a_64_magic_prime; } for (;;) { @@ -1167,27 +1280,17 @@ public long scanFieldSymbol(char[] fieldName) { return hash; } - public Collection newCollectionByType(Class type){ - if (type.isAssignableFrom(HashSet.class)) { - HashSet list = new HashSet(); - return list; - } else if (type.isAssignableFrom(ArrayList.class)) { - ArrayList list2 = new ArrayList(); - return list2; - } else { - try { - Collection list = (Collection) type.newInstance(); - return list; - } catch (Exception e) { - throw new JSONException(e.getMessage(), e); - } - } - } - @SuppressWarnings("unchecked") public Collection scanFieldStringArray(char[] fieldName, Class type) { matchStat = UNKNOWN; + while (ch == '\n' || ch == ' ') { + int index = ++bp; + ch = (index >= this.len ? // + EOI // + : text.charAt(index)); + } + if (!charArrayCompare(text, bp, fieldName)) { matchStat = NOT_MATCH_NAME; return null; @@ -1207,6 +1310,9 @@ public Collection scanFieldStringArray(char[] fieldName, Class type) // } // } + int startPos = this.bp; + char startChar = this.ch; + int index = bp + fieldName.length; char ch = charAt(index++); @@ -1328,6 +1434,8 @@ public Collection scanFieldStringArray(char[] fieldName, Class type) matchStat = END; } else { + this.ch = startChar; + bp = startPos; matchStat = NOT_MATCH; return null; } @@ -1517,14 +1625,14 @@ public boolean scanFieldBoolean(char[] fieldName) { ch = charAt(bp); value = false; } else if (ch == '1') { - if (quote && charAt(index++) != '"') { - matchStat = NOT_MATCH; - return false; - } + if (quote && charAt(index++) != '"') { + matchStat = NOT_MATCH; + return false; + } - bp = index; - ch = charAt(bp); - value = true; + bp = index; + ch = charAt(bp); + value = true; } else if (ch == '0') { if (quote && charAt(index++) != '"') { matchStat = NOT_MATCH; @@ -1586,6 +1694,7 @@ public boolean scanFieldBoolean(char[] fieldName) { public final int scanInt(char expectNext) { matchStat = UNKNOWN; + final int mark = bp; int offset = bp; char chLocal = charAt(offset++); @@ -1610,7 +1719,12 @@ public final int scanInt(char expectNext) { for (;;) { chLocal = charAt(offset++); if (chLocal >= '0' && chLocal <= '9') { - value = value * 10 + (chLocal - '0'); + int value_10 = value * 10; + if (value_10 < value) { + throw new JSONException("parseInt error : " + + subString(mark, offset - 1)); + } + value = value_10 + (chLocal - '0'); } else if (chLocal == '.') { matchStat = NOT_MATCH; return 0; @@ -1767,7 +1881,7 @@ public double scanDouble(char seperator) { count = offset - start - 1; } - if (!exp && count < 20) { + if (!exp && count < 18) { value = ((double) intVal) / power; if (negative) { value = -value; @@ -2059,11 +2173,36 @@ protected final void arrayCopy(int srcPos, char[] dest, int destPos, int length) } public String info() { - return "pos " + bp // - + ", json : " // - + (text.length() < 65536 // - ? text // - : text.substring(0, 65536)); + StringBuilder buf = new StringBuilder(); + +// buf.append("pos ").append(bp); +// return "pos " + bp // +// + ", json : " // +// + (text.length() < 65536 // +// ? text // +// : text.substring(0, 65536)); + + int line = 1; + int column = 1; + for (int i = 0; i < bp; ++i, column++) { + char ch = text.charAt(i); + if (ch == '\n') { + column = 1; + line++; + } + } + + buf.append("pos ").append(bp) + .append(", line ").append(line) + .append(", column ").append(column); + + if (text.length() < 65535) { + buf.append(text); + } else { + buf.append(text.substring(0, 65535)); + } + + return buf.toString(); } // for hsf support @@ -2194,7 +2333,724 @@ public boolean matchField2(char[] fieldName) { matchStat = NOT_MATCH_NAME; return false; } + } + + public final void skipObject() { + skipObject(false); + } + + public final void skipObject(boolean valid) { + boolean quote = false; + int braceCnt = 0; + int i = bp; + for (; i < text.length(); ++i) { + final char ch = text.charAt(i); + if (ch == '\\') { + if (i < len - 1) { + ++i; + continue; + } else { + this.ch = ch; + this.bp = i; + throw new JSONException("illegal str, " + info()); + } + } else if (ch == '"') { + quote = !quote; + } else if (ch == '{') { + if (quote) { + continue; + } + braceCnt++; + } else if (ch == '}') { + if (quote) { + continue; + } else { + braceCnt--; + } + if (braceCnt == -1) { + this.bp = i + 1; + if (this.bp == text.length()) { + this.ch = EOI; + this.token = JSONToken.EOF; + return; + } + this.ch = text.charAt(this.bp); + if (this.ch == ',') { + token = JSONToken.COMMA; + int index = ++bp; + this.ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + return; + } else if (this.ch == '}') { + token = JSONToken.RBRACE; + next(); + return; + } else if (this.ch == ']') { + token = JSONToken.RBRACKET; + next(); + return; + } else { + nextToken(JSONToken.COMMA); + } + return; + } + } + } + + for (int j = 0; j < bp; j++) { + if (j < text.length() && text.charAt(j) == ' ') { + i++; + } + } + + if (i == text.length()) { + throw new JSONException("illegal str, " + info()); + } + } + + public final void skipArray() { + skipArray(false); + } + + public final void skipArray(boolean valid) { + boolean quote = false; + int bracketCnt = 0; + int i = bp; + for (; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch == '\\') { + if (i < len - 1) { + ++i; + continue; + } else { + this.ch = ch; + this.bp = i; + throw new JSONException("illegal str, " + info()); + } + } else if (ch == '"') { + quote = !quote; + } else if (ch == '[') { + if (quote) { + continue; + } + bracketCnt++; + } else if (ch == '{' && valid) { + { + int index = ++bp; + this.ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + + skipObject(valid); + } else if (ch == ']') { + if (quote) { + continue; + } else { + bracketCnt--; + } + if (bracketCnt == -1) { + this.bp = i + 1; + if (this.bp == text.length()) { + this.ch = EOI; + token = JSONToken.EOF; + return; + } + this.ch = text.charAt(this.bp); + nextToken(JSONToken.COMMA); + return; + } + } + } + + if (i == text.length()) { + throw new JSONException("illegal str, " + info()); + } + } + + public final void skipString() { + if (ch == '"') { + for (int i = bp + 1; i < text.length(); ++i) { + char c = text.charAt(i); + if (c == '\\') { + if (i < len - 1) { + ++i; + continue; + } + } else if (c == '"') { + this.ch = text.charAt(bp = i + 1); + return; + } + } + throw new JSONException("unclosed str"); + } else { + throw new UnsupportedOperationException(); + } + } + + public boolean seekArrayToItem(int index) { + if (index < 0) { + throw new IllegalArgumentException("index must > 0, but " + index); + } + + if (token == JSONToken.EOF) { + return false; + } + if (token != JSONToken.LBRACKET) { + throw new UnsupportedOperationException(); + } +// nextToken(); + + for (int i = 0; i < index; ++i) { + skipWhitespace(); + if (ch == '"' || ch == '\'') { + skipString(); + if (ch == ',') { + next(); + continue; + } else if (ch == ']') { + next(); + nextToken(JSONToken.COMMA); + return false; + } else { + throw new JSONException("illegal json."); + } + } else if (ch == '{') { + next(); + token = JSONToken.LBRACE; + skipObject(false); + } else if (ch == '[') { + next(); + token = JSONToken.LBRACKET; + skipArray(false); + } else { + boolean match = false; + for (int j = bp + 1; j < text.length(); ++j) { + char c = text.charAt(j); + if (c == ',') { + match = true; + bp = j + 1; + ch = charAt(bp); + break; + } else if (c == ']') { + bp = j + 1; + ch = charAt(bp); + nextToken(); + return false; + } + } + + if (!match) { + throw new JSONException("illegal json."); + } + + continue; + } + + if (token == JSONToken.COMMA) { + continue; + } else if (token == JSONToken.RBRACKET) { + return false; + } else { + throw new UnsupportedOperationException(); + } + + } + + nextToken(); + return true; + } + + public int seekObjectToField(long fieldNameHash, boolean deepScan) { + if (token == JSONToken.EOF) { + return JSONLexer.NOT_MATCH; + } + + if (token == JSONToken.RBRACE || token == JSONToken.RBRACKET) { + nextToken(); + return JSONLexer.NOT_MATCH; + } + + if (token != JSONToken.LBRACE && token != JSONToken.COMMA) { + throw new UnsupportedOperationException(JSONToken.name(token)); + } + + for (;;) { + if (ch == '}') { + next(); + nextToken(); + return JSONLexer.NOT_MATCH; + } + if (ch == EOI) { + return JSONLexer.NOT_MATCH; + } + + if (ch != '"') { + skipWhitespace(); + } + + long hash; + if (ch == '"') { + hash = fnv1a_64_magic_hashcode; + + for (int i = bp + 1; i < text.length(); ++i) { + char c = text.charAt(i); + if (c == '\\') { + ++i; + if (i == text.length()) { + throw new JSONException("unclosed str, " + info()); + } + c = text.charAt(i); + } + + if (c == '"') { + bp = i + 1; + ch = (bp >= text.length() // + ? EOI // + : text.charAt(bp)); + break; + } + + hash ^= c; + hash *= fnv1a_64_magic_prime; + } + } else { + throw new UnsupportedOperationException(); + } + + if (hash == fieldNameHash) { + if (ch != ':') { + skipWhitespace(); + } + if (ch == ':') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + if (ch == ',') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + token = JSONToken.COMMA; + } else if (ch == ']') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + token = JSONToken.RBRACKET; + } else if (ch == '}') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + token = JSONToken.RBRACE; + } else if (ch >= '0' && ch <= '9') { + sp = 0; + pos = bp; + scanNumber(); + } else { + nextToken(JSONToken.LITERAL_INT); + } + } + return VALUE; + } + + if (ch != ':') { + skipWhitespace(); + } + + if (ch == ':') { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } else { + throw new JSONException("illegal json, " + info()); + } + + if (ch != '"' + && ch != '\'' + && ch != '{' + && ch != '[' + && ch != '0' + && ch != '1' + && ch != '2' + && ch != '3' + && ch != '4' + && ch != '5' + && ch != '6' + && ch != '7' + && ch != '8' + && ch != '9' + && ch != '+' + && ch != '-') { + skipWhitespace(); + } + + // skip fieldValues + if (ch == '-' || ch == '+' || (ch >= '0' && ch <= '9')) { + next(); + while (ch >= '0' && ch <= '9') { + next(); + } + + // scale + if (ch == '.') { + next(); + while (ch >= '0' && ch <= '9') { + next(); + } + } + + // exp + if (ch == 'E' || ch == 'e') { + next(); + if (ch == '-' || ch == '+') { + next(); + } + while (ch >= '0' && ch <= '9') { + next(); + } + } + + if (ch != ',') { + skipWhitespace(); + } + if (ch == ',') { + next(); + } + } else if (ch == '"') { + skipString(); + + if (ch != ',' && ch != '}') { + skipWhitespace(); + } + + if (ch == ',') { + next(); + } + } else if (ch == 't') { + next(); + if (ch == 'r') { + next(); + if (ch == 'u') { + next(); + if (ch == 'e') { + next(); + } + } + } + + if (ch != ',' && ch != '}') { + skipWhitespace(); + } + + if (ch == ',') { + next(); + } + } else if (ch == 'n') { + next(); + if (ch == 'u') { + next(); + if (ch == 'l') { + next(); + if (ch == 'l') { + next(); + } + } + } + + if (ch != ',' && ch != '}') { + skipWhitespace(); + } + + if (ch == ',') { + next(); + } + } else if (ch == 'f') { + next(); + if (ch == 'a') { + next(); + if (ch == 'l') { + next(); + if (ch == 's') { + next(); + if (ch == 'e') { + next(); + } + } + } + } + + if (ch != ',' && ch != '}') { + skipWhitespace(); + } + + if (ch == ',') { + next(); + } + } else if (ch == '{') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + if (deepScan) { + token = JSONToken.LBRACE; + return OBJECT; + } + + skipObject(false); + if (token == JSONToken.RBRACE) { + return JSONLexer.NOT_MATCH; + } + } else if (ch == '[') { + next(); + if (deepScan) { + token = JSONToken.LBRACKET; + return ARRAY; + } + skipArray(false); + if (token == JSONToken.RBRACE) { + return JSONLexer.NOT_MATCH; + } + } else { + throw new UnsupportedOperationException(); + } + } + } + + public int seekObjectToField(long[] fieldNameHash) { + if (token != JSONToken.LBRACE && token != JSONToken.COMMA) { + throw new UnsupportedOperationException(); + } + + for (;;) { + if (ch == '}') { + next(); + nextToken(); + this.matchStat = JSONLexer.NOT_MATCH; + return -1; + } + if (ch == EOI) { + this.matchStat = JSONLexer.NOT_MATCH; + return -1; + } + + if (ch != '"') { + skipWhitespace(); + } + + long hash; + if (ch == '"') { + hash = fnv1a_64_magic_hashcode; + + for (int i = bp + 1; i < text.length(); ++i) { + char c = text.charAt(i); + if (c == '\\') { + ++i; + if (i == text.length()) { + throw new JSONException("unclosed str, " + info()); + } + c = text.charAt(i); + } + + if (c == '"') { + bp = i + 1; + ch = (bp >= text.length() // + ? EOI // + : text.charAt(bp)); + break; + } + + hash ^= c; + hash *= fnv1a_64_magic_prime; + } + } else { + throw new UnsupportedOperationException(); + } + + int matchIndex = -1; + for (int i = 0; i < fieldNameHash.length; i++) { + if (hash == fieldNameHash[i]) { + matchIndex = i; + break; + } + } + + if (matchIndex != -1) { + if (ch != ':') { + skipWhitespace(); + } + if (ch == ':') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + if (ch == ',') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + token = JSONToken.COMMA; + } else if (ch == ']') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + token = JSONToken.RBRACKET; + } else if (ch == '}') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + token = JSONToken.RBRACE; + } else if (ch >= '0' && ch <= '9') { + sp = 0; + pos = bp; + scanNumber(); + } else { + nextToken(JSONToken.LITERAL_INT); + } + } + + matchStat = VALUE; + return matchIndex; + } + + if (ch != ':') { + skipWhitespace(); + } + + if (ch == ':') { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } else { + throw new JSONException("illegal json, " + info()); + } + + if (ch != '"' + && ch != '\'' + && ch != '{' + && ch != '[' + && ch != '0' + && ch != '1' + && ch != '2' + && ch != '3' + && ch != '4' + && ch != '5' + && ch != '6' + && ch != '7' + && ch != '8' + && ch != '9' + && ch != '+' + && ch != '-') { + skipWhitespace(); + } + + // skip fieldValues + if (ch == '-' || ch == '+' || (ch >= '0' && ch <= '9')) { + next(); + while (ch >= '0' && ch <= '9') { + next(); + } + + // scale + if (ch == '.') { + next(); + while (ch >= '0' && ch <= '9') { + next(); + } + } + + // exp + if (ch == 'E' || ch == 'e') { + next(); + if (ch == '-' || ch == '+') { + next(); + } + while (ch >= '0' && ch <= '9') { + next(); + } + } + + if (ch != ',') { + skipWhitespace(); + } + if (ch == ',') { + next(); + } + } else if (ch == '"') { + skipString(); + + if (ch != ',' && ch != '}') { + skipWhitespace(); + } + + if (ch == ',') { + next(); + } + } else if (ch == '{') { + { + int index = ++bp; + ch = (index >= text.length() // + ? EOI // + : text.charAt(index)); + } + + skipObject(false); + } else if (ch == '[') { + next(); + + skipArray(false); + } else { + throw new UnsupportedOperationException(); + } + } + } + + public String scanTypeName(SymbolTable symbolTable) { + if (text.startsWith("\"@type\":\"", bp)) { + int p = text.indexOf('"', bp + 9); + if (p != -1) { + bp += 9; + int h = 0; + for (int i = bp; i < p; i++) { + h = 31 * h + text.charAt(i); + } + String typeName = addSymbol(bp, p - bp, h, symbolTable); + char separator = text.charAt(p + 1); + if (separator != ',' && separator != ']') { + return null; + } + bp = p + 2; + ch = text.charAt(bp); + return typeName; + } + } + return null; } } diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONToken.java b/src/main/java/com/alibaba/fastjson/parser/JSONToken.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/parser/ParseContext.java b/src/main/java/com/alibaba/fastjson/parser/ParseContext.java old mode 100755 new mode 100644 index 2b215cdaa5..2b43cecb54 --- a/src/main/java/com/alibaba/fastjson/parser/ParseContext.java +++ b/src/main/java/com/alibaba/fastjson/parser/ParseContext.java @@ -7,6 +7,7 @@ public class ParseContext { public Object object; public final ParseContext parent; public final Object fieldName; + public final int level; public Type type; private transient String path; @@ -14,6 +15,7 @@ public ParseContext(ParseContext parent, Object object, Object fieldName){ this.parent = parent; this.object = object; this.fieldName = fieldName; + this.level = parent == null ? 0 : parent.level + 1; } public String toString() { diff --git a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java index 8e11868e71..bd11a3dd15 100644 --- a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java +++ b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java @@ -15,18 +15,10 @@ */ package com.alibaba.fastjson.parser; -import java.io.Closeable; -import java.io.File; -import java.io.Serializable; +import java.io.*; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; +import java.lang.reflect.*; import java.math.BigDecimal; import java.math.BigInteger; import java.net.Inet4Address; @@ -38,23 +30,11 @@ import java.nio.charset.Charset; import java.security.AccessControlException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Currency; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeMap; -import java.util.UUID; +import java.util.*; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicIntegerArray; @@ -64,29 +44,47 @@ import java.util.regex.Pattern; import com.alibaba.fastjson.*; +import com.alibaba.fastjson.annotation.JSONCreator; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.asm.ClassReader; +import com.alibaba.fastjson.asm.TypeCollector; import com.alibaba.fastjson.parser.deserializer.*; import com.alibaba.fastjson.serializer.*; +import com.alibaba.fastjson.spi.Module; +import com.alibaba.fastjson.support.moneta.MonetaCodec; import com.alibaba.fastjson.util.*; +import com.alibaba.fastjson.util.IdentityHashMap; +import com.alibaba.fastjson.util.ServiceLoader; -import javax.sql.DataSource; import javax.xml.datatype.XMLGregorianCalendar; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime; + /** * @author wenshao[szujobs@hotmail.com] */ public class ParserConfig { - public final static String DENY_PROPERTY = "fastjson.parser.deny"; - public final static String AUTOTYPE_ACCEPT = "fastjson.parser.autoTypeAccept"; - public final static String AUTOTYPE_SUPPORT_PROPERTY = "fastjson.parser.autoTypeSupport"; - - public static final String[] DENYS; + public static final String DENY_PROPERTY_INTERNAL = "fastjson.parser.deny.internal"; + public static final String DENY_PROPERTY = "fastjson.parser.deny"; + public static final String AUTOTYPE_ACCEPT = "fastjson.parser.autoTypeAccept"; + public static final String AUTOTYPE_SUPPORT_PROPERTY = "fastjson.parser.autoTypeSupport"; + public static final String SAFE_MODE_PROPERTY = "fastjson.parser.safeMode"; + + public static final String[] DENYS_INTERNAL; + public static final String[] DENYS; private static final String[] AUTO_TYPE_ACCEPT_LIST; - public static final boolean AUTO_SUPPORT; + public static final boolean AUTO_SUPPORT; + public static final boolean SAFE_MODE; + private static final long[] INTERNAL_WHITELIST_HASHCODES; static { + { + String property = IOUtils.getStringProperty(DENY_PROPERTY_INTERNAL); + DENYS_INTERNAL = splitItemsFormProperty(property); + } { String property = IOUtils.getStringProperty(DENY_PROPERTY); DENYS = splitItemsFormProperty(property); @@ -95,6 +93,10 @@ public class ParserConfig { String property = IOUtils.getStringProperty(AUTOTYPE_SUPPORT_PROPERTY); AUTO_SUPPORT = "true".equals(property); } + { + String property = IOUtils.getStringProperty(SAFE_MODE_PROPERTY); + SAFE_MODE = "true".equals(property); + } { String property = IOUtils.getStringProperty(AUTOTYPE_ACCEPT); String[] items = splitItemsFormProperty(property); @@ -103,20 +105,28 @@ public class ParserConfig { } AUTO_TYPE_ACCEPT_LIST = items; } + + INTERNAL_WHITELIST_HASHCODES = new long[] { + 0x9F2E20FB6049A371L, + 0xA8AAA929446FFCE4L, + 0xD45D6F8C9017FAL, + 0x64DC636F343516DCL + }; } public static ParserConfig getGlobalInstance() { return global; } - public static ParserConfig global = new ParserConfig(); private final IdentityHashMap deserializers = new IdentityHashMap(); + private final IdentityHashMap> mixInDeserializers = new IdentityHashMap>(16); + private final ConcurrentMap> typeMapping = new ConcurrentHashMap>(16, 0.75f, 1); private boolean asmEnable = !ASMUtils.IS_ANDROID; public final SymbolTable symbolTable = new SymbolTable(4096); - + public PropertyNamingStrategy propertyNamingStrategy; protected ClassLoader defaultClassLoader; @@ -125,14 +135,204 @@ public static ParserConfig getGlobalInstance() { private static boolean awtError = false; private static boolean jdk8Error = false; + private static boolean jodaError = false; + private static boolean guavaError = false; private boolean autoTypeSupport = AUTO_SUPPORT; - private String[] denyList = "bsh,com.mchange,com.sun.,java.lang.Thread,java.net.Socket,java.rmi,javax.xml,org.apache.bcel,org.apache.commons.beanutils,org.apache.commons.collections.Transformer,org.apache.commons.collections.functors,org.apache.commons.collections4.comparators,org.apache.commons.fileupload,org.apache.myfaces.context.servlet,org.apache.tomcat,org.apache.wicket.util,org.apache.xalan,org.codehaus.groovy.runtime,org.hibernate,org.jboss,org.mozilla.javascript,org.python.core,org.springframework".split(","); - private String[] acceptList = AUTO_TYPE_ACCEPT_LIST; + private long[] internalDenyHashCodes; + private long[] denyHashCodes; + private long[] acceptHashCodes; + public final boolean fieldBased; + private boolean jacksonCompatible = false; public boolean compatibleWithJavaBean = TypeUtils.compatibleWithJavaBean; + private List modules = new ArrayList(); + private volatile List autoTypeCheckHandlers; + private boolean safeMode = SAFE_MODE; + + { + denyHashCodes = new long[]{ + 0x80D0C70BCC2FEA02L, + 0x868385095A22725FL, + 0x86FC2BF9BEAF7AEFL, + 0x87F52A1B07EA33A6L, + 0x8872F29FD0B0B7A7L, + 0x8BAAEE8F9BF77FA7L, + 0x8EADD40CB2A94443L, + 0x8F75F9FA0DF03F80L, + 0x9172A53F157930AFL, + 0x92122D710E364FB8L, + 0x941866E73BEFF4C9L, + 0x94305C26580F73C5L, + 0x9437792831DF7D3FL, + 0xA123A62F93178B20L, + 0xA85882CE1044C450L, + 0xAA3DAFFDB10C4937L, + 0xAAA9E6B7C1E1C6A7L, + 0xAAAA0826487A3737L, + 0xAB82562F53E6E48FL, + 0xAC6262F52C98AA39L, + 0xAD937A449831E8A0L, + 0xAE50DA1FAD60A096L, + 0xAFF6FF23388E225AL, + 0xAFFF4C95B99A334DL, + 0xB40F341C746EC94FL, + 0xB7E8ED757F5D13A2L, + 0xB98B6B5396932FE9L, + 0xBCDD9DC12766F0CEL, + 0xBCE0DEE34E726499L, + 0xBE4F13E96A6796D0L, + 0xBEBA72FB1CCBA426L, + 0xC00BE1DEBAF2808BL, + 0xC1086AFAE32E6258L, + 0xC2664D0958ECFE4CL, + 0xC41FF7C9C87C7C05L, + 0xC664B363BACA050AL, + 0xC7599EBFE3E72406L, + 0xC8D49E5601E661A9L, + 0xC8F04B3A28909935L, + 0xC963695082FD728EL, + 0xCBF29CE484222325L, + 0xD1EFCDF4B3316D34L, + 0xD54B91CC77B239EDL, + 0xD59EE91F0B09EA01L, + 0xD66F68AB92E7FEF5L, + 0xD8CA3D595E982BACL, + 0xDCD8D615A6449E3EL, + 0xDE23A0809A8B9BD6L, + 0xDEFC208F237D4104L, + 0xDF2DDFF310CDB375L, + 0xE09AE4604842582FL, + 0xE1919804D5BF468FL, + 0xE2EB3AC7E56C467EL, + 0xE603D6A51FAD692BL, + 0xE704FD19052B2A34L, + 0xE9184BE55B1D962AL, + 0xE9F20BAD25F60807L, + 0xED13653CB45C4BEDL, + 0xF2983D099D29B477L, + 0xF3702A4A5490B8E8L, + 0xF474E44518F26736L, + 0xF4D93F4FB3E3D991L, + 0xF5D77DCF8E4D71E6L, + 0xF6C0340E73A36A69L, + 0xF7E96E74DFA58DBCL, + 0xFC773AE20C827691L, + 0xFCF3E78644B98BD8L, + 0xFD5BFC610056D720L, + 0xFFA15BF021F1E37CL, + 0xFFDD1A80F1ED3405L, + 0x10E067CD55C5E5L, + 0x761619136CC13EL, + 0x22BAA234C5BFB8AL, + 0x3085068CB7201B8L, + 0x45B11BC78A3ABA3L, + 0x55CFCA0F2281C07L, + 0xA555C74FE3A5155L, + 0xB6E292FA5955ADEL, + 0xBEF8514D0B79293L, + 0xEE6511B66FD5EF0L, + 0x100150A253996624L, + 0x10B2BDCA849D9B3EL, + 0x10DBC48446E0DAE5L, + 0x119B5B1F10210AFCL, + 0x144277B467723158L, + 0x14DB2E6FEAD04AF0L, + 0x154B6CB22D294CFAL, + 0x17924CCA5227622AL, + 0x193B2697EAAED41AL, + 0x1CD6F11C6A358BB7L, + 0x1E0A8C3358FF3DAEL, + 0x24652CE717E713BBL, + 0x24D2F6048FEF4E49L, + 0x24EC99D5E7DC5571L, + 0x25E962F1C28F71A2L, + 0x275D0732B877AF29L, + 0x28AC82E44E933606L, + 0x2A71CE2CC40A710CL, + 0x2AD1CE3A112F015DL, + 0x2ADFEFBBFE29D931L, + 0x2B3A37467A344CDFL, + 0x2B6DD8B3229D6837L, + 0x2D308DBBC851B0D8L, + 0x2FE950D3EA52AE0DL, + 0x313BB4ABD8D4554CL, + 0x327C8ED7C8706905L, + 0x332F0B5369A18310L, + 0x339A3E0B6BEEBEE9L, + 0x33C64B921F523F2FL, + 0x33E7F3E02571B153L, + 0x34A81EE78429FDF1L, + 0x37317698DCFCE894L, + 0x378307CB0111E878L, + 0x3826F4B2380C8B9BL, + 0x398F942E01920CF0L, + 0x3A31412DBB05C7FFL, + 0x3A7EE0635EB2BC33L, + 0x3ADBA40367F73264L, + 0x3B0B51ECBF6DB221L, + 0x3BF14094A524F0E2L, + 0x42D11A560FC9FBA9L, + 0x43320DC9D2AE0892L, + 0x440E89208F445FB9L, + 0x46C808A4B5841F57L, + 0x470FD3A18BB39414L, + 0x49312BDAFB0077D9L, + 0x4A3797B30328202CL, + 0x4BA3E254E758D70DL, + 0x4BF881E49D37F530L, + 0x4CF54EEC05E3E818L, + 0x4DA972745FEB30C1L, + 0x4EF08C90FF16C675L, + 0x4FD10DDC6D13821FL, + 0x521B4F573376DF4AL, + 0x527DB6B46CE3BCBCL, + 0x535E552D6F9700C1L, + 0x54855E265FE1DAD5L, + 0x5728504A6D454FFCL, + 0x599B5C1213A099ACL, + 0x5A5BD85C072E5EFEL, + 0x5AB0CB3071AB40D1L, + 0x5B6149820275EA42L, + 0x5D74D3E5B9370476L, + 0x5D92E6DDDE40ED84L, + 0x5E61093EF8CDDDBBL, + 0x5F215622FB630753L, + 0x61C5BDD721385107L, + 0x62DB241274397C34L, + 0x636ECCA2A131B235L, + 0x63A220E60A17C7B9L, + 0x647AB0224E149EBEL, + 0x65F81B84C1D920CDL, + 0x665C53C311193973L, + 0x6749835432E0F0D2L, + 0x69B6E0175084B377L, + 0x6A47501EBB2AFDB2L, + 0x6FCABF6FA54CAFFFL, + 0x6FE92D83FC0A4628L, + 0x746BD4A53EC195FBL, + 0x74B50BB9260E31FFL, + 0x75CC60F5871D0FD3L, + 0x767A586A5107FEEFL, + 0x78E5935826671397L, + 0x793ADDDED7A967F5L, + 0x7AA7EE3627A19CF3L, + 0x7AFA070241B8CC4BL, + 0x7ED9311D28BF1A65L, + 0x7ED9481D28BF417AL, + 0x7EE6C477DA20BBE3L + }; + + long[] hashCodes = new long[AUTO_TYPE_ACCEPT_LIST.length]; + for (int i = 0; i < AUTO_TYPE_ACCEPT_LIST.length; i++) { + hashCodes[i] = TypeUtils.fnv1a_64(AUTO_TYPE_ACCEPT_LIST[i]); + } + + Arrays.sort(hashCodes); + acceptHashCodes = hashCodes; + } public ParserConfig(){ this(false); @@ -174,11 +374,26 @@ private ParserConfig(ASMDeserializerFactory asmFactory, ClassLoader parentClassL asmEnable = false; } + initDeserializers(); + + addItemsToDeny(DENYS); + addItemsToDeny0(DENYS_INTERNAL); + addItemsToAccept(AUTO_TYPE_ACCEPT_LIST); + + } + + private final Callable initDeserializersWithJavaSql = new Callable() { + public Void call() { + deserializers.put(java.sql.Timestamp.class, SqlDateDeserializer.instance_timestamp); + deserializers.put(java.sql.Date.class, SqlDateDeserializer.instance); + deserializers.put(java.sql.Time.class, TimeDeserializer.instance); + deserializers.put(java.util.Date.class, DateCodec.instance); + return null; + } + }; + + private void initDeserializers() { deserializers.put(SimpleDateFormat.class, MiscCodec.instance); - deserializers.put(java.sql.Timestamp.class, SqlDateDeserializer.instance_timestamp); - deserializers.put(java.sql.Date.class, SqlDateDeserializer.instance); - deserializers.put(java.sql.Time.class, TimeDeserializer.instance); - deserializers.put(java.util.Date.class, DateCodec.instance); deserializers.put(Calendar.class, CalendarCodec.instance); deserializers.put(XMLGregorianCalendar.class, CalendarCodec.instance); @@ -233,7 +448,7 @@ private ParserConfig(ASMDeserializerFactory asmFactory, ClassLoader parentClassL deserializers.put(TimeZone.class, MiscCodec.instance); deserializers.put(Locale.class, MiscCodec.instance); deserializers.put(Currency.class, MiscCodec.instance); - deserializers.put(InetAddress.class, MiscCodec.instance); + deserializers.put(Inet4Address.class, MiscCodec.instance); deserializers.put(Inet6Address.class, MiscCodec.instance); deserializers.put(InetSocketAddress.class, MiscCodec.instance); @@ -254,12 +469,9 @@ private ParserConfig(ASMDeserializerFactory asmFactory, ClassLoader parentClassL deserializers.put(Closeable.class, JavaObjectDeserializer.instance); deserializers.put(JSONPObject.class, new JSONPDeserializer()); - - addItemsToDeny(DENYS); - addItemsToAccept(AUTO_TYPE_ACCEPT_LIST); - + ModuleUtil.callWhenHasJavaSql(initDeserializersWithJavaSql); } - + private static String[] splitItemsFormProperty(final String property ){ if (property != null && property.length() > 0) { return property.split(","); @@ -287,7 +499,18 @@ public void configFromPropety(Properties properties) { } } } - + + private void addItemsToDeny0(final String[] items){ + if (items == null){ + return; + } + + for (int i = 0; i < items.length; ++i) { + String item = items[i]; + this.addDenyInternal(item); + } + } + private void addItemsToDeny(final String[] items){ if (items == null){ return; @@ -310,6 +533,20 @@ private void addItemsToAccept(final String[] items){ } } + /** + * @since 1.2.68 + */ + public boolean isSafeMode() { + return safeMode; + } + + /** + * @since 1.2.68 + */ + public void setSafeMode(boolean safeMode) { + this.safeMode = safeMode; + } + public boolean isAutoTypeSupport() { return autoTypeSupport; } @@ -326,14 +563,21 @@ public void setAsmEnable(boolean asmEnable) { this.asmEnable = asmEnable; } + /** + * @deprecated + */ + public IdentityHashMap getDerializers() { + return deserializers; + } + public IdentityHashMap getDeserializers() { return deserializers; } public ObjectDeserializer getDeserializer(Type type) { - ObjectDeserializer derializer = this.deserializers.get(type); - if (derializer != null) { - return derializer; + ObjectDeserializer deserializer = get(type); + if (deserializer != null) { + return deserializer; } if (type instanceof Class) { @@ -362,18 +606,23 @@ public ObjectDeserializer getDeserializer(Type type) { } public ObjectDeserializer getDeserializer(Class clazz, Type type) { - ObjectDeserializer derializer = deserializers.get(type); - if (derializer != null) { - return derializer; + ObjectDeserializer deserializer = get(type); + if (deserializer == null && type instanceof ParameterizedTypeImpl) { + Type innerType = TypeReference.intern((ParameterizedTypeImpl) type); + deserializer = get(innerType); + } + + if (deserializer != null) { + return deserializer; } if (type == null) { type = clazz; } - derializer = deserializers.get(type); - if (derializer != null) { - return derializer; + deserializer = get(type); + if (deserializer != null) { + return deserializer; } { @@ -387,11 +636,19 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { } if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) { - derializer = deserializers.get(clazz); + deserializer = get(clazz); + } + + if (deserializer != null) { + return deserializer; } - if (derializer != null) { - return derializer; + for (Module module : modules) { + deserializer = module.createDeserializer(this, clazz); + if (deserializer != null) { + putDeserializer(type, deserializer); + return deserializer; + } } String className = clazz.getName(); @@ -410,8 +667,8 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { try { for (String name : names) { if (name.equals(className)) { - deserializers.put(Class.forName(name), derializer = AwtCodec.instance); - return derializer; + putDeserializer(Class.forName(name), deserializer = AwtCodec.instance); + return deserializer; } } } catch (Throwable e) { @@ -419,7 +676,7 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { awtError = true; } - derializer = AwtCodec.instance; + deserializer = AwtCodec.instance; } } @@ -443,8 +700,8 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { for (String name : names) { if (name.equals(className)) { - deserializers.put(Class.forName(name), derializer = Jdk8DateCodec.instance); - return derializer; + putDeserializer(Class.forName(name), deserializer = Jdk8DateCodec.instance); + return deserializer; } } } else if (className.startsWith("java.util.Optional")) { @@ -456,8 +713,8 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { }; for (String name : names) { if (name.equals(className)) { - deserializers.put(Class.forName(name), derializer = OptionalCodec.instance); - return derializer; + putDeserializer(Class.forName(name), deserializer = OptionalCodec.instance); + return deserializer; } } } @@ -467,12 +724,71 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { } } + if (!jodaError) { + try { + if (className.startsWith("org.joda.time.")) { + String[] names = new String[] { + "org.joda.time.DateTime", + "org.joda.time.LocalDate", + "org.joda.time.LocalDateTime", + "org.joda.time.LocalTime", + "org.joda.time.Instant", + "org.joda.time.Period", + "org.joda.time.Duration", + "org.joda.time.DateTimeZone", + "org.joda.time.format.DateTimeFormatter" + }; + + for (String name : names) { + if (name.equals(className)) { + putDeserializer(Class.forName(name), deserializer = JodaCodec.instance); + return deserializer; + } + } + } + } catch (Throwable e) { + // skip + jodaError = true; + } + } + + if ((!guavaError) // + && className.startsWith("com.google.common.collect.")) { + try { + String[] names = new String[] { + "com.google.common.collect.HashMultimap", + "com.google.common.collect.LinkedListMultimap", + "com.google.common.collect.LinkedHashMultimap", + "com.google.common.collect.ArrayListMultimap", + "com.google.common.collect.TreeMultimap" + }; + + for (String name : names) { + if (name.equals(className)) { + putDeserializer(Class.forName(name), deserializer = GuavaCodec.instance); + return deserializer; + } + } + } catch (ClassNotFoundException e) { + // skip + guavaError = true; + } + } + + if (className.equals("java.nio.ByteBuffer")) { + putDeserializer(clazz, deserializer = ByteBufferCodec.instance); + } + if (className.equals("java.nio.file.Path")) { - deserializers.put(clazz, derializer = MiscCodec.instance); + putDeserializer(clazz, deserializer = MiscCodec.instance); } if (clazz == Map.Entry.class) { - deserializers.put(clazz, derializer = MiscCodec.instance); + putDeserializer(clazz, deserializer = MiscCodec.instance); + } + + if (className.equals("org.javamoney.moneta.Money")) { + putDeserializer(clazz, deserializer = MonetaCodec.instance); } final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); @@ -480,56 +796,122 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader)) { for (Type forType : autowired.getAutowiredFor()) { - deserializers.put(forType, autowired); + putDeserializer(forType, autowired); } } } catch (Exception ex) { // skip } - if (derializer == null) { - derializer = deserializers.get(type); + if (deserializer == null) { + deserializer = get(type); } - if (derializer != null) { - return derializer; + if (deserializer != null) { + return deserializer; } if (clazz.isEnum()) { + if (jacksonCompatible) { + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + if (TypeUtils.isJacksonCreator(method)) { + deserializer = createJavaBeanDeserializer(clazz, type); + putDeserializer(type, deserializer); + return deserializer; + } + } + } + + Class mixInType = (Class) JSON.getMixInAnnotations(clazz); + Class deserClass = null; - JSONType jsonType = clazz.getAnnotation(JSONType.class); + JSONType jsonType = TypeUtils.getAnnotation(mixInType != null ? mixInType : clazz, JSONType.class); + if (jsonType != null) { deserClass = jsonType.deserializer(); try { - derializer = (ObjectDeserializer) deserClass.newInstance(); - deserializers.put(clazz, derializer); - return derializer; + deserializer = (ObjectDeserializer) deserClass.newInstance(); + putDeserializer(clazz, deserializer); + return deserializer; } catch (Throwable error) { // skip } } - derializer = new EnumDeserializer(clazz); + Method jsonCreatorMethod = null; + if (mixInType != null) { + Method mixedCreator = getEnumCreator(mixInType, clazz); + if (mixedCreator != null) { + try { + jsonCreatorMethod = clazz.getMethod(mixedCreator.getName(), mixedCreator.getParameterTypes()); + } catch (Exception e) { + // skip + } + } + } else { + jsonCreatorMethod = getEnumCreator(clazz, clazz); + } + + if (jsonCreatorMethod != null) { + deserializer = new EnumCreatorDeserializer(jsonCreatorMethod); + putDeserializer(clazz, deserializer); + return deserializer; + } + + deserializer = getEnumDeserializer(clazz); } else if (clazz.isArray()) { - derializer = ObjectArrayCodec.instance; + deserializer = ObjectArrayCodec.instance; } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class || clazz == ArrayList.class) { - derializer = CollectionCodec.instance; + deserializer = CollectionCodec.instance; } else if (Collection.class.isAssignableFrom(clazz)) { - derializer = CollectionCodec.instance; + deserializer = CollectionCodec.instance; } else if (Map.class.isAssignableFrom(clazz)) { - derializer = MapDeserializer.instance; + deserializer = MapDeserializer.instance; } else if (Throwable.class.isAssignableFrom(clazz)) { - derializer = new ThrowableDeserializer(this, clazz); + deserializer = new ThrowableDeserializer(this, clazz); } else if (PropertyProcessable.class.isAssignableFrom(clazz)) { - derializer = new PropertyProcessableDeserializer((Class)clazz); + deserializer = new PropertyProcessableDeserializer((Class) clazz); + } else if (clazz == InetAddress.class) { + deserializer = MiscCodec.instance; } else { - derializer = createJavaBeanDeserializer(clazz, type); + deserializer = createJavaBeanDeserializer(clazz, type); } - putDeserializer(type, derializer); + putDeserializer(type, deserializer); - return derializer; + return deserializer; + } + + private static Method getEnumCreator(Class clazz, Class enumClass) { + Method[] methods = clazz.getMethods(); + Method jsonCreatorMethod = null; + for (Method method : methods) { + if (Modifier.isStatic(method.getModifiers()) + && method.getReturnType() == enumClass + && method.getParameterTypes().length == 1 + ) { + JSONCreator jsonCreator = method.getAnnotation(JSONCreator.class); + if (jsonCreator != null) { + jsonCreatorMethod = method; + break; + } + } + } + + return jsonCreatorMethod; + } + + /** + * 可以通过重写这个方法,定义自己的枚举反序列化实现 + * @param clazz 转换的类型 + * @return 返回一个枚举的反序列化实现 + * @author zhu.xiaojie + * @time 2020-4-5 + */ + protected ObjectDeserializer getEnumDeserializer(Class clazz){ + return new EnumDeserializer(clazz); } /** @@ -567,8 +949,9 @@ public ObjectDeserializer createJavaBeanDeserializer(Class clazz, Type type) // skip } } - - asmEnable = jsonType.asm(); + + asmEnable = jsonType.asm() + && jsonType.parseFeatures().length == 0; } if (asmEnable) { @@ -607,7 +990,13 @@ public ObjectDeserializer createJavaBeanDeserializer(Class clazz, Type type) if (clazz.isInterface()) { asmEnable = false; } - JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy); + JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz + , type + , propertyNamingStrategy + ,false + , TypeUtils.compatibleWithJavaBean + , jacksonCompatible + ); if (asmEnable && beanInfo.fields.length > 200) { asmEnable = false; @@ -646,6 +1035,7 @@ public ObjectDeserializer createJavaBeanDeserializer(Class clazz, Type type) && ((!ASMUtils.checkName(annotation.name())) // || annotation.format().length() != 0 // || annotation.deserializeUsing() != Void.class // + || annotation.parseFeatures().length != 0 // || annotation.unwrapped()) || (fieldInfo.method != null && fieldInfo.method.getParameterTypes().length > 1)) { asmEnable = false; @@ -668,6 +1058,12 @@ public ObjectDeserializer createJavaBeanDeserializer(Class clazz, Type type) } } + if (asmEnable) { + if (TypeUtils.isXmlField(clazz)) { + asmEnable = false; + } + } + if (!asmEnable) { return new JavaBeanDeserializer(this, clazz, type); } @@ -710,7 +1106,30 @@ public FieldDeserializer createFieldDeserializer(ParserConfig mapping, // } public void putDeserializer(Type type, ObjectDeserializer deserializer) { - deserializers.put(type, deserializer); + Type mixin = JSON.getMixInAnnotations(type); + if (mixin != null) { + IdentityHashMap mixInClasses = this.mixInDeserializers.get(type); + if (mixInClasses == null) { + //多线程下可能会重复创建,但不影响正确性 + mixInClasses = new IdentityHashMap(4); + this.mixInDeserializers.put(type, mixInClasses); + } + mixInClasses.put(mixin, deserializer); + } else { + this.deserializers.put(type, deserializer); + } + } + + public ObjectDeserializer get(Type type) { + Type mixin = JSON.getMixInAnnotations(type); + if (null == mixin) { + return this.deserializers.get(type); + } + IdentityHashMap mixInClasses = this.mixInDeserializers.get(type); + if (mixInClasses == null) { + return null; + } + return mixInClasses.get(mixin); } public ObjectDeserializer getDeserializer(FieldInfo fieldInfo) { @@ -724,33 +1143,42 @@ public boolean isPrimitive(Class clazz) { return isPrimitive2(clazz); } + private static Function, Boolean> isPrimitiveFuncation = new Function, Boolean>() { + public Boolean apply(Class clazz) { + return clazz == java.sql.Date.class // + || clazz == java.sql.Time.class // + || clazz == java.sql.Timestamp.class; + } + }; + /** * @deprecated internal method, dont call */ - public static boolean isPrimitive2(Class clazz) { - return clazz.isPrimitive() // - || clazz == Boolean.class // - || clazz == Character.class // - || clazz == Byte.class // - || clazz == Short.class // - || clazz == Integer.class // - || clazz == Long.class // - || clazz == Float.class // - || clazz == Double.class // - || clazz == BigInteger.class // - || clazz == BigDecimal.class // - || clazz == String.class // - || clazz == java.util.Date.class // - || clazz == java.sql.Date.class // - || clazz == java.sql.Time.class // - || clazz == java.sql.Timestamp.class // - || clazz.isEnum() // - ; - } - + public static boolean isPrimitive2(final Class clazz) { + Boolean primitive = clazz.isPrimitive() // + || clazz == Boolean.class // + || clazz == Character.class // + || clazz == Byte.class // + || clazz == Short.class // + || clazz == Integer.class // + || clazz == Long.class // + || clazz == Float.class // + || clazz == Double.class // + || clazz == BigInteger.class // + || clazz == BigDecimal.class // + || clazz == String.class // + || clazz == java.util.Date.class // + || clazz.isEnum() // + ; + if (!primitive) { + primitive = ModuleUtil.callWhenHasJavaSql(isPrimitiveFuncation, clazz); + } + return primitive != null ? primitive : false; + } + /** * fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询 - * + * * @param clazz * @param fieldCacheMap :map<fieldName ,Field> */ @@ -766,7 +1194,7 @@ public static void parserAllFieldToCache(Class clazz,Map fieldCacheMap) { Field field = fieldCacheMap.get(fieldName); @@ -789,8 +1217,7 @@ public static Field getFieldFromCache(String fieldName, Map field if (fieldName.length() > 2) { char c1 = fieldName.charAt(1); - if (fieldName.length() > 2 - && c0 >= 'a' && c0 <= 'z' + if (c0 >= 'a' && c0 <= 'z' && c1 >= 'A' && c1 <= 'Z') { for (Map.Entry entry : fieldCacheMap.entrySet()) { if (fieldName.equalsIgnoreCase(entry.getKey())) { @@ -813,21 +1240,43 @@ public void setDefaultClassLoader(ClassLoader defaultClassLoader) { this.defaultClassLoader = defaultClassLoader; } + public void addDenyInternal(String name) { + if (name == null || name.length() == 0) { + return; + } + + long hash = TypeUtils.fnv1a_64(name); + if (internalDenyHashCodes == null) { + this.internalDenyHashCodes = new long[] {hash}; + return; + } + + if (Arrays.binarySearch(this.internalDenyHashCodes, hash) >= 0) { + return; + } + + long[] hashCodes = new long[this.internalDenyHashCodes.length + 1]; + hashCodes[hashCodes.length - 1] = hash; + System.arraycopy(this.internalDenyHashCodes, 0, hashCodes, 0, this.internalDenyHashCodes.length); + Arrays.sort(hashCodes); + this.internalDenyHashCodes = hashCodes; + } + public void addDeny(String name) { if (name == null || name.length() == 0) { return; } - for (String item : denyList) { - if (name.equals(item)) { - return; // skip duplication - } + long hash = TypeUtils.fnv1a_64(name); + if (Arrays.binarySearch(this.denyHashCodes, hash) >= 0) { + return; } - String[] denyList = new String[this.denyList.length + 1]; - System.arraycopy(this.denyList, 0, denyList, 0, this.denyList.length); - denyList[denyList.length - 1] = name; - this.denyList = denyList; + long[] hashCodes = new long[this.denyHashCodes.length + 1]; + hashCodes[hashCodes.length - 1] = hash; + System.arraycopy(this.denyHashCodes, 0, hashCodes, 0, this.denyHashCodes.length); + Arrays.sort(hashCodes); + this.denyHashCodes = hashCodes; } public void addAccept(String name) { @@ -835,16 +1284,24 @@ public void addAccept(String name) { return; } - for (String item : acceptList) { - if (name.equals(item)) { - return; // skip duplication - } + long hash = TypeUtils.fnv1a_64(name); + if (Arrays.binarySearch(this.acceptHashCodes, hash) >= 0) { + return; + } + + long[] hashCodes = new long[this.acceptHashCodes.length + 1]; + hashCodes[hashCodes.length - 1] = hash; + System.arraycopy(this.acceptHashCodes, 0, hashCodes, 0, this.acceptHashCodes.length); + Arrays.sort(hashCodes); + this.acceptHashCodes = hashCodes; + } + + public Class checkAutoType(Class type) { + if (get(type) != null) { + return type; } - String[] acceptList = new String[this.acceptList.length + 1]; - System.arraycopy(this.acceptList, 0, acceptList, 0, this.acceptList.length); - acceptList[acceptList.length - 1] = name; - this.acceptList = acceptList; + return checkAutoType(type.getName(), null, JSON.DEFAULT_PARSER_FEATURE); } public Class checkAutoType(String typeName, Class expectClass) { @@ -856,43 +1313,130 @@ public Class checkAutoType(String typeName, Class expectClass, int feature return null; } - if (typeName.length() >= 128) { + if (autoTypeCheckHandlers != null) { + for (AutoTypeCheckHandler h : autoTypeCheckHandlers) { + Class type = h.handler(typeName, expectClass, features); + if (type != null) { + return type; + } + } + } + + final int safeModeMask = Feature.SafeMode.mask; + boolean safeMode = this.safeMode + || (features & safeModeMask) != 0 + || (JSON.DEFAULT_PARSER_FEATURE & safeModeMask) != 0; + if (safeMode) { + throw new JSONException("safeMode not support autoType : " + typeName); + } + + final int mask = Feature.SupportAutoType.mask; + boolean autoTypeSupport = this.autoTypeSupport + || (features & mask) != 0 + || (JSON.DEFAULT_PARSER_FEATURE & mask) != 0; + + if (typeName.length() >= 192 || typeName.length() < 3) { + throw new JSONException("autoType is not support. " + typeName); + } + + final boolean expectClassFlag; + if (expectClass == null) { + expectClassFlag = false; + } else { + long expectHash = TypeUtils.fnv1a_64(expectClass.getName()); + if (expectHash == 0x90a25f5baa21529eL + || expectHash == 0x2d10a5801b9d6136L + || expectHash == 0xaf586a571e302c6bL + || expectHash == 0xed007300a7b227c6L + || expectHash == 0x295c4605fd1eaa95L + || expectHash == 0x47ef269aadc650b4L + || expectHash == 0x6439c4dff712ae8bL + || expectHash == 0xe3dd9875a2dc5283L + || expectHash == 0xe2a8ddba03e69e0dL + || expectHash == 0xd734ceb4c3e9d1daL + ) { + expectClassFlag = false; + } else { + expectClassFlag = true; + } + } + + String className = typeName.replace('$', '.'); + Class clazz; + + final long h1 = (fnv1a_64_magic_hashcode ^ className.charAt(0)) * fnv1a_64_magic_prime; + if (h1 == 0xaf64164c86024f1aL) { // [ throw new JSONException("autoType is not support. " + typeName); } - final String className = typeName.replace('$', '.'); - Class clazz = null; + if ((h1 ^ className.charAt(className.length() - 1)) * fnv1a_64_magic_prime == 0x9198507b5af98f0L) { + throw new JSONException("autoType is not support. " + typeName); + } + + final long h3 = (((((fnv1a_64_magic_hashcode ^ className.charAt(0)) + * fnv1a_64_magic_prime) + ^ className.charAt(1)) + * fnv1a_64_magic_prime) + ^ className.charAt(2)) + * fnv1a_64_magic_prime; + + long fullHash = TypeUtils.fnv1a_64(className); + boolean internalWhite = Arrays.binarySearch(INTERNAL_WHITELIST_HASHCODES, fullHash) >= 0; + + if (internalDenyHashCodes != null) { + long hash = h3; + for (int i = 3; i < className.length(); ++i) { + hash ^= className.charAt(i); + hash *= fnv1a_64_magic_prime; + if (Arrays.binarySearch(internalDenyHashCodes, hash) >= 0) { + throw new JSONException("autoType is not support. " + typeName); + } + } + } - if (autoTypeSupport || expectClass != null) { - for (int i = 0; i < acceptList.length; ++i) { - String accept = acceptList[i]; - if (className.startsWith(accept)) { - clazz = TypeUtils.loadClass(typeName, defaultClassLoader, false); + if ((!internalWhite) && (autoTypeSupport || expectClassFlag)) { + long hash = h3; + for (int i = 3; i < className.length(); ++i) { + hash ^= className.charAt(i); + hash *= fnv1a_64_magic_prime; + if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) { + clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true); if (clazz != null) { return clazz; } } - } + if (Arrays.binarySearch(denyHashCodes, hash) >= 0 && TypeUtils.getClassFromMapping(typeName) == null) { + if (Arrays.binarySearch(acceptHashCodes, fullHash) >= 0) { + continue; + } - for (int i = 0; i < denyList.length; ++i) { - String deny = denyList[i]; - if (className.startsWith(deny) && TypeUtils.getClassFromMapping(typeName) == null) { throw new JSONException("autoType is not support. " + typeName); } } } + clazz = TypeUtils.getClassFromMapping(typeName); + if (clazz == null) { - clazz = TypeUtils.getClassFromMapping(typeName); + clazz = deserializers.findClass(typeName); + } + + if (expectClass == null && clazz != null && Throwable.class.isAssignableFrom(clazz) && !autoTypeSupport) { + clazz = null; } if (clazz == null) { - clazz = deserializers.findClass(typeName); + clazz = typeMapping.get(typeName); + } + + if (internalWhite) { + clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true); } if (clazz != null) { if (expectClass != null && clazz != java.util.HashMap.class + && clazz != java.util.LinkedHashMap.class && !expectClass.isAssignableFrom(clazz)) { throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName()); } @@ -901,44 +1445,83 @@ public Class checkAutoType(String typeName, Class expectClass, int feature } if (!autoTypeSupport) { - for (int i = 0; i < denyList.length; ++i) { - String deny = denyList[i]; - if (className.startsWith(deny)) { + long hash = h3; + for (int i = 3; i < className.length(); ++i) { + char c = className.charAt(i); + hash ^= c; + hash *= fnv1a_64_magic_prime; + + if (Arrays.binarySearch(denyHashCodes, hash) >= 0) { + if (typeName.endsWith("Exception") || typeName.endsWith("Error")) { + return null; + } + throw new JSONException("autoType is not support. " + typeName); } - } - for (int i = 0; i < acceptList.length; ++i) { - String accept = acceptList[i]; - if (className.startsWith(accept)) { + + // white list + if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) { + clazz = TypeUtils.loadClass(typeName, defaultClassLoader, true); + if (clazz == null) { - clazz = TypeUtils.loadClass(typeName, defaultClassLoader, false); + return expectClass; } if (expectClass != null && expectClass.isAssignableFrom(clazz)) { throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName()); } + return clazz; } } } - if (clazz == null) { - clazz = TypeUtils.loadClass(typeName, defaultClassLoader, false); + boolean jsonType = false; + InputStream is = null; + try { + String resource = typeName.replace('.', '/') + ".class"; + if (defaultClassLoader != null) { + is = defaultClassLoader.getResourceAsStream(resource); + } else { + is = ParserConfig.class.getClassLoader().getResourceAsStream(resource); + } + if (is != null) { + ClassReader classReader = new ClassReader(is, true); + TypeCollector visitor = new TypeCollector("", new Class[0]); + classReader.accept(visitor); + jsonType = visitor.hasJsonType(); + } + } catch (Exception e) { + // skip + } finally { + IOUtils.close(is); + } + + if (autoTypeSupport || jsonType || expectClassFlag) { + boolean cacheClass = autoTypeSupport || jsonType; + clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass); } if (clazz != null) { - if (TypeUtils.getAnnotation(clazz,JSONType.class) != null) { + if (jsonType) { + if (autoTypeSupport) { + TypeUtils.addMapping(typeName, clazz); + } return clazz; } if (ClassLoader.class.isAssignableFrom(clazz) // classloader is danger - || DataSource.class.isAssignableFrom(clazz) // dataSource can load jdbc driver + || javax.sql.DataSource.class.isAssignableFrom(clazz) // dataSource can load jdbc driver + || javax.sql.RowSet.class.isAssignableFrom(clazz) // ) { throw new JSONException("autoType is not support. " + typeName); } if (expectClass != null) { if (expectClass.isAssignableFrom(clazz)) { + if (autoTypeSupport) { + TypeUtils.addMapping(typeName, clazz); + } return clazz; } else { throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName()); @@ -951,15 +1534,59 @@ public Class checkAutoType(String typeName, Class expectClass, int feature } } - final int mask = Feature.SupportAutoType.mask; - boolean autoTypeSupport = this.autoTypeSupport - || (features & mask) != 0 - || (JSON.DEFAULT_PARSER_FEATURE & mask) != 0; - if (!autoTypeSupport) { + if (typeName.endsWith("Exception") || typeName.endsWith("Error")) { + return null; + } + throw new JSONException("autoType is not support. " + typeName); } + if (clazz != null) { + if (autoTypeSupport) { + TypeUtils.addMapping(typeName, clazz); + } + } + return clazz; } + + public void clearDeserializers() { + this.deserializers.clear(); + this.initDeserializers(); + } + + public boolean isJacksonCompatible() { + return jacksonCompatible; + } + + public void setJacksonCompatible(boolean jacksonCompatible) { + this.jacksonCompatible = jacksonCompatible; + } + + public void register(String typeName, Class type) { + typeMapping.putIfAbsent(typeName, type); + } + + public void register(Module module) { + this.modules.add(module); + } + + public void addAutoTypeCheckHandler(AutoTypeCheckHandler h) { + List autoTypeCheckHandlers = this.autoTypeCheckHandlers; + if (autoTypeCheckHandlers == null) { + this.autoTypeCheckHandlers + = autoTypeCheckHandlers + = new CopyOnWriteArrayList(); + } + + autoTypeCheckHandlers.add(h); + } + + /** + * @since 1.2.68 + */ + public interface AutoTypeCheckHandler { + Class handler(String typeName, Class expectClass, int features); + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/SymbolTable.java b/src/main/java/com/alibaba/fastjson/parser/SymbolTable.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java old mode 100755 new mode 100644 index 3737505c6f..e2349758cb --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java @@ -37,10 +37,7 @@ import com.alibaba.fastjson.parser.ParseContext; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.parser.SymbolTable; -import com.alibaba.fastjson.util.ASMClassLoader; -import com.alibaba.fastjson.util.FieldInfo; -import com.alibaba.fastjson.util.JavaBeanInfo; -import com.alibaba.fastjson.util.TypeUtils; +import com.alibaba.fastjson.util.*; public class ASMDeserializerFactory implements Opcodes { @@ -63,15 +60,22 @@ public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, JavaBe } String className = "FastjsonASMDeserializer_" + seed.incrementAndGet() + "_" + clazz.getSimpleName(); - String packageName = ASMDeserializerFactory.class.getPackage().getName(); - String classNameType = packageName.replace('.', '/') + "/" + className; - String classNameFull = packageName + "." + className; + String classNameType; + String classNameFull; + + Package pkg = ASMDeserializerFactory.class.getPackage(); + if (pkg != null) { + String packageName = pkg.getName(); + classNameType = packageName.replace('.', '/') + "/" + className; + classNameFull = packageName + "." + className; + } else { + classNameType = className; + classNameFull = className; + } ClassWriter cw = new ClassWriter(); cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, classNameType, type(JavaBeanDeserializer.class), null); - - _init(cw, new Context(classNameType, config, beanInfo, 3)); _createInstance(cw, new Context(classNameType, config, beanInfo, 3)); _deserialze(cw, new Context(classNameType, config, beanInfo, 5)); @@ -110,6 +114,41 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { defineVarLexer(context, mw); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getSymbolTable", "()" + desc(SymbolTable.class)); + mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanTypeName", "(" + desc(SymbolTable.class) + ")Ljava/lang/String;"); + mw.visitVarInsn(ASTORE, context.var("typeName")); + + Label typeNameNotNull_ = new Label(); + mw.visitVarInsn(ALOAD, context.var("typeName")); + mw.visitJumpInsn(IFNULL, typeNameNotNull_); + + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getConfig", "()" + desc(ParserConfig.class)); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, type(JavaBeanDeserializer.class), "beanInfo", desc(JavaBeanInfo.class)); + mw.visitVarInsn(ALOAD, context.var("typeName")); + mw.visitMethodInsn(INVOKESTATIC, type(JavaBeanDeserializer.class), "getSeeAlso" + , "(" + desc(ParserConfig.class) + desc(JavaBeanInfo.class) + "Ljava/lang/String;)" + desc(JavaBeanDeserializer.class)); + mw.visitVarInsn(ASTORE, context.var("userTypeDeser")); + mw.visitVarInsn(ALOAD, context.var("userTypeDeser")); + mw.visitTypeInsn(INSTANCEOF, type(JavaBeanDeserializer.class)); + mw.visitJumpInsn(IFEQ, typeNameNotNull_); + + mw.visitVarInsn(ALOAD, context.var("userTypeDeser")); + mw.visitVarInsn(ALOAD, Context.parser); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ALOAD, 3); + mw.visitVarInsn(ALOAD, 4); + mw.visitMethodInsn(INVOKEVIRTUAL, // + type(JavaBeanDeserializer.class), // + "deserialzeArrayMapping", // + "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + mw.visitInsn(ARETURN); + + mw.visitLabel(typeNameNotNull_); + _createInstance(context, mw); FieldInfo[] sortedFieldInfoList = context.beanInfo.sortedFields; @@ -127,21 +166,21 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanInt", "(C)I"); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == Byte.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanInt", "(C)I"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == Short.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); @@ -149,14 +188,14 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanInt", "(C)I"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == Integer.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); @@ -164,20 +203,20 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanInt", "(C)I"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == long.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanLong", "(C)J"); - mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(LSTORE, context.var_asm(fieldInfo, 2)); } else if (fieldClass == Long.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); @@ -185,25 +224,25 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanLong", "(C)J"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == boolean.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanBoolean", "(C)Z"); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == float.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFloat", "(C)F"); - mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(FSTORE, context.var_asm(fieldInfo)); } else if (fieldClass == Float.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); @@ -211,21 +250,21 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFloat", "(C)F"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == double.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanDouble", "(C)D"); - mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(DSTORE, context.var_asm(fieldInfo, 2)); } else if (fieldClass == Double.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); @@ -233,14 +272,14 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanDouble", "(C)D"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == char.class) { @@ -249,30 +288,30 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanString", "(C)Ljava/lang/String;"); mw.visitInsn(ICONST_0); mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C"); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == String.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanString", "(C)Ljava/lang/String;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == BigDecimal.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanDecimal", "(C)Ljava/math/BigDecimal;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == java.util.Date.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanDate", "(C)Ljava/util/Date;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == java.util.UUID.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanUUID", "(C)Ljava/util/UUID;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass.isEnum()) { Label enumNumIf_ = new Label(); @@ -328,12 +367,15 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitLabel(enumStore_); mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (Collection.class.isAssignableFrom(fieldClass)) { Class itemClass = TypeUtils.getCollectionItemClass(fieldType); if (itemClass == String.class) { - if (fieldClass == List.class || fieldClass == Collections.class || fieldClass == ArrayList.class) { + if (fieldClass == List.class + || fieldClass == Collections.class + || fieldClass == ArrayList.class + ) { mw.visitTypeInsn(NEW, type(ArrayList.class)); mw.visitInsn(DUP); mw.visitMethodInsn(INVOKESPECIAL, type(ArrayList.class), "", "()V"); @@ -342,10 +384,10 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKESTATIC, type(TypeUtils.class), "createCollection", "(Ljava/lang/Class;)Ljava/util/Collection;"); } - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); mw.visitVarInsn(BIPUSH, seperator); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanStringArray", "(Ljava/util/Collection;C)V"); @@ -355,7 +397,7 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); @@ -371,7 +413,7 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitJumpInsn(IF_ICMPEQ, notError_); mw.visitVarInsn(ALOAD, 1); // DefaultJSONParser - mw.visitVarInsn(ILOAD, context.var("token")); + mw.visitLdcInsn(token); mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "throwException", "(I)V"); mw.visitLabel(notError_); @@ -398,7 +440,7 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { _newCollection(mw, fieldClass, i, false); mw.visitInsn(DUP); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); _getCollectionFieldItemDeser(context, mw, fieldInfo, itemClass); mw.visitVarInsn(ALOAD, 1); mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(itemClass))); @@ -424,7 +466,7 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { "(Ljava/lang/reflect/Type;)Ljava/lang/Object;"); mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else { Label objElseIf_ = new Label(); Label objEndIf_ = new Label(); @@ -443,7 +485,7 @@ private void _deserialzeArrayMapping(ClassWriter cw, Context context) { mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanLong", "(C)J"); mw.visitMethodInsn(INVOKESPECIAL, type(java.util.Date.class), "", "(J)V"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitJumpInsn(GOTO, objEndIf_); } @@ -613,14 +655,21 @@ private void _deserialze(ClassWriter cw, Context context) { mw.visitLdcInsn(Feature.SortFeidFastMatch.mask); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "isEnabled", "(I)Z"); - mw.visitJumpInsn(IFEQ, super_); + Label continue_ = new Label(); + mw.visitJumpInsn(IFNE, continue_); + mw.visitJumpInsn(GOTO_W, super_); + mw.visitLabel(continue_); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitLdcInsn(context.clazz.getName()); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanType", "(Ljava/lang/String;)I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.NOT_MATCH); - mw.visitJumpInsn(IF_ICMPEQ, super_); + + Label continue_2 = new Label(); + mw.visitJumpInsn(IF_ICMPNE, continue_2); + mw.visitJumpInsn(GOTO_W, super_); + mw.visitLabel(continue_2); mw.visitVarInsn(ALOAD, 1); // parser mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getContext", "()" + desc(ParseContext.class)); @@ -650,7 +699,12 @@ private void _deserialze(ClassWriter cw, Context context) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.END); - mw.visitJumpInsn(IF_ICMPEQ, return_); + //mw.visitJumpInsn(IF_ICMPEQ, return_); + + Label continue_3 = new Label(); + mw.visitJumpInsn(IF_ICMPNE, continue_3); + mw.visitJumpInsn(GOTO_W, return_); + mw.visitLabel(continue_3); mw.visitInsn(ICONST_0); // UNKOWN mw.visitIntInsn(ISTORE, context.var("matchStat")); @@ -676,16 +730,16 @@ private void _deserialze(ClassWriter cw, Context context) { || fieldClass == short.class // || fieldClass == int.class) { mw.visitInsn(ICONST_0); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == long.class) { mw.visitInsn(LCONST_0); - mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(LSTORE, context.var_asm(fieldInfo, 2)); } else if (fieldClass == float.class) { mw.visitInsn(FCONST_0); - mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(FSTORE, context.var_asm(fieldInfo)); } else if (fieldClass == double.class) { mw.visitInsn(DCONST_0); - mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(DSTORE, context.var_asm(fieldInfo, 2)); } else { if (fieldClass == String.class) { Label flagEnd_ = new Label(); @@ -706,7 +760,7 @@ private void _deserialze(ClassWriter cw, Context context) { } mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } } @@ -720,222 +774,222 @@ private void _deserialze(ClassWriter cw, Context context) { if (fieldClass == boolean.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldBoolean", "([C)Z"); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == byte.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I"); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == Byte.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == short.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I"); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == Short.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == int.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I"); - mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ISTORE, context.var_asm(fieldInfo)); } else if (fieldClass == Integer.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == long.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldLong", "([C)J"); - mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(LSTORE, context.var_asm(fieldInfo, 2)); } else if (fieldClass == Long.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldLong", "([C)J"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == float.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloat", "([C)F"); - mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(FSTORE, context.var_asm(fieldInfo)); } else if (fieldClass == Float.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloat", "([C)F"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == double.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldDouble", "([C)D"); - mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(DSTORE, context.var_asm(fieldInfo, 2)); } else if (fieldClass == Double.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldDouble", "([C)D"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); Label valueNullEnd_ = new Label(); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I"); mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL); mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(valueNullEnd_); } else if (fieldClass == String.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldString", "([C)Ljava/lang/String;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == java.util.Date.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldDate", "([C)Ljava/util/Date;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == java.util.UUID.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldUUID", "([C)Ljava/util/UUID;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == BigDecimal.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldDecimal", "([C)Ljava/math/BigDecimal;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == BigInteger.class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldBigInteger", "([C)Ljava/math/BigInteger;"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == int[].class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldIntArray", "([C)[I"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == float[].class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloatArray", "([C)[F"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass == float[][].class) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloatArray2", "([C)[[F"); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else if (fieldClass.isEnum()) { mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); _getFieldDeser(context, mw, fieldInfo); mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "scanEnum" , "(L" + JSONLexerBase + ";[C" + desc(ObjectDeserializer.class) + ")Ljava/lang/Enum;"); mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); // } else if (fieldClass.isEnum()) { // mw.visitVarInsn(ALOAD, context.var("lexer")); // mw.visitVarInsn(ALOAD, 0); -// mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); +// mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); // Label enumNull_ = new Label(); // mw.visitInsn(ACONST_NULL); // mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast -// mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); +// mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); // // mw.visitVarInsn(ALOAD, 1); // @@ -955,12 +1009,12 @@ private void _deserialze(ClassWriter cw, Context context) { // mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm_enumName")); // mw.visitMethodInsn(INVOKESTATIC, type(fieldClass), "valueOf", // "(Ljava/lang/String;)" + desc(fieldClass)); -// mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); +// mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); // mw.visitLabel(enumNull_); } else if (Collection.class.isAssignableFrom(fieldClass)) { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); Class itemClass = TypeUtils.getCollectionItemClass(fieldType); @@ -968,7 +1022,7 @@ private void _deserialze(ClassWriter cw, Context context) { mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass))); // cast mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldStringArray", "([CLjava/lang/Class;)" + desc(Collection.class)); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); } else { _deserialze_list_obj(context, mw, reset_, fieldInfo, fieldClass, itemClass, i); @@ -1120,8 +1174,6 @@ private void _createInstance(Context context, MethodVisitor mw) { mw.visitInsn(DUP); mw.visitMethodInsn(INVOKESPECIAL, type(defaultConstructor.getDeclaringClass()), "", "()V"); - - mw.visitVarInsn(ASTORE, context.var("instance")); } else { mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 1); @@ -1130,8 +1182,9 @@ private void _createInstance(Context context, MethodVisitor mw) { mw.visitMethodInsn(INVOKESPECIAL, type(JavaBeanDeserializer.class), "createInstance", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;)Ljava/lang/Object;"); mw.visitTypeInsn(CHECKCAST, type(context.getInstClass())); // cast - mw.visitVarInsn(ASTORE, context.var("instance")); } + + mw.visitVarInsn(ASTORE, context.var("instance")); } private void _batchSet(Context context, MethodVisitor mw) { @@ -1161,18 +1214,18 @@ private void _loadAndSet(Context context, MethodVisitor mw, FieldInfo fieldInfo) if (fieldClass == boolean.class) { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(ILOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ILOAD, context.var_asm(fieldInfo)); _set(context, mw, fieldInfo); } else if (fieldClass == byte.class // || fieldClass == short.class // || fieldClass == int.class // || fieldClass == char.class) { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(ILOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ILOAD, context.var_asm(fieldInfo)); _set(context, mw, fieldInfo); } else if (fieldClass == long.class) { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(LLOAD, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(LLOAD, context.var_asm(fieldInfo, 2)); if (fieldInfo.method != null) { mw.visitMethodInsn(INVOKEVIRTUAL, type(context.getInstClass()), fieldInfo.method.getName(), desc(fieldInfo.method)); @@ -1185,34 +1238,34 @@ private void _loadAndSet(Context context, MethodVisitor mw, FieldInfo fieldInfo) } } else if (fieldClass == float.class) { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(FLOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(FLOAD, context.var_asm(fieldInfo)); _set(context, mw, fieldInfo); } else if (fieldClass == double.class) { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(DLOAD, context.var(fieldInfo.name + "_asm", 2)); + mw.visitVarInsn(DLOAD, context.var_asm(fieldInfo, 2)); _set(context, mw, fieldInfo); } else if (fieldClass == String.class) { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); _set(context, mw, fieldInfo); } else if (fieldClass.isEnum()) { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); _set(context, mw, fieldInfo); } else if (Collection.class.isAssignableFrom(fieldClass)) { mw.visitVarInsn(ALOAD, context.var("instance")); Type itemType = TypeUtils.getCollectionItemClass(fieldType); if (itemType == String.class) { - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast } else { - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); } _set(context, mw, fieldInfo); } else { mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); _set(context, mw, fieldInfo); } } @@ -1313,7 +1366,7 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset mw.visitJumpInsn(IF_ICMPNE, reset_); _newCollection(mw, fieldClass, i, false); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); _getCollectionFieldItemDeser(context, mw, fieldInfo, itemType); mw.visitVarInsn(ALOAD, 1); @@ -1324,7 +1377,7 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;"); mw.visitVarInsn(ASTORE, context.var("list_item_value")); - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); mw.visitVarInsn(ALOAD, context.var("list_item_value")); if (fieldClass.isInterface()) { mw.visitMethodInsn(INVOKEINTERFACE, type(fieldClass), "add", "(Ljava/lang/Object;)Z"); @@ -1340,7 +1393,7 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset _newCollection(mw, fieldClass, i, false); mw.visitLabel(storeCollection_); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); boolean isPrimitive = ParserConfig.isPrimitive2(fieldInfo.fieldClass); _getCollectionFieldItemDeser(context, mw, fieldInfo, itemType); @@ -1365,7 +1418,7 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset mw.visitVarInsn(ASTORE, context.var("listContext")); mw.visitVarInsn(ALOAD, 1); // parser - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); mw.visitLdcInsn(fieldInfo.name); mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "setContext", "(Ljava/lang/Object;Ljava/lang/Object;)" + desc(ParseContext.class)); @@ -1402,7 +1455,7 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset mw.visitIincInsn(context.var("i"), 1); - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); mw.visitVarInsn(ALOAD, context.var("list_item_value")); if (fieldClass.isInterface()) { mw.visitMethodInsn(INVOKEINTERFACE, type(fieldClass), "add", "(Ljava/lang/Object;)Z"); @@ -1412,7 +1465,7 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset mw.visitInsn(POP); mw.visitVarInsn(ALOAD, 1); - mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ALOAD, context.var_asm(fieldInfo)); mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "checkListResolve", "(Ljava/util/Collection;)V"); mw.visitVarInsn(ALOAD, context.var("lexer")); @@ -1609,11 +1662,11 @@ private void _deserialze_obj(Context context, MethodVisitor mw, Label reset_, Fi mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldName(fieldInfo), "[C"); mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "matchField", "([C)Z"); mw.visitJumpInsn(IFNE, matched_); mw.visitInsn(ACONST_NULL); - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitJumpInsn(GOTO, _end_if); @@ -1682,7 +1735,7 @@ private void _deserObject(Context context, MethodVisitor mw, FieldInfo fieldInfo mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "deserialze", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;I)Ljava/lang/Object;"); mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitJumpInsn(GOTO, instanceOfEnd_); @@ -1702,7 +1755,7 @@ private void _deserObject(Context context, MethodVisitor mw, FieldInfo fieldInfo mw.visitMethodInsn(INVOKEINTERFACE, type(ObjectDeserializer.class), "deserialze", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;"); mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast - mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm")); + mw.visitVarInsn(ASTORE, context.var_asm(fieldInfo)); mw.visitLabel(instanceOfEnd_); } @@ -1710,7 +1763,7 @@ private void _deserObject(Context context, MethodVisitor mw, FieldInfo fieldInfo private void _getFieldDeser(Context context, MethodVisitor mw, FieldInfo fieldInfo) { Label notNull_ = new Label(); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_deser__", desc(ObjectDeserializer.class)); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldDeserName(fieldInfo), desc(ObjectDeserializer.class)); mw.visitJumpInsn(IFNONNULL, notNull_); mw.visitVarInsn(ALOAD, 0); @@ -1721,12 +1774,12 @@ private void _getFieldDeser(Context context, MethodVisitor mw, FieldInfo fieldIn mw.visitMethodInsn(INVOKEVIRTUAL, type(ParserConfig.class), "getDeserializer", "(Ljava/lang/reflect/Type;)" + desc(ObjectDeserializer.class)); - mw.visitFieldInsn(PUTFIELD, context.className, fieldInfo.name + "_asm_deser__", desc(ObjectDeserializer.class)); + mw.visitFieldInsn(PUTFIELD, context.className, context.fieldDeserName(fieldInfo), desc(ObjectDeserializer.class)); mw.visitLabel(notNull_); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_deser__", desc(ObjectDeserializer.class)); + mw.visitFieldInsn(GETFIELD, context.className, context.fieldDeserName(fieldInfo), desc(ObjectDeserializer.class)); } static class Context { @@ -1778,13 +1831,52 @@ public int var(String name) { i = variants.get(name); return i.intValue(); } + + public int var_asm(FieldInfo fieldInfo) { + return var(fieldInfo.name + "_asm"); + } + + public int var_asm(FieldInfo fieldInfo, int increment) { + return var(fieldInfo.name + "_asm", increment); + } + + public String fieldName(FieldInfo fieldInfo) { + return validIdent(fieldInfo.name) + ? fieldInfo.name + "_asm_prefix__" + : "asm_field_" + TypeUtils.fnv1a_64_extract(fieldInfo.name); + } + + + public String fieldDeserName(FieldInfo fieldInfo) { + return validIdent(fieldInfo.name) + ? fieldInfo.name + "_asm_deser__" + : "_asm_deser__" + TypeUtils.fnv1a_64_extract(fieldInfo.name); + } + + + boolean validIdent(String name) { + for (int i = 0; i < name.length(); ++i) { + char ch = name.charAt(i); + if (ch == 0) { + if (!IOUtils.firstIdentifier(ch)) { + return false; + } + } else { + if (!IOUtils.isIdent(ch)) { + return false; + } + } + } + + return true; + } } private void _init(ClassWriter cw, Context context) { for (int i = 0, size = context.fieldInfoList.length; i < size; ++i) { FieldInfo fieldInfo = context.fieldInfoList[i]; - FieldWriter fw = new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_prefix__", "[C"); + FieldWriter fw = new FieldWriter(cw, ACC_PUBLIC, context.fieldName(fieldInfo), "[C"); fw.visitEnd(); } @@ -1801,7 +1893,7 @@ private void _init(ClassWriter cw, Context context) { desc(ObjectDeserializer.class)); fw.visitEnd(); } else { - FieldWriter fw = new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_deser__", + FieldWriter fw = new FieldWriter(cw, ACC_PUBLIC, context.fieldDeserName(fieldInfo), desc(ObjectDeserializer.class)); fw.visitEnd(); } @@ -1822,7 +1914,7 @@ private void _init(ClassWriter cw, Context context) { mw.visitVarInsn(ALOAD, 0); mw.visitLdcInsn("\"" + fieldInfo.name + "\":"); // public char[] toCharArray() mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toCharArray", "()[C"); - mw.visitFieldInsn(PUTFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C"); + mw.visitFieldInsn(PUTFIELD, context.className, context.fieldName(fieldInfo), "[C"); } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/AbstractDateDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/AbstractDateDeserializer.java old mode 100755 new mode 100644 index 9ffb278310..91a4d3020a --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/AbstractDateDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/AbstractDateDeserializer.java @@ -3,6 +3,7 @@ import java.lang.reflect.Type; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Locale; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; @@ -22,32 +23,77 @@ public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName, Object val; if (lexer.token() == JSONToken.LITERAL_INT) { - val = lexer.longValue(); + long millis = lexer.longValue(); lexer.nextToken(JSONToken.COMMA); + if ("unixtime".equals(format)) { + millis *= 1000; + } + val = millis; } else if (lexer.token() == JSONToken.LITERAL_STRING) { String strVal = lexer.stringVal(); if (format != null) { + if ("yyyy-MM-dd HH:mm:ss.SSSSSSSSS".equals(format) + && clazz instanceof Class + && ((Class) clazz).getName().equals("java.sql.Timestamp")) { + return (T) TypeUtils.castToTimestamp(strVal); + } + SimpleDateFormat simpleDateFormat = null; try { - simpleDateFormat = new SimpleDateFormat(format,JSON.defaultLocale); + simpleDateFormat = new SimpleDateFormat(format, parser.lexer.getLocale()); } catch (IllegalArgumentException ex) { - if (format.equals("yyyy-MM-ddTHH:mm:ss.SSS")) { - format = "yyyy-MM-dd'T'HH:mm:ss.SSS"; - simpleDateFormat = new SimpleDateFormat(format); - } else if (format.equals("yyyy-MM-ddTHH:mm:ss")) { - format = "yyyy-MM-dd'T'HH:mm:ss"; - simpleDateFormat = new SimpleDateFormat(format); + if (format.contains("T")) { + String fromat2 = format.replaceAll("T", "'T'"); + try { + simpleDateFormat = new SimpleDateFormat(fromat2, parser.lexer.getLocale()); + } catch (IllegalArgumentException e2) { + throw ex; + } } } + if (JSON.defaultTimeZone != null) { + simpleDateFormat.setTimeZone(parser.lexer.getTimeZone()); + } + try { val = simpleDateFormat.parse(strVal); } catch (ParseException ex) { + val = null; + // skip + } + + if (val == null && JSON.defaultLocale == Locale.CHINA) { + try { + simpleDateFormat = new SimpleDateFormat(format, Locale.US); + } catch (IllegalArgumentException ex) { + if (format.contains("T")) { + String fromat2 = format.replaceAll("T", "'T'"); + try { + simpleDateFormat = new SimpleDateFormat(fromat2, parser.lexer.getLocale()); + } catch (IllegalArgumentException e2) { + throw ex; + } + } + } + simpleDateFormat.setTimeZone(parser.lexer.getTimeZone()); + + try { + val = simpleDateFormat.parse(strVal); + } catch (ParseException ex) { + val = null; + // skip + } + } + + if (val == null) { if (format.equals("yyyy-MM-dd'T'HH:mm:ss.SSS") // && strVal.length() == 19) { try { - val = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(strVal); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", JSON.defaultLocale); + df.setTimeZone(JSON.defaultTimeZone); + val = df.parse(strVal); } catch (ParseException ex2) { // skip val = null; diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java old mode 100755 new mode 100644 index c8db519937..158ff8e52f --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java @@ -8,6 +8,8 @@ import java.util.Collection; import java.util.Map; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.JSONLexer; @@ -53,7 +55,11 @@ public void parseField(DefaultJSONParser parser, Object object, Type objectType, final int token = lexer.token(); if (token == JSONToken.NULL || (token == JSONToken.LITERAL_STRING && lexer.stringVal().length() == 0)) { - setValue(object, null); + if (object == null) { + fieldValues.put(fieldInfo.name, null); + } else { + setValue(object, null); + } return; } @@ -130,10 +136,27 @@ public final void parseArray(DefaultJSONParser parser, Type objectType, Collecti if (paramIndex != -1) { itemActualTypeArgs[0] = paramType.getActualTypeArguments()[paramIndex]; - itemType = new ParameterizedTypeImpl(itemActualTypeArgs, parameterizedItemType.getOwnerType(), parameterizedItemType.getRawType()); + itemType = TypeReference.intern( + new ParameterizedTypeImpl(itemActualTypeArgs, parameterizedItemType.getOwnerType(), parameterizedItemType.getRawType()) + ); } } } + } else if (itemType instanceof TypeVariable && objectType instanceof Class) { + Class objectClass = (Class) objectType; + TypeVariable typeVar = (TypeVariable) itemType; + objectClass.getTypeParameters(); + + for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) { + TypeVariable item = objectClass.getTypeParameters()[i]; + if (item.getName().equals(typeVar.getName())) { + Type[] bounds = item.getBounds(); + if (bounds.length == 1) { + itemType = bounds[0]; + } + break; + } + } } final JSONLexer lexer = parser.lexer; @@ -147,7 +170,7 @@ public final void parseArray(DefaultJSONParser parser, Type objectType, Collecti lexer.nextToken(itemFastMatchToken); - for (int i = 0;; ++i) { + for (int i = 0; ; ++i) { if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { while (lexer.token() == JSONToken.COMMA) { lexer.nextToken(); @@ -171,6 +194,11 @@ public final void parseArray(DefaultJSONParser parser, Type objectType, Collecti } lexer.nextToken(JSONToken.COMMA); + } else if (token == JSONToken.LITERAL_STRING && fieldInfo.unwrapped) { + String str = lexer.stringVal(); + lexer.nextToken(); + DefaultJSONParser valueParser = new DefaultJSONParser(str); + valueParser.parseArray(array); } else { if (itemTypeDeser == null) { itemTypeDeser = deserializer = parser.getConfig().getDeserializer(itemType); diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/AutowiredObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/AutowiredObjectDeserializer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java old mode 100755 new mode 100644 index 86b2dbcee1..fa578a767a --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; import java.util.Map; import java.util.zip.GZIPInputStream; @@ -21,9 +20,15 @@ public class DefaultFieldDeserializer extends FieldDeserializer { protected ObjectDeserializer fieldValueDeserilizer; + protected boolean customDeserilizer = false; - public DefaultFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo){ + public DefaultFieldDeserializer(ParserConfig config, Class clazz, FieldInfo fieldInfo){ super(clazz, fieldInfo); + JSONField annotation = fieldInfo.getAnnotation(); + if (annotation != null) { + Class deserializeUsing = annotation.deserializeUsing(); + customDeserilizer = deserializeUsing != null && deserializeUsing != Void.class; + } } public ObjectDeserializer getFieldValueDeserilizer(ParserConfig config) { @@ -59,7 +64,9 @@ public void parseField(DefaultJSONParser parser, Object object, Type objectType, } if (fieldType != objectType) { fieldType = FieldInfo.getFieldType(this.clazz, objectType, fieldType); - fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldType); + if (fieldValueDeserilizer instanceof JavaObjectDeserializer) { + fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldType); + } } } @@ -69,7 +76,8 @@ public void parseField(DefaultJSONParser parser, Object object, Type objectType, JavaBeanDeserializer javaBeanDeser = (JavaBeanDeserializer) fieldValueDeserilizer; value = javaBeanDeser.deserialze(parser, fieldType, fieldInfo.name, fieldInfo.parserFeatures); } else { - if (this.fieldInfo.format != null && fieldValueDeserilizer instanceof ContextObjectDeserializer) { + if ((this.fieldInfo.format != null || this.fieldInfo.parserFeatures != 0) + && fieldValueDeserilizer instanceof ContextObjectDeserializer) { value = ((ContextObjectDeserializer) fieldValueDeserilizer) // .deserialze(parser, fieldType, diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumCreatorDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumCreatorDeserializer.java new file mode 100644 index 0000000000..caebdd72f4 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumCreatorDeserializer.java @@ -0,0 +1,33 @@ +package com.alibaba.fastjson.parser.deserializer; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +public class EnumCreatorDeserializer implements ObjectDeserializer { + private final Method creator; + private final Class paramType; + + public EnumCreatorDeserializer(Method creator) { + this.creator = creator; + paramType = creator.getParameterTypes()[0]; + } + + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + Object arg = parser.parseObject(paramType); + try { + return (T) creator.invoke(null, arg); + } catch (IllegalAccessException e) { + throw new JSONException("parse enum error", e); + } catch (InvocationTargetException e) { + throw new JSONException("parse enum error", e); + } + } + + public int getFastMatchToken() { + return 0; + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java old mode 100755 new mode 100644 index 19bf69e794..3d95a1189d --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java @@ -7,8 +7,13 @@ import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.TypeUtils; + +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime; @SuppressWarnings("rawtypes") public class EnumDeserializer implements ObjectDeserializer { @@ -31,7 +36,7 @@ public EnumDeserializer(Class enumClass){ JSONField jsonField = null; try { Field field = enumClass.getField(name); - jsonField = field.getAnnotation(JSONField.class); + jsonField = TypeUtils.getAnnotation(field, JSONField.class); if (jsonField != null) { String jsonFieldName = jsonField.name(); if (jsonFieldName != null && jsonFieldName.length() > 0) { @@ -42,16 +47,16 @@ public EnumDeserializer(Class enumClass){ // skip } - long hash = 0xcbf29ce484222325L; - long hash_lower = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; + long hash_lower = fnv1a_64_magic_hashcode; for (int j = 0; j < name.length(); ++j) { char ch = name.charAt(j); hash ^= ch; hash_lower ^= ((ch >= 'A' && ch <= 'Z') ? (ch + 32) : ch); - hash *= 0x100000001b3L; - hash_lower *= 0x100000001b3L; + hash *= fnv1a_64_magic_prime; + hash_lower *= fnv1a_64_magic_prime; } enumMap.put(hash, e); @@ -61,11 +66,11 @@ public EnumDeserializer(Class enumClass){ if (jsonField != null) { for (String alterName : jsonField.alternateNames()) { - long alterNameHash = 0xcbf29ce484222325L; + long alterNameHash = fnv1a_64_magic_hashcode; for (int j = 0; j < alterName.length(); ++j) { char ch = alterName.charAt(j); alterNameHash ^= ch; - alterNameHash *= 0x100000001b3L; + alterNameHash *= fnv1a_64_magic_prime; } if (alterNameHash != hash && alterNameHash != hash_lower) { enumMap.put(alterNameHash, e); @@ -119,7 +124,7 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { int intValue = lexer.intValue(); lexer.nextToken(JSONToken.COMMA); - if (intValue < 0 || intValue > ordinalEnums.length) { + if (intValue < 0 || intValue >= ordinalEnums.length) { throw new JSONException("parse enum " + enumClass.getName() + " error, value : " + intValue); } @@ -132,14 +137,27 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { return (T) null; } - long hash = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; + long hash_lower = fnv1a_64_magic_hashcode; for (int j = 0; j < name.length(); ++j) { char ch = name.charAt(j); + hash ^= ch; - hash *= 0x100000001b3L; + hash_lower ^= ((ch >= 'A' && ch <= 'Z') ? (ch + 32) : ch); + + hash *= fnv1a_64_magic_prime; + hash_lower *= fnv1a_64_magic_prime; } - return (T) getEnumByHashCode(hash); + Enum e = getEnumByHashCode(hash); + if (e == null && hash_lower != hash) { + e = getEnumByHashCode(hash_lower); + } + + if (e == null && lexer.isEnabled(Feature.ErrorOnEnumNotMatch)) { + throw new JSONException("not match enum value, " + enumClass.getName() + " : " + name); + } + return (T) e; } else if (token == JSONToken.NULL) { value = null; lexer.nextToken(JSONToken.COMMA); diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java old mode 100755 new mode 100644 index 66a903e356..17c78a15b5 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java @@ -1,32 +1,37 @@ package com.alibaba.fastjson.parser.deserializer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Type; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.BeanContext; +import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.TypeUtils; + +import java.lang.reflect.*; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultJSONParser; -import com.alibaba.fastjson.serializer.BeanContext; -import com.alibaba.fastjson.util.FieldInfo; - public abstract class FieldDeserializer { public final FieldInfo fieldInfo; - protected final Class clazz; - - protected BeanContext beanContext; + protected final Class clazz; + + protected BeanContext beanContext; - public FieldDeserializer(Class clazz, FieldInfo fieldInfo){ + public FieldDeserializer(Class clazz, FieldInfo fieldInfo) { this.clazz = clazz; this.fieldInfo = fieldInfo; } - + + public Class getOwnerClass() { + return clazz; + } + public abstract void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues); @@ -50,14 +55,14 @@ public void setValue(Object object, String value) { setValue(object, (Object) value); } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) public void setValue(Object object, Object value) { if (value == null // - && fieldInfo.fieldClass.isPrimitive()) { + && fieldInfo.fieldClass.isPrimitive()) { return; } else if (fieldInfo.fieldClass == String.class && fieldInfo.format != null - && fieldInfo.format.equals("trim")){ + && fieldInfo.format.equals("trim")) { value = ((String) value).trim(); } @@ -69,27 +74,93 @@ public void setValue(Object object, Object value) { AtomicInteger atomic = (AtomicInteger) method.invoke(object); if (atomic != null) { atomic.set(((AtomicInteger) value).get()); + } else { + degradeValueAssignment(fieldInfo.field, method, object, value); } } else if (fieldInfo.fieldClass == AtomicLong.class) { AtomicLong atomic = (AtomicLong) method.invoke(object); if (atomic != null) { atomic.set(((AtomicLong) value).get()); + } else { + degradeValueAssignment(fieldInfo.field, method, object, value); } } else if (fieldInfo.fieldClass == AtomicBoolean.class) { AtomicBoolean atomic = (AtomicBoolean) method.invoke(object); if (atomic != null) { atomic.set(((AtomicBoolean) value).get()); + } else { + degradeValueAssignment(fieldInfo.field, method, object, value); } } else if (Map.class.isAssignableFrom(method.getReturnType())) { - Map map = (Map) method.invoke(object); + Map map = null; + try { + map = (Map) method.invoke(object); + } catch (InvocationTargetException e) { + degradeValueAssignment(fieldInfo.field, method, object, value); + return; + } if (map != null) { + if (map == Collections.emptyMap()) { + return; + } + + if (map.isEmpty() && ((Map) value).isEmpty()) { + return; + } + + String mapClassName = map.getClass().getName(); + if (mapClassName.equals("java.util.ImmutableCollections$Map1") + || mapClassName.equals("java.util.ImmutableCollections$MapN") + || mapClassName.startsWith("java.util.Collections$Unmodifiable")) { + // skip + + return; + } + + if (map.getClass().getName().equals("kotlin.collections.EmptyMap")) { + degradeValueAssignment(fieldInfo.field, method, object, value); + return; + } + map.putAll((Map) value); + } else if (value != null) { + degradeValueAssignment(fieldInfo.field, method, object, value); } } else { - Collection collection = (Collection) method.invoke(object); + Collection collection = null; + try { + collection = (Collection) method.invoke(object); + } catch (InvocationTargetException e) { + degradeValueAssignment(fieldInfo.field, method, object, value); + return; + } if (collection != null && value != null) { - collection.clear(); + String collectionClassName = collection.getClass().getName(); + + if (collection == Collections.emptySet() + || collection == Collections.emptyList() + || collectionClassName == "java.util.ImmutableCollections$ListN" + || collectionClassName == "java.util.ImmutableCollections$List12" + || collectionClassName.startsWith("java.util.Collections$Unmodifiable")) { + // skip + return; + } + + if (!collection.isEmpty()) { + collection.clear(); + } else if (((Collection) value).isEmpty()) { + return; //skip + } + + + if (collectionClassName.equals("kotlin.collections.EmptyList") + || collectionClassName.equals("kotlin.collections.EmptySet")) { + degradeValueAssignment(fieldInfo.field, method, object, value); + return; + } collection.addAll((Collection) value); + } else if (collection == null && value != null) { + degradeValueAssignment(fieldInfo.field, method, object, value); } } } else { @@ -117,11 +188,23 @@ public void setValue(Object object, Object value) { } else if (Map.class.isAssignableFrom(fieldInfo.fieldClass)) { Map map = (Map) field.get(object); if (map != null) { + if (map == Collections.emptyMap() + || map.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) { + // skip + return; + } map.putAll((Map) value); } } else { Collection collection = (Collection) field.get(object); if (collection != null && value != null) { + if (collection == Collections.emptySet() + || collection == Collections.emptyList() + || collection.getClass().getName().startsWith("java.util.Collections$Unmodifiable")) { + // skip + return; + } + collection.clear(); collection.addAll((Collection) value); } @@ -133,8 +216,43 @@ public void setValue(Object object, Object value) { } } } catch (Exception e) { - throw new JSONException("set property error, " + fieldInfo.name, e); + throw new JSONException("set property error, " + clazz.getName() + "#" + fieldInfo.name, e); + } + } + + /** + * kotlin代理类property的get方法会抛未初始化异常,用set方法直接赋值 + */ + private static boolean degradeValueAssignment( + Field field, + Method getMethod, + Object object, + Object value + ) throws InvocationTargetException, IllegalAccessException { + if (setFieldValue(field, object, value)) { + return true; + } + + try { + Method setMethod = object + .getClass() + .getDeclaredMethod("set" + getMethod.getName().substring(3), getMethod.getReturnType()); + setMethod.invoke(object, value); + return true; + } catch (InvocationTargetException ignored) { + } catch (NoSuchMethodException ignored) { + } catch (IllegalAccessException ignored) { + } + return false; + } + + private static boolean setFieldValue(Field field, Object object, Object value) throws IllegalAccessException { + if (field != null + && !Modifier.isFinal(field.getModifiers())) { + field.set(object, value); + return true; } + return false; } public void setWrappedValue(String key, Object value) { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java old mode 100755 new mode 100644 index b5821dc00e..a19e652a91 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java @@ -1,28 +1,25 @@ package com.alibaba.fastjson.parser.deserializer; -import java.lang.reflect.*; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONValidator; import com.alibaba.fastjson.annotation.JSONField; -import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.*; import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONLexerBase; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.parser.ParseContext; -import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.FieldInfo; import com.alibaba.fastjson.util.JavaBeanInfo; import com.alibaba.fastjson.util.TypeUtils; +import java.lang.reflect.*; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; + public class JavaBeanDeserializer implements ObjectDeserializer { private final FieldDeserializer[] fieldDeserializers; @@ -32,12 +29,15 @@ public class JavaBeanDeserializer implements ObjectDeserializer { private ConcurrentMap extraFieldDeserializers; private final Map alterNameFieldDeserializers; + private Map fieldDeserializerMap; private transient long[] smartMatchHashArray; private transient short[] smartMatchHashArrayMapping; private transient long[] hashArray; private transient short[] hashArrayMapping; + + private final ParserConfig.AutoTypeCheckHandler autoTypeCheckHandler; public JavaBeanDeserializer(ParserConfig config, Class clazz) { this(config, clazz, clazz); @@ -45,7 +45,7 @@ public JavaBeanDeserializer(ParserConfig config, Class clazz) { public JavaBeanDeserializer(ParserConfig config, Class clazz, Type type){ this(config // - , JavaBeanInfo.build(clazz, type, config.propertyNamingStrategy, config.fieldBased, config.compatibleWithJavaBean) + , JavaBeanInfo.build(clazz, type, config.propertyNamingStrategy, config.fieldBased, config.compatibleWithJavaBean, config.isJacksonCompatible()) ); } @@ -53,6 +53,16 @@ public JavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo){ this.clazz = beanInfo.clazz; this.beanInfo = beanInfo; + ParserConfig.AutoTypeCheckHandler autoTypeCheckHandler = null; + if (beanInfo.jsonType != null && beanInfo.jsonType.autoTypeCheckHandler() != ParserConfig.AutoTypeCheckHandler.class) { + try { + autoTypeCheckHandler = beanInfo.jsonType.autoTypeCheckHandler().newInstance(); + } catch (Exception e) { + // + } + } + this.autoTypeCheckHandler = autoTypeCheckHandler; + Map alterNameFieldDeserializers = null; sortedFieldDeserializers = new FieldDeserializer[beanInfo.sortedFields.length]; for (int i = 0, size = beanInfo.sortedFields.length; i < size; ++i) { @@ -61,6 +71,13 @@ public JavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo){ sortedFieldDeserializers[i] = fieldDeserializer; + if (size > 128) { + if (fieldDeserializerMap == null) { + fieldDeserializerMap = new HashMap(); + } + fieldDeserializerMap.put(fieldInfo.name, fieldDeserializer); + } + for (String name : fieldInfo.alternateNames) { if (alterNameFieldDeserializers == null) { alterNameFieldDeserializers = new HashMap(); @@ -86,6 +103,13 @@ public FieldDeserializer getFieldDeserializer(String key, int[] setFlags) { if (key == null) { return null; } + + if (fieldDeserializerMap != null) { + FieldDeserializer fieldDeserializer = fieldDeserializerMap.get(key); + if (fieldDeserializer != null) { + return fieldDeserializer; + } + } int low = 0; int high = sortedFieldDeserializers.length - 1; @@ -159,14 +183,8 @@ static boolean isSetFlag(int i, int[] setFlags) { } int flagIndex = i / 32; - int bitIndex = i % 32; - if (flagIndex < setFlags.length) { - if ((setFlags[flagIndex] & (1 << bitIndex)) != 0) { - return true; - } - } - - return false; + return flagIndex < setFlags.length + && (setFlags[flagIndex] & (1 << i % 32)) != 0; } public Object createInstance(DefaultJSONParser parser, Type type) { @@ -230,12 +248,14 @@ public Object createInstance(DefaultJSONParser parser, Type type) { if (parentName.equals(parentClassName)) { param = parentContext.object; } + } else { + param = ctxObj; } } else { param = ctxObj; } - if (param == null) { + if (param == null || param instanceof Collection && ((Collection)param).isEmpty()) { throw new JSONException("can't create non-static inner class instance."); } @@ -278,6 +298,22 @@ public T deserialzeArrayMapping(DefaultJSONParser parser, Type type, Object throw new JSONException("error"); } + String typeName = null; + if ((typeName = lexer.scanTypeName(parser.symbolTable)) != null) { + ObjectDeserializer deserializer = getSeeAlso(parser.getConfig(), this.beanInfo, typeName); + Class userType = null; + + if (deserializer == null) { + Class expectClass = TypeUtils.getClass(type); + userType = parser.getConfig().checkAutoType(typeName, expectClass, lexer.getFeatures()); + deserializer = parser.getConfig().getDeserializer(userType); + } + + if (deserializer instanceof JavaBeanDeserializer) { + return ((JavaBeanDeserializer) deserializer).deserialzeArrayMapping(parser, type, fieldName, object); + } + } + object = createInstance(parser, type); for (int i = 0, size = sortedFieldDeserializers.length; i < size; ++i) { @@ -424,8 +460,6 @@ protected T deserialze(DefaultJSONParser parser, // } } } - } else if (token == JSONToken.LITERAL_ISO8601_DATE) { - Calendar calendar = lexer.getCalendar(); } if (token == JSONToken.LBRACKET && lexer.getCurrent() == ']') { @@ -433,8 +467,29 @@ protected T deserialze(DefaultJSONParser parser, // lexer.nextToken(); return null; } + + if (beanInfo.factoryMethod != null && beanInfo.fields.length == 1) { + try { + FieldInfo field = beanInfo.fields[0]; + if (field.fieldClass == Integer.class) { + if (token == JSONToken.LITERAL_INT) { + int intValue = lexer.intValue(); + lexer.nextToken(); + return (T) createFactoryInstance(config, intValue); + } + } else if (field.fieldClass == String.class) { + if (token == JSONToken.LITERAL_STRING) { + String stringVal = lexer.stringVal(); + lexer.nextToken(); + return (T) createFactoryInstance(config, stringVal); + } + } + } catch (Exception ex) { + throw new JSONException(ex.getMessage(), ex); + } + } - StringBuffer buf = (new StringBuffer()) // + StringBuilder buf = (new StringBuilder()) // .append("syntax error, expect {, actual ") // .append(lexer.tokenName()) // .append(", pos ") // @@ -456,42 +511,60 @@ protected T deserialze(DefaultJSONParser parser, // } String typeKey = beanInfo.typeKey; - for (int fieldIndex = 0;; fieldIndex++) { + for (int fieldIndex = 0, notMatchCount = 0;; fieldIndex++) { String key = null; - FieldDeserializer fieldDeser = null; + FieldDeserializer fieldDeserializer = null; FieldInfo fieldInfo = null; Class fieldClass = null; - JSONField feildAnnotation = null; - if (fieldIndex < sortedFieldDeserializers.length) { - fieldDeser = sortedFieldDeserializers[fieldIndex]; - fieldInfo = fieldDeser.fieldInfo; + JSONField fieldAnnotation = null; + boolean customDeserializer = false; + if (fieldIndex < sortedFieldDeserializers.length && notMatchCount < 16) { + fieldDeserializer = sortedFieldDeserializers[fieldIndex]; + fieldInfo = fieldDeserializer.fieldInfo; fieldClass = fieldInfo.fieldClass; - feildAnnotation = fieldInfo.getAnnotation(); + fieldAnnotation = fieldInfo.getAnnotation(); + if (fieldAnnotation != null && fieldDeserializer instanceof DefaultFieldDeserializer) { + customDeserializer = ((DefaultFieldDeserializer) fieldDeserializer).customDeserilizer; + } } boolean matchField = false; boolean valueParsed = false; Object fieldValue = null; - if (fieldDeser != null) { + if (fieldDeserializer != null) { char[] name_chars = fieldInfo.name_chars; - if (fieldClass == int.class || fieldClass == Integer.class) { - fieldValue = lexer.scanFieldInt(name_chars); - + if (customDeserializer && lexer.matchField(name_chars)) { + matchField = true; + } else if (fieldClass == int.class || fieldClass == Integer.class) { + int intVal = lexer.scanFieldInt(name_chars); + if (intVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { + fieldValue = null; + } else { + fieldValue = intVal; + } + if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { - continue; + notMatchCount++; + continue; } } else if (fieldClass == long.class || fieldClass == Long.class) { - fieldValue = lexer.scanFieldLong(name_chars); - + long longVal = lexer.scanFieldLong(name_chars); + if (longVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { + fieldValue = null; + } else { + fieldValue = longVal; + } + if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { - continue; + notMatchCount++; + continue; } } else if (fieldClass == String.class) { fieldValue = lexer.scanFieldString(name_chars); @@ -500,7 +573,8 @@ protected T deserialze(DefaultJSONParser parser, // matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { - continue; + notMatchCount++; + continue; } } else if (fieldClass == java.util.Date.class && fieldInfo.format == null) { fieldValue = lexer.scanFieldDate(name_chars); @@ -509,6 +583,7 @@ protected T deserialze(DefaultJSONParser parser, // matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { + notMatchCount++; continue; } } else if (fieldClass == BigDecimal.class) { @@ -518,6 +593,7 @@ protected T deserialze(DefaultJSONParser parser, // matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { + notMatchCount++; continue; } } else if (fieldClass == BigInteger.class) { @@ -527,47 +603,68 @@ protected T deserialze(DefaultJSONParser parser, // matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { + notMatchCount++; continue; } } else if (fieldClass == boolean.class || fieldClass == Boolean.class) { - fieldValue = lexer.scanFieldBoolean(name_chars); + boolean booleanVal = lexer.scanFieldBoolean(name_chars); + + if (lexer.matchStat == JSONLexer.VALUE_NULL) { + fieldValue = null; + } else { + fieldValue = booleanVal; + } if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { - continue; + notMatchCount++; + continue; } } else if (fieldClass == float.class || fieldClass == Float.class) { - fieldValue = lexer.scanFieldFloat(name_chars); - + float floatVal = lexer.scanFieldFloat(name_chars); + if (floatVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { + fieldValue = null; + } else { + fieldValue = floatVal; + } + if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { - continue; + notMatchCount++; + continue; } } else if (fieldClass == double.class || fieldClass == Double.class) { - fieldValue = lexer.scanFieldDouble(name_chars); - + double doubleVal = lexer.scanFieldDouble(name_chars); + if (doubleVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { + fieldValue = null; + } else { + fieldValue = doubleVal; + } + if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { - continue; + notMatchCount++; + continue; } } else if (fieldClass.isEnum() // && parser.getConfig().getDeserializer(fieldClass) instanceof EnumDeserializer - && (feildAnnotation == null || feildAnnotation.deserializeUsing() == Void.class) + && (fieldAnnotation == null || fieldAnnotation.deserializeUsing() == Void.class) ) { - if (fieldDeser instanceof DefaultFieldDeserializer) { - ObjectDeserializer fieldValueDeserilizer = ((DefaultFieldDeserializer) fieldDeser).fieldValueDeserilizer; + if (fieldDeserializer instanceof DefaultFieldDeserializer) { + ObjectDeserializer fieldValueDeserilizer = ((DefaultFieldDeserializer) fieldDeserializer).fieldValueDeserilizer; fieldValue = this.scanEnum(lexer, name_chars, fieldValueDeserilizer); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { + notMatchCount++; continue; } } @@ -578,6 +675,7 @@ protected T deserialze(DefaultJSONParser parser, // matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { + notMatchCount++; continue; } } else if (fieldClass == float[].class) { @@ -587,6 +685,7 @@ protected T deserialze(DefaultJSONParser parser, // matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { + notMatchCount++; continue; } } else if (fieldClass == float[][].class) { @@ -596,6 +695,7 @@ protected T deserialze(DefaultJSONParser parser, // matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { + notMatchCount++; continue; } } else if (lexer.matchField(name_chars)) { @@ -649,6 +749,17 @@ protected T deserialze(DefaultJSONParser parser, // parser.resolveStatus = DefaultJSONParser.NeedToResolve; } } else { + if (ref.indexOf('\\') > 0) { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < ref.length(); ++i) { + char ch = ref.charAt(i); + if (ch == '\\') { + ch = ref.charAt(++i); + } + buf.append(ch); + } + ref = buf.toString(); + } Object refObj = parser.resolveReference(ref); if (refObj != null) { object = refObj; @@ -693,7 +804,24 @@ protected T deserialze(DefaultJSONParser parser, // if (deserializer == null) { Class expectClass = TypeUtils.getClass(type); - userType = config.checkAutoType(typeName, expectClass, lexer.getFeatures()); + + if (autoTypeCheckHandler != null) { + userType = autoTypeCheckHandler.handler(typeName, expectClass, lexer.getFeatures()); + } + + if (userType == null) { + if (typeName.equals("java.util.HashMap") || typeName.equals("java.util.LinkedHashMap")) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + break; + } + continue; + } + } + + if (userType == null) { + userType = config.checkAutoType(typeName, expectClass, lexer.getFeatures()); + } deserializer = parser.getConfig().getDeserializer(userType); } @@ -702,7 +830,9 @@ protected T deserialze(DefaultJSONParser parser, // JavaBeanDeserializer javaBeanDeserializer = (JavaBeanDeserializer) deserializer; if (typeKey != null) { FieldDeserializer typeKeyFieldDeser = javaBeanDeserializer.getFieldDeserializer(typeKey); - typeKeyFieldDeser.setValue(typedObject, typeName); + if (typeKeyFieldDeser != null) { + typeKeyFieldDeser.setValue(typedObject, typeName); + } } } return (T) typedObject; @@ -725,7 +855,7 @@ protected T deserialze(DefaultJSONParser parser, // if (matchField) { if (!valueParsed) { - fieldDeser.parseField(parser, object, type, fieldValues); + fieldDeserializer.parseField(parser, object, type, fieldValues); } else { if (object == null) { fieldValues.put(fieldInfo.name, fieldValue); @@ -736,16 +866,23 @@ protected T deserialze(DefaultJSONParser parser, // && fieldClass != double.class // && fieldClass != boolean.class // ) { - fieldDeser.setValue(object, fieldValue); + fieldDeserializer.setValue(object, fieldValue); } } else { - fieldDeser.setValue(object, fieldValue); + if (fieldClass == String.class + && ((features & Feature.TrimStringFieldValue.mask) != 0 + || (beanInfo.parserFeatures & Feature.TrimStringFieldValue.mask) != 0 + || (fieldInfo.parserFeatures & Feature.TrimStringFieldValue.mask) != 0)) { + fieldValue = ((String) fieldValue).trim(); + } + + fieldDeserializer.setValue(object, fieldValue); } if (setFlags != null) { int flagIndex = fieldIndex / 32; int bitIndex = fieldIndex % 32; - setFlags[flagIndex] |= (1 >> bitIndex); + setFlags[flagIndex] |= (1 << bitIndex); } if (lexer.matchStat == JSONLexer.END) { @@ -753,7 +890,9 @@ protected T deserialze(DefaultJSONParser parser, // } } } else { - boolean match = parseField(parser, key, object, type, fieldValues, setFlags); + boolean match = parseField(parser, key, object, type, + fieldValues == null ? new HashMap(this.fieldDeserializers.length) : fieldValues, setFlags); + if (!match) { if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(); @@ -818,6 +957,24 @@ protected T deserialze(DefaultJSONParser parser, // && (fieldInfo.parserFeatures & Feature.InitStringFieldAsEmpty.mask) != 0) { param = ""; } + } else { + if (beanInfo.creatorConstructorParameterTypes != null && i < beanInfo.creatorConstructorParameterTypes.length) { + Type paramType = beanInfo.creatorConstructorParameterTypes[i]; + if (paramType instanceof Class) { + Class paramClass = (Class) paramType; + if (!paramClass.isInstance(param)) { + if (param instanceof List) { + List list = (List) param; + if (list.size() == 1) { + Object first = list.get(0); + if (paramClass.isInstance(first)) { + param = list.get(0); + } + } + } + } + } + } } params[i] = param; } @@ -854,8 +1011,33 @@ protected T deserialze(DefaultJSONParser parser, // } if (beanInfo.creatorConstructor != null) { + boolean hasNull = false; + if (beanInfo.kotlin) { + for (int i = 0; i < params.length; i++) { + if (params[i] == null && beanInfo.fields != null && i < beanInfo.fields.length) { + FieldInfo fieldInfo = beanInfo.fields[i]; + if (fieldInfo.fieldClass == String.class) { + hasNull = true; + } + break; + } + } + } + try { - object = beanInfo.creatorConstructor.newInstance(params); + if (hasNull && beanInfo.kotlinDefaultConstructor != null) { + object = beanInfo.kotlinDefaultConstructor.newInstance(new Object[0]); + + for (int i = 0; i < params.length; i++) { + final Object param = params[i]; + if (param != null && beanInfo.fields != null && i < beanInfo.fields.length) { + FieldInfo fieldInfo = beanInfo.fields[i]; + fieldInfo.set(object, param); + } + } + } else { + object = beanInfo.creatorConstructor.newInstance(params); + } } catch (Exception e) { throw new JSONException("create instance error, " + paramNames + ", " + beanInfo.creatorConstructor.toGenericString(), e); @@ -877,7 +1059,9 @@ protected T deserialze(DefaultJSONParser parser, // } } - childContext.object = object; + if (childContext != null) { + childContext.object = object; + } } Method buildMethod = beanInfo.buildMethod; @@ -913,9 +1097,20 @@ protected Enum scanEnum(JSONLexerBase lexer, char[] name_chars, ObjectDeserializ return null; } - long enumNameHashCode = lexer.scanFieldSymbol(name_chars); + long enumNameHashCode = lexer.scanEnumSymbol(name_chars); if (lexer.matchStat > 0) { - return enumDeserializer.getEnumByHashCode(enumNameHashCode); + Enum e = enumDeserializer.getEnumByHashCode(enumNameHashCode); + if (e == null) { + if (enumNameHashCode == fnv1a_64_magic_hashcode) { + return null; + } + + if (lexer.isEnabled(Feature.ErrorOnEnumNotMatch)) { + throw new JSONException("not match enum value, " + enumDeserializer.enumClass); + } + } + + return e; } else { return null; } @@ -931,9 +1126,12 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T JSONLexer lexer = parser.lexer; // xxx final int disableFieldSmartMatchMask = Feature.DisableFieldSmartMatch.mask; + final int initStringFieldAsEmpty = Feature.InitStringFieldAsEmpty.mask; FieldDeserializer fieldDeserializer; if (lexer.isEnabled(disableFieldSmartMatchMask) || (this.beanInfo.parserFeatures & disableFieldSmartMatchMask) != 0) { fieldDeserializer = getFieldDeserializer(key); + } else if (lexer.isEnabled(initStringFieldAsEmpty) || (this.beanInfo.parserFeatures & initStringFieldAsEmpty) != 0) { + fieldDeserializer = smartMatch(key); } else { fieldDeserializer = smartMatch(key, setFlags); } @@ -955,6 +1153,13 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T if ((fieldModifiers & Modifier.FINAL) != 0 || (fieldModifiers & Modifier.STATIC) != 0) { continue; } + JSONField jsonField = TypeUtils.getAnnotation(field, JSONField.class); + if (jsonField != null) { + String alteredFieldName = jsonField.name(); + if (!"".equals(alteredFieldName)) { + fieldName = alteredFieldName; + } + } extraFieldDeserializers.put(fieldName, field); } } @@ -980,7 +1185,10 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key); } - for (FieldDeserializer fieldDeser : this.sortedFieldDeserializers) { + int fieldIndex = -1; + for (int i = 0; i < this.sortedFieldDeserializers.length; i++) { + FieldDeserializer fieldDeser = this.sortedFieldDeserializers[i]; + FieldInfo fieldInfo = fieldDeser.fieldInfo; if (fieldInfo.unwrapped // && fieldDeser instanceof DefaultFieldDeserializer) { @@ -1000,7 +1208,7 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T } lexer.nextTokenWithColon(defaultFieldDeserializer.getFastMatchToken()); unwrappedFieldDeser.parseField(parser, fieldObject, objectType, fieldValues); - return true; + fieldIndex = i; } catch (Exception e) { throw new JSONException("parse unwrapped field error.", e); } @@ -1022,7 +1230,7 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T } catch (Exception e) { throw new JSONException("parse unwrapped field error.", e); } - return true; + fieldIndex = i; } } else if (fieldInfo.method.getParameterTypes().length == 2) { lexer.nextTokenWithColon(); @@ -1032,10 +1240,19 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T } catch (Exception e) { throw new JSONException("parse unwrapped field error.", e); } - return true; + fieldIndex = i; } } } + + if (fieldIndex != -1) { + if (setFlags != null) { + int flagIndex = fieldIndex / 32; + int bitIndex = fieldIndex % 32; + setFlags[flagIndex] |= (1 << bitIndex); + } + return true; + } parser.parseExtra(object, key); @@ -1060,6 +1277,12 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T fieldDeserializer.parseField(parser, object, objectType, fieldValues); + if (setFlags != null) { + int flagIndex = fieldIndex / 32; + int bitIndex = fieldIndex % 32; + setFlags[flagIndex] |= (1 << bitIndex); + } + return true; } @@ -1075,21 +1298,26 @@ public FieldDeserializer smartMatch(String key, int[] setFlags) { FieldDeserializer fieldDeserializer = getFieldDeserializer(key, setFlags); if (fieldDeserializer == null) { - long smartKeyHash = TypeUtils.fnv1a_64_lower(key); if (this.smartMatchHashArray == null) { long[] hashArray = new long[sortedFieldDeserializers.length]; for (int i = 0; i < sortedFieldDeserializers.length; i++) { - hashArray[i] = TypeUtils.fnv1a_64_lower(sortedFieldDeserializers[i].fieldInfo.name); + hashArray[i] = sortedFieldDeserializers[i].fieldInfo.nameHashCode; } Arrays.sort(hashArray); this.smartMatchHashArray = hashArray; } // smartMatchHashArrayMapping + long smartKeyHash = TypeUtils.fnv1a_64_lower(key); int pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash); + if (pos < 0) { + long smartKeyHash1 = TypeUtils.fnv1a_64_extract(key); + pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash1); + } + boolean is = false; if (pos < 0 && (is = key.startsWith("is"))) { - smartKeyHash = TypeUtils.fnv1a_64_lower(key.substring(2)); + smartKeyHash = TypeUtils.fnv1a_64_extract(key.substring(2)); pos = Arrays.binarySearch(smartMatchHashArray, smartKeyHash); } @@ -1098,8 +1326,7 @@ public FieldDeserializer smartMatch(String key, int[] setFlags) { short[] mapping = new short[smartMatchHashArray.length]; Arrays.fill(mapping, (short) -1); for (int i = 0; i < sortedFieldDeserializers.length; i++) { - int p = Arrays.binarySearch(smartMatchHashArray - , TypeUtils.fnv1a_64_lower(sortedFieldDeserializers[i].fieldInfo.name)); + int p = Arrays.binarySearch(smartMatchHashArray, sortedFieldDeserializers[i].fieldInfo.nameHashCode); if (p >= 0) { mapping[p] = (short) i; } @@ -1135,6 +1362,13 @@ public FieldDeserializer smartMatch(String key, int[] setFlags) { public int getFastMatchToken() { return JSONToken.LBRACE; } + + private Object createFactoryInstance(ParserConfig config, Object value) // + throws IllegalArgumentException, + IllegalAccessException, + InvocationTargetException { + return beanInfo.factoryMethod.invoke(null, value); + } public Object createInstance(Map map, ParserConfig config) // throws IllegalArgumentException, @@ -1155,8 +1389,103 @@ public Object createInstance(Map map, ParserConfig config) // } final FieldInfo fieldInfo = fieldDeser.fieldInfo; + Field field = fieldDeser.fieldInfo.field; Type paramType = fieldInfo.fieldType; - value = TypeUtils.cast(value, paramType, config); + + Class fieldClass = fieldInfo.fieldClass; + JSONField fieldAnnation = fieldInfo.getAnnotation(); + + if (fieldInfo.declaringClass != null + && ((!fieldClass.isInstance(value)) + || (fieldAnnation != null && fieldAnnation.deserializeUsing() != Void.class)) + ) { + String input; + if (value instanceof String + && JSONValidator.from(((String) value)) + .validate()) + { + input = (String) value; + } else { + input = JSON.toJSONString(value); + } + + DefaultJSONParser parser = new DefaultJSONParser(input); + fieldDeser.parseField(parser, object, paramType, null); + continue; + } + + if (field != null && fieldInfo.method == null) { + Class fieldType = field.getType(); + if (fieldType == boolean.class) { + if (value == Boolean.FALSE) { + field.setBoolean(object, false); + continue; + } + + if (value == Boolean.TRUE) { + field.setBoolean(object, true); + continue; + } + } else if (fieldType == int.class) { + if (value instanceof Number) { + field.setInt(object, ((Number) value).intValue()); + continue; + } + } else if (fieldType == long.class) { + if (value instanceof Number) { + field.setLong(object, ((Number) value).longValue()); + continue; + } + } else if (fieldType == float.class) { + if (value instanceof Number) { + field.setFloat(object, ((Number) value).floatValue()); + continue; + } else if (value instanceof String) { + String strVal = (String) value; + float floatValue; + if (strVal.length() <= 10) { + floatValue = TypeUtils.parseFloat(strVal); + } else { + floatValue = Float.parseFloat(strVal); + } + + field.setFloat(object, floatValue); + continue; + } + } else if (fieldType == double.class) { + if (value instanceof Number) { + field.setDouble(object, ((Number) value).doubleValue()); + continue; + } else if (value instanceof String) { + String strVal = (String) value; + double doubleValue; + if (strVal.length() <= 10) { + doubleValue = TypeUtils.parseDouble(strVal); + } else { + doubleValue = Double.parseDouble(strVal); + } + + field.setDouble(object, doubleValue); + continue; + } + } else if (value != null && paramType == value.getClass()) { + field.set(object, value); + continue; + } + } + + String format = fieldInfo.format; + if (format != null && paramType == Date.class) { + value = TypeUtils.castToDate(value, format); + } else if (format != null && (paramType instanceof Class) && (((Class) paramType).getName().equals("java.time.LocalDateTime"))) { + value = Jdk8DateCodec.castToLocalDateTime(value, format); + } else { + if (paramType instanceof ParameterizedType) { + value = TypeUtils.cast(value, (ParameterizedType) paramType, config); + } else { + value = TypeUtils.cast(value, paramType, config); + } + } fieldDeser.setValue(object, value); } @@ -1179,9 +1508,11 @@ public Object createInstance(Map map, ParserConfig config) // FieldInfo[] fieldInfoList = beanInfo.fields; int size = fieldInfoList.length; Object[] params = new Object[size]; + Map missFields = null; for (int i = 0; i < size; ++i) { FieldInfo fieldInfo = fieldInfoList[i]; Object param = map.get(fieldInfo.name); + if (param == null) { Class fieldClass = fieldInfo.fieldClass; if (fieldClass == int.class) { @@ -1201,16 +1532,69 @@ public Object createInstance(Map map, ParserConfig config) // } else if (fieldClass == boolean.class) { param = false; } + if (missFields == null) { + missFields = new HashMap(); + } + missFields.put(fieldInfo.name, i); } params[i] = param; } - + + if (missFields != null) { + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + FieldDeserializer fieldDeser = smartMatch(key); + if (fieldDeser != null) { + Integer index = missFields.get(fieldDeser.fieldInfo.name); + if (index != null) { + params[index] = value; + } + } + } + } + if (beanInfo.creatorConstructor != null) { - try { - object = beanInfo.creatorConstructor.newInstance(params); - } catch (Exception e) { - throw new JSONException("create instance error, " - + beanInfo.creatorConstructor.toGenericString(), e); + boolean hasNull = false; + if (beanInfo.kotlin) { + for (int i = 0; i < params.length; i++) { + Object param = params[i]; + if (param == null) { + if (beanInfo.fields != null && i < beanInfo.fields.length) { + FieldInfo fieldInfo = beanInfo.fields[i]; + if (fieldInfo.fieldClass == String.class) { + hasNull = true; + } + } + } else if (param.getClass() != beanInfo.fields[i].fieldClass){ + params[i] = TypeUtils.cast(param, beanInfo.fields[i].fieldClass, config); + } + } + } + + if (hasNull && beanInfo.kotlinDefaultConstructor != null) { + try { + object = beanInfo.kotlinDefaultConstructor.newInstance(); + + for (int i = 0; i < params.length; i++) { + final Object param = params[i]; + if (param != null && beanInfo.fields != null && i < beanInfo.fields.length) { + FieldInfo fieldInfo = beanInfo.fields[i]; + fieldInfo.set(object, param); + } + } + } catch (Exception e) { + throw new JSONException("create instance error, " + + beanInfo.creatorConstructor.toGenericString(), e); + } + } else { + try { + object = beanInfo.creatorConstructor.newInstance(params); + } catch (Exception e) { + throw new JSONException("create instance error, " + + beanInfo.creatorConstructor.toGenericString(), e); + } } } else if (beanInfo.factoryMethod != null) { try { @@ -1242,7 +1626,7 @@ protected Object parseRest(DefaultJSONParser parser return value; } - protected JavaBeanDeserializer getSeeAlso(ParserConfig config, JavaBeanInfo beanInfo, String typeName) { + protected static JavaBeanDeserializer getSeeAlso(ParserConfig config, JavaBeanInfo beanInfo, String typeName) { if (beanInfo.jsonType == null) { return null; } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java index fbca60aea1..e511eb3c4d 100644 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java @@ -1,5 +1,6 @@ package com.alibaba.fastjson.parser.deserializer; +import java.io.Closeable; import java.io.Serializable; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; @@ -10,6 +11,7 @@ import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.TypeUtils; public class JavaObjectDeserializer implements ObjectDeserializer { @@ -26,19 +28,18 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { List list = new ArrayList(); parser.parseArray(componentType, list); - Class componentClass; - if (componentType instanceof Class) { - componentClass = (Class) componentType; - Object[] array = (Object[]) Array.newInstance(componentClass, list.size()); - list.toArray(array); - return (T) array; - } else { - return (T) list.toArray(); - } - + Class componentClass = TypeUtils.getRawClass(componentType); + Object[] array = (Object[]) Array.newInstance(componentClass, list.size()); + list.toArray(array); + return (T) array; } - if (type instanceof Class && type != Object.class && type != Serializable.class) { + if (type instanceof Class + && type != Object.class + && type != Serializable.class + && type != Cloneable.class + && type != Closeable.class + && type != Comparable.class) { return (T) parser.parseObject(type); } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java index 2c2f698575..b6644343a0 100644 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java @@ -12,44 +12,53 @@ import java.time.Period; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.chrono.ChronoZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAccessor; +import java.util.Date; import java.util.Locale; +import java.util.TimeZone; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.serializer.*; +import com.alibaba.fastjson.util.TypeUtils; public class Jdk8DateCodec extends ContextObjectDeserializer implements ObjectSerializer, ContextObjectSerializer, ObjectDeserializer { - public static final Jdk8DateCodec instance = new Jdk8DateCodec(); - - private final static String defaultPatttern = "yyyy-MM-dd HH:mm:ss"; - private final static DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern(defaultPatttern); - private final static DateTimeFormatter formatter_dt19_tw = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); - private final static DateTimeFormatter formatter_dt19_cn = DateTimeFormatter.ofPattern("yyyy年M月d日 HH:mm:ss"); - private final static DateTimeFormatter formatter_dt19_cn_1 = DateTimeFormatter.ofPattern("yyyy年M月d日 H时m分s秒"); - private final static DateTimeFormatter formatter_dt19_kr = DateTimeFormatter.ofPattern("yyyy년M월d일 HH:mm:ss"); - private final static DateTimeFormatter formatter_dt19_us = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss"); - private final static DateTimeFormatter formatter_dt19_eur = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); - private final static DateTimeFormatter formatter_dt19_de = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); - private final static DateTimeFormatter formatter_dt19_in = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss"); - - private final static DateTimeFormatter formatter_d8 = DateTimeFormatter.ofPattern("yyyyMMdd"); - private final static DateTimeFormatter formatter_d10_tw = DateTimeFormatter.ofPattern("yyyy/MM/dd"); - private final static DateTimeFormatter formatter_d10_cn = DateTimeFormatter.ofPattern("yyyy年M月d日"); - private final static DateTimeFormatter formatter_d10_kr = DateTimeFormatter.ofPattern("yyyy년M월d일"); - private final static DateTimeFormatter formatter_d10_us = DateTimeFormatter.ofPattern("MM/dd/yyyy"); - private final static DateTimeFormatter formatter_d10_eur = DateTimeFormatter.ofPattern("dd/MM/yyyy"); - private final static DateTimeFormatter formatter_d10_de = DateTimeFormatter.ofPattern("dd.MM.yyyy"); - private final static DateTimeFormatter formatter_d10_in = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + public static final Jdk8DateCodec instance = new Jdk8DateCodec(); + + private final static String defaultPatttern = "yyyy-MM-dd HH:mm:ss"; + private final static DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern(defaultPatttern); + private final static DateTimeFormatter defaultFormatter_23 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + private final static DateTimeFormatter formatter_dt19_tw = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_cn = DateTimeFormatter.ofPattern("yyyy年M月d日 HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_cn_1 = DateTimeFormatter.ofPattern("yyyy年M月d日 H时m分s秒"); + private final static DateTimeFormatter formatter_dt19_kr = DateTimeFormatter.ofPattern("yyyy년M월d일 HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_us = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_eur = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_de = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_in = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss"); + + private final static DateTimeFormatter formatter_d8 = DateTimeFormatter.ofPattern("yyyyMMdd"); + private final static DateTimeFormatter formatter_d10_tw = DateTimeFormatter.ofPattern("yyyy/MM/dd"); + private final static DateTimeFormatter formatter_d10_cn = DateTimeFormatter.ofPattern("yyyy年M月d日"); + private final static DateTimeFormatter formatter_d10_kr = DateTimeFormatter.ofPattern("yyyy년M월d일"); + private final static DateTimeFormatter formatter_d10_us = DateTimeFormatter.ofPattern("MM/dd/yyyy"); + private final static DateTimeFormatter formatter_d10_eur = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + private final static DateTimeFormatter formatter_d10_de = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + private final static DateTimeFormatter formatter_d10_in = DateTimeFormatter.ofPattern("dd-MM-yyyy"); private final static DateTimeFormatter ISO_FIXED_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()); private final static String formatter_iso8601_pattern = "yyyy-MM-dd'T'HH:mm:ss"; + private final static String formatter_iso8601_pattern_23 = "yyyy-MM-dd'T'HH:mm:ss.SSS"; + private final static String formatter_iso8601_pattern_29 = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS"; private final static DateTimeFormatter formatter_iso8601 = DateTimeFormatter.ofPattern(formatter_iso8601_pattern); @SuppressWarnings("unchecked") @@ -98,20 +107,52 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName, S return (T) localDate; } else if (type == LocalTime.class) { - LocalTime localDate; + LocalTime localTime; if (text.length() == 23) { LocalDateTime localDateTime = LocalDateTime.parse(text); - localDate = LocalTime.of(localDateTime.getHour(), localDateTime.getMinute(), + localTime = LocalTime.of(localDateTime.getHour(), localDateTime.getMinute(), localDateTime.getSecond(), localDateTime.getNano()); } else { - localDate = LocalTime.parse(text); + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + localTime = LocalDateTime + .ofInstant( + Instant.ofEpochMilli(epochMillis), + JSON.defaultTimeZone.toZoneId()) + .toLocalTime(); + } else { + localTime = LocalTime.parse(text); + } } - return (T) localDate; + return (T) localTime; } else if (type == ZonedDateTime.class) { if (formatter == defaultFormatter) { formatter = ISO_FIXED_FORMAT; } + if (formatter == null) { + if (text.length() <= 19) { + JSONScanner s = new JSONScanner(text); + TimeZone timeZone = parser.lexer.getTimeZone(); + s.setTimeZone(timeZone); + boolean match = s.scanISO8601DateIfMatch(false); + if (match) { + Date date = s.getCalendar().getTime(); + return (T) ZonedDateTime.ofInstant(date.toInstant(), timeZone.toZoneId()); + } + } + + } + ZonedDateTime zonedDateTime = parseZonedDateTime(text, formatter); return (T) zonedDateTime; @@ -133,9 +174,21 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName, S return (T) period; } else if (type == Duration.class) { Duration duration = Duration.parse(text); - return (T) duration; } else if (type == Instant.class) { + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + return (T) Instant.ofEpochMilli(epochMillis); + } + Instant instant = Instant.parse(text); return (T) instant; @@ -144,11 +197,64 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName, S long millis = lexer.longValue(); lexer.nextToken(); + if ("unixtime".equals(format)) { + millis *= 1000; + } else if ("yyyyMMddHHmmss".equals(format)) { + int yyyy = (int) (millis / 10000000000L); + int MM = (int) ((millis / 100000000L) % 100); + int dd = (int) ((millis / 1000000L) % 100); + int HH = (int) ((millis / 10000L) % 100); + int mm = (int) ((millis / 100L) % 100); + int ss = (int) (millis % 100); + + if (type == LocalDateTime.class) { + return (T) LocalDateTime.of(yyyy, MM, dd, HH, mm, ss); + } + } + if (type == LocalDateTime.class) { - return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault()); + return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId()); + } + + if (type == LocalDate.class) { + return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId()).toLocalDate(); + } + if (type == LocalTime.class) { + return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId()).toLocalTime(); + } + + if (type == ZonedDateTime.class) { + return (T) ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), JSON.defaultTimeZone.toZoneId()); + } + + if (type == Instant.class) { + return (T) Instant.ofEpochMilli(millis); } throw new UnsupportedOperationException(); + } else if (lexer.token() == JSONToken.LBRACE) { + JSONObject object = parser.parseObject(); + + if (type == Instant.class) { + Object epochSecond = object.get("epochSecond"); + Object nano = object.get("nano"); + if (epochSecond instanceof Number && nano instanceof Number) { + return (T) Instant.ofEpochSecond( + TypeUtils.longExtractValue((Number) epochSecond) + , TypeUtils.longExtractValue((Number) nano)); + } + + if (epochSecond instanceof Number) { + return (T) Instant.ofEpochSecond( + TypeUtils.longExtractValue((Number) epochSecond)); + } + } else if (type == Duration.class) { + Long seconds = object.getLong("seconds"); + if (seconds != null) { + long nanos = object.getLongValue("nano"); + return (T) Duration.ofSeconds(seconds, nanos); + } + } } else { throw new UnsupportedOperationException(); } @@ -170,8 +276,6 @@ protected LocalDateTime parseDateTime(String text, DateTimeFormatter formatter) } else if (c10 == ' ') { formatter = defaultFormatter; } - } else if (c4 == '-' && c7 == '-') { - formatter = defaultFormatter; } else if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd formatter = formatter_dt19_tw; } else { @@ -204,6 +308,23 @@ protected LocalDateTime parseDateTime(String text, DateTimeFormatter formatter) } } } + } else if (text.length() == 23) { + char c4 = text.charAt(4); + char c7 = text.charAt(7); + char c10 = text.charAt(10); + char c13 = text.charAt(13); + char c16 = text.charAt(16); + char c19 = text.charAt(19); + + if (c13 == ':' + && c16 == ':' + && c4 == '-' + && c7 == '-' + && c10 == ' ' + && c19 == '.' + ) { + formatter = defaultFormatter_23; + } } if (text.length() >= 17) { @@ -220,6 +341,27 @@ protected LocalDateTime parseDateTime(String text, DateTimeFormatter formatter) } } + if (formatter == null) { + JSONScanner dateScanner = new JSONScanner(text); + if (dateScanner.scanISO8601DateIfMatch(false)) { + Instant instant = dateScanner.getCalendar().toInstant(); + return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + } + + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), JSON.defaultTimeZone.toZoneId()); + } + } + return formatter == null ? // LocalDateTime.parse(text) // : LocalDateTime.parse(text, formatter); @@ -275,6 +417,23 @@ protected LocalDate parseLocalDate(String text, String format, DateTimeFormatter formatter = formatter_d10_kr; } } + + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + return LocalDateTime + .ofInstant( + Instant.ofEpochMilli(epochMillis), + JSON.defaultTimeZone.toZoneId()) + .toLocalDate(); + } } return formatter == null ? // @@ -297,8 +456,6 @@ protected ZonedDateTime parseZonedDateTime(String text, DateTimeFormatter format } else if (c10 == ' ') { formatter = defaultFormatter; } - } else if (c4 == '-' && c7 == '-') { - formatter = defaultFormatter; } else if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd formatter = formatter_dt19_tw; } else { @@ -345,6 +502,19 @@ protected ZonedDateTime parseZonedDateTime(String text, DateTimeFormatter format formatter = formatter_dt19_kr; } } + + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + return ZonedDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), JSON.defaultTimeZone.toZoneId()); + } } return formatter == null ? // @@ -371,20 +541,32 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty LocalDateTime dateTime = (LocalDateTime) object; String format = serializer.getDateFormatPattern(); - if (format == null && (features & mask) != 0 || serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) { - format = formatter_iso8601_pattern; + if (format == null) { + if ((features & mask) != 0 || serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) { + format = formatter_iso8601_pattern; + } else if (serializer.isEnabled(SerializerFeature.WriteDateUseDateFormat)) { + if (serializer.getFastJsonConfigDateFormatPattern() != null && + serializer.getFastJsonConfigDateFormatPattern().length() > 0){ + format = serializer.getFastJsonConfigDateFormatPattern(); + }else{ + format = JSON.DEFFAULT_DATE_FORMAT; + } + } else { + int nano = dateTime.getNano(); + if (nano == 0) { + format = formatter_iso8601_pattern; + } else if (nano % 1000000 == 0) { + format = formatter_iso8601_pattern_23; + } else { + format = formatter_iso8601_pattern_29; + } + } } - if (dateTime.getNano() == 0 || format != null) { - - if (format == null) { - format = JSON.DEFFAULT_DATE_FORMAT; - } + if (format != null) { write(out, dateTime, format); } else { - out.writeString(object.toString()); -// format = JSON.DEFFAULT_LOCAL_DATE_TIME_FORMAT; -// write(out, dateTime, format); + out.writeLong(dateTime.atZone(JSON.defaultTimeZone.toZoneId()).toInstant().toEpochMilli()); } } else { out.writeString(object.toString()); @@ -400,6 +582,35 @@ public void write(JSONSerializer serializer, Object object, BeanContext context) private void write(SerializeWriter out, TemporalAccessor object, String format) { DateTimeFormatter formatter; + if ("unixtime".equals(format)) { + Instant instant = null; + if (object instanceof ChronoZonedDateTime) { + long seconds = ((ChronoZonedDateTime) object).toEpochSecond(); + out.writeInt((int) seconds); + return; + } + + if (object instanceof LocalDateTime) { + long seconds = ((LocalDateTime) object).atZone(JSON.defaultTimeZone.toZoneId()).toEpochSecond(); + out.writeInt((int) seconds); + return; + } + } + + if ("millis".equals(format)) { + Instant instant = null; + if (object instanceof ChronoZonedDateTime) { + instant = ((ChronoZonedDateTime) object).toInstant(); + } else if (object instanceof LocalDateTime) { + instant = ((LocalDateTime) object).atZone(JSON.defaultTimeZone.toZoneId()).toInstant(); + } + if (instant != null) { + long millis = instant.toEpochMilli(); + out.writeLong(millis); + return; + } + } + if (format == formatter_iso8601_pattern) { formatter = formatter_iso8601; } else { @@ -409,4 +620,17 @@ private void write(SerializeWriter out, TemporalAccessor object, String format) String text = formatter.format((TemporalAccessor) object); out.writeString(text); } + + public static Object castToLocalDateTime(Object value, String format) { + if (value == null) { + return null; + } + + if (format == null) { + format = "yyyy-MM-dd HH:mm:ss"; + } + + DateTimeFormatter df = DateTimeFormatter.ofPattern(format); + return LocalDateTime.parse(value.toString(), df); + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java index 7d61405bee..e7a55a505e 100644 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java @@ -1,6 +1,5 @@ package com.alibaba.fastjson.parser.deserializer; -import java.lang.reflect.Constructor; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; @@ -13,15 +12,13 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.*; import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask; -import com.alibaba.fastjson.serializer.CollectionCodec; -import com.alibaba.fastjson.util.TypeUtils; -public class MapDeserializer implements ObjectDeserializer { +public class MapDeserializer extends ContextObjectDeserializer implements ObjectDeserializer { public static MapDeserializer instance = new MapDeserializer(); - - + @SuppressWarnings("unchecked") - public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName, String format, int features) + { if (type == JSONObject.class && parser.getFieldTypeResolver() == null) { return (T) parser.parseObject(); } @@ -32,20 +29,33 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { return null; } - Map map = createMap(type); + boolean unmodifiableMap = type instanceof Class + && "java.util.Collections$UnmodifiableMap".equals(((Class) type).getName()); + + Map map = (lexer.getFeatures() & Feature.OrderedField.mask) != 0 + ? createMap(type, lexer.getFeatures()) + : createMap(type); ParseContext context = parser.getContext(); try { parser.setContext(context, map, fieldName); - return (T) deserialze(parser, type, fieldName, map); + T t = (T) deserialze(parser, type, fieldName, map, features); + if (unmodifiableMap) { + t = (T) Collections.unmodifiableMap((Map) t); + } + return t; } finally { parser.setContext(context); } } - @SuppressWarnings({ "rawtypes", "unchecked" }) protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldName, Map map) { + return deserialze(parser, type, fieldName, map, 0); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldName, Map map, int features) { if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; Type keyType = parameterizedType.getActualTypeArguments()[0]; @@ -56,7 +66,7 @@ protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldNam valueType = parameterizedType.getActualTypeArguments()[1]; } if (String.class == keyType) { - return parseMap(parser, (Map) map, valueType, fieldName); + return parseMap(parser, (Map) map, valueType, fieldName, features); } else { return parseMap(parser, map, keyType, valueType, fieldName); } @@ -64,13 +74,24 @@ protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldNam return parser.parseObject(map, fieldName); } } + + public static Map parseMap(DefaultJSONParser parser, Map map, Type valueType, Object fieldName) { + return parseMap(parser, map, valueType, fieldName, 0); + } @SuppressWarnings("rawtypes") - public static Map parseMap(DefaultJSONParser parser, Map map, Type valueType, Object fieldName) { + public static Map parseMap(DefaultJSONParser parser, Map map, Type valueType, Object fieldName, int features) { JSONLexer lexer = parser.lexer; int token = lexer.token(); if (token != JSONToken.LBRACE) { + if (token == JSONToken.LITERAL_STRING) { + String stringVal = lexer.stringVal(); + if (stringVal.length() == 0 || stringVal.equals("null")) { + return null; + } + } + String msg = "syntax error, expect {, actual " + lexer.tokenName(); if (fieldName instanceof String) { msg += ", fieldName "; @@ -150,11 +171,29 @@ public static Map parseMap(DefaultJSONParser parser, Map map, Ty lexer.resetStringPosition(); - if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) { + if (key == JSON.DEFAULT_TYPE_KEY + && !lexer.isEnabled(Feature.DisableSpecialKeyDetect) + && !Feature.isEnabled(features, Feature.DisableSpecialKeyDetect) + ) { String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"'); final ParserConfig config = parser.getConfig(); - Class clazz = config.checkAutoType(typeName, null, lexer.getFeatures()); + Class clazz; + + if (typeName.equals("java.util.HashMap")) { + clazz = java.util.HashMap.class; + } else if (typeName.equals("java.util.LinkedHashMap")) { + clazz = java.util.LinkedHashMap.class; + } else if (config.isSafeMode()) { + clazz = java.util.HashMap.class; + } else { + try { + clazz = config.checkAutoType(typeName, null, lexer.getFeatures()); + } catch (JSONException ex) { + // skip + clazz = java.util.HashMap.class; + } + } if (Map.class.isAssignableFrom(clazz) ) { lexer.nextToken(JSONToken.COMMA); @@ -286,7 +325,18 @@ public static Object parseMap(DefaultJSONParser parser, Map map, lexer.nextToken(keyDeserializer.getFastMatchToken()); } - Object key = keyDeserializer.deserialze(parser, keyType, null); + Object key; + if (lexer.token() == JSONToken.LITERAL_STRING + && keyDeserializer instanceof JavaBeanDeserializer + ) { + String keyStrValue = lexer.stringVal(); + lexer.nextToken(); + DefaultJSONParser keyParser = new DefaultJSONParser(keyStrValue, parser.getConfig(), parser.getLexer().getFeatures()); + keyParser.setDateFormat(parser.getDateFomartPattern()); + key = keyDeserializer.deserialze(keyParser, keyType, null); + } else { + key = keyDeserializer.deserialze(parser, keyType, null); + } if (lexer.token() != JSONToken.COLON) { throw new JSONException("syntax error, expect :, actual " + lexer.token()); @@ -310,8 +360,12 @@ public static Object parseMap(DefaultJSONParser parser, Map map, return map; } + public Map createMap(Type type) { + return createMap(type, JSON.DEFAULT_GENERATE_FEATURE); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) - protected Map createMap(Type type) { + public Map createMap(Type type, int featrues) { if (type == Properties.class) { return new Properties(); } @@ -332,10 +386,16 @@ protected Map createMap(Type type) { return new ConcurrentHashMap(); } - if (type == Map.class || type == HashMap.class) { + if (type == Map.class) { + return (featrues & Feature.OrderedField.mask) != 0 + ? new LinkedHashMap() + : new HashMap(); + } + + if (type == HashMap.class) { return new HashMap(); } - + if (type == LinkedHashMap.class) { return new LinkedHashMap(); } @@ -349,13 +409,17 @@ protected Map createMap(Type type) { return new EnumMap((Class) actualArgs[0]); } - return createMap(rawType); + return createMap(rawType, featrues); } Class clazz = (Class) type; if (clazz.isInterface()) { throw new JSONException("unsupport type " + type); } + + if ("java.util.Collections$UnmodifiableMap".equals(clazz.getName())) { + return new HashMap(); + } try { return (Map) clazz.newInstance(); diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java old mode 100755 new mode 100644 index d23c063374..ac516cf951 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java @@ -4,8 +4,8 @@ import java.math.BigDecimal; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.util.TypeUtils; @@ -55,21 +55,28 @@ public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) return (T) Double.valueOf(Double.parseDouble(val)); } - BigDecimal val = lexer.decimalValue(); - lexer.nextToken(JSONToken.COMMA); - if (clazz == short.class || clazz == Short.class) { - if (val.compareTo(BigDecimal.valueOf(Short.MAX_VALUE)) > 0 || val.compareTo(BigDecimal.valueOf(Short.MIN_VALUE)) < 0) { - throw new JSONException("short overflow : " + val); - } - return (T) Short.valueOf(val.shortValue()); + BigDecimal val = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + short shortValue = TypeUtils.shortValue(val); + return (T) Short.valueOf(shortValue); } if (clazz == byte.class || clazz == Byte.class) { - return (T) Byte.valueOf(val.byteValue()); + BigDecimal val = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + byte byteValue = TypeUtils.byteValue(val); + return (T) Byte.valueOf(byteValue); } - return (T) val; + BigDecimal val = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + + if (lexer.isEnabled(Feature.UseBigDecimal)) { + return (T) val; + } else { + return (T) Double.valueOf(val.doubleValue()); + } } if (lexer.token() == JSONToken.IDENTIFIER && "NaN".equals(lexer.stringVal())) { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ObjectDeserializer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java old mode 100755 new mode 100644 index 254a36858e..be01a29548 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java @@ -1,14 +1,17 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Type; +import java.math.BigDecimal; import java.text.DateFormat; import java.text.ParseException; import java.util.Date; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.TypeUtils; public class SqlDateDeserializer extends AbstractDateDeserializer implements ObjectDeserializer { @@ -37,6 +40,8 @@ protected T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Obj if (val instanceof java.util.Date) { val = new java.sql.Date(((Date) val).getTime()); + } else if (val instanceof BigDecimal) { + val = (T) new java.sql.Date(TypeUtils.longValue((BigDecimal) val)); } else if (val instanceof Number) { val = (T) new java.sql.Date(((Number) val).longValue()); } else if (val instanceof String) { @@ -86,6 +91,10 @@ protected T castTimestamp(DefaultJSONParser parser, Type clazz, Object field return (T) new java.sql.Timestamp(((Date) val).getTime()); } + if (val instanceof BigDecimal) { + return (T) new java.sql.Timestamp(TypeUtils.longValue((BigDecimal) val)); + } + if (val instanceof Number) { return (T) new java.sql.Timestamp(((Number) val).longValue()); } @@ -99,10 +108,22 @@ protected T castTimestamp(DefaultJSONParser parser, Type clazz, Object field long longVal; JSONScanner dateLexer = new JSONScanner(strVal); try { - if (dateLexer.scanISO8601DateIfMatch()) { + if (strVal.length() > 19 + && strVal.charAt(4) == '-' + && strVal.charAt(7) == '-' + && strVal.charAt(10) == ' ' + && strVal.charAt(13) == ':' + && strVal.charAt(16) == ':' + && strVal.charAt(19) == '.') { + String dateFomartPattern = parser.getDateFomartPattern(); + if (dateFomartPattern.length() != strVal.length() && dateFomartPattern == JSON.DEFFAULT_DATE_FORMAT) { + return (T) java.sql.Timestamp.valueOf(strVal); + } + } + + if (dateLexer.scanISO8601DateIfMatch(false)) { longVal = dateLexer.getCalendar().getTimeInMillis(); } else { - DateFormat dateFormat = parser.getDateFormat(); try { java.util.Date date = (java.util.Date) dateFormat.parse(strVal); diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/StackTraceElementDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/StackTraceElementDeserializer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java old mode 100755 new mode 100644 index 6b07590929..301ab86b79 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java @@ -1,7 +1,6 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; @@ -13,7 +12,7 @@ import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.serializer.JavaBeanSerializer; +import com.alibaba.fastjson.util.FieldInfo; import com.alibaba.fastjson.util.TypeUtils; public class ThrowableDeserializer extends JavaBeanDeserializer { @@ -142,13 +141,19 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { } } - for (Map.Entry entry : otherValues.entrySet()) { - String key = entry.getKey(); - Object value = entry.getValue(); - - FieldDeserializer fieldDeserializer = exBeanDeser.getFieldDeserializer(key); - if (fieldDeserializer != null) { - fieldDeserializer.setValue(ex, value); + if (exBeanDeser != null) { + for (Map.Entry entry : otherValues.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + FieldDeserializer fieldDeserializer = exBeanDeser.getFieldDeserializer(key); + if (fieldDeserializer != null) { + FieldInfo fieldInfo = fieldDeserializer.fieldInfo; + if (!fieldInfo.fieldClass.isInstance(value)) { + value = TypeUtils.cast(value, fieldInfo.fieldType, parser.getConfig()); + } + fieldDeserializer.setValue(ex, value); + } } } } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeDeserializer.java old mode 100755 new mode 100644 index e938969ee6..b8030a48be --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeDeserializer.java @@ -1,12 +1,14 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Type; +import java.math.BigDecimal; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.TypeUtils; public class TimeDeserializer implements ObjectDeserializer { @@ -47,6 +49,8 @@ public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) if (val instanceof java.sql.Time) { return (T) val; + } else if (val instanceof BigDecimal) { + return (T) new java.sql.Time(TypeUtils.longValue((BigDecimal) val)); } else if (val instanceof Number) { return (T) new java.sql.Time(((Number) val).longValue()); } else if (val instanceof String) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java b/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java old mode 100755 new mode 100644 index a9f7967ac8..e65bbece7d --- a/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java @@ -109,7 +109,7 @@ public JavaBeanSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) t throw new JSONException("unsupportd class " + clazz.getName()); } - JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class); + JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class); FieldInfo[] unsortedGetters = beanInfo.fields; @@ -136,9 +136,17 @@ public JavaBeanSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) t } String className = "ASMSerializer_" + seed.incrementAndGet() + "_" + clazz.getSimpleName(); - String packageName = ASMSerializerFactory.class.getPackage().getName(); - String classNameType = packageName.replace('.', '/') + "/" + className; - String classNameFull = packageName + "." + className; + String classNameType; + String classNameFull; + Package pkg = ASMSerializerFactory.class.getPackage(); + if (pkg != null) { + String packageName = pkg.getName(); + classNameType = packageName.replace('.', '/') + "/" + className; + classNameFull = packageName + "." + className; + } else { + classNameType = className; + classNameFull = className; + } ClassWriter cw = new ClassWriter(); cw.visit(V1_5 // @@ -408,6 +416,23 @@ public JavaBeanSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) t private void generateWriteAsArray(Class clazz, MethodVisitor mw, FieldInfo[] getters, Context context) throws Exception { + Label nonPropertyFilters_ = new Label(); + mw.visitVarInsn(ALOAD, Context.serializer); + mw.visitVarInsn(ALOAD, 0); + mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "hasPropertyFilters", "(" + SerializeFilterable_desc + ")Z"); + mw.visitJumpInsn(IFNE, nonPropertyFilters_); + mw.visitVarInsn(ALOAD, 0); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ALOAD, 3); + mw.visitVarInsn(ALOAD, 4); + mw.visitVarInsn(ILOAD, 5); + mw.visitMethodInsn(INVOKESPECIAL, JavaBeanSerializer, + "writeNoneASM", "(L" + JSONSerializer + + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); + mw.visitInsn(RETURN); + + mw.visitLabel(nonPropertyFilters_); mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(BIPUSH, '['); mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V"); @@ -773,6 +798,7 @@ private void generateWriteMethod(Class clazz, MethodVisitor mw, FieldInfo[] g for (FieldInfo getter : getters) { if (getter.method != null) { hasMethod = true; + break; } } @@ -1961,7 +1987,10 @@ private void _if_write_null(MethodVisitor mw, FieldInfo fieldInfo, Context conte int features = 0; if (annotation != null) { features = SerializerFeature.of(annotation.serialzeFeatures()); - ; + } + JSONType jsonType = context.beanInfo.jsonType; + if (jsonType != null) { + features |= SerializerFeature.of(jsonType.serialzeFeatures()); } int writeNullFeatures; diff --git a/src/main/java/com/alibaba/fastjson/serializer/AfterFilter.java b/src/main/java/com/alibaba/fastjson/serializer/AfterFilter.java index 0c032fcf6d..7e61e23b4b 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/AfterFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AfterFilter.java @@ -11,17 +11,23 @@ public abstract class AfterFilter implements SerializeFilter { private final static Character COMMA = Character.valueOf(','); final char writeAfter(JSONSerializer serializer, Object object, char seperator) { + JSONSerializer last = serializerLocal.get(); serializerLocal.set(serializer); seperatorLocal.set(seperator); writeAfter(object); - serializerLocal.set(null); + serializerLocal.set(last); return seperatorLocal.get(); } protected final void writeKeyValue(String key, Object value) { JSONSerializer serializer = serializerLocal.get(); char seperator = seperatorLocal.get(); + + boolean ref = serializer.containsReference(value); serializer.writeKeyValue(seperator, key, value); + if (!ref && serializer.references != null) { + serializer.references.remove(value); + } if (seperator != ',') { seperatorLocal.set(COMMA); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/AnnotationSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AnnotationSerializer.java index 66689cdc9e..b2e08d992e 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/AnnotationSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AnnotationSerializer.java @@ -1,8 +1,8 @@ package com.alibaba.fastjson.serializer; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; -import sun.reflect.annotation.AnnotationType; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -15,6 +15,11 @@ * Created by wenshao on 10/05/2017. */ public class AnnotationSerializer implements ObjectSerializer { + private static volatile Class sun_AnnotationType = null; + private static volatile boolean sun_AnnotationType_error = false; + private static volatile Method sun_AnnotationType_getInstance = null; + private static volatile Method sun_AnnotationType_members = null; + public static AnnotationSerializer instance = new AnnotationSerializer(); public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { @@ -22,8 +27,58 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty Class[] interfaces = objClass.getInterfaces(); if (interfaces.length == 1 && interfaces[0].isAnnotation()) { Class annotationClass = interfaces[0]; - AnnotationType type = AnnotationType.getInstance(annotationClass); - Map members = type.members(); + + if (sun_AnnotationType == null && !sun_AnnotationType_error) { + try { + sun_AnnotationType = Class.forName("sun.reflect.annotation.AnnotationType"); + } catch (Throwable ex) { + sun_AnnotationType_error = true; + throw new JSONException("not support Type Annotation.", ex); + } + } + + if (sun_AnnotationType == null) { + throw new JSONException("not support Type Annotation."); + } + + if (sun_AnnotationType_getInstance == null && !sun_AnnotationType_error) { + try { + sun_AnnotationType_getInstance = sun_AnnotationType.getMethod("getInstance", Class.class); + } catch (Throwable ex) { + sun_AnnotationType_error = true; + throw new JSONException("not support Type Annotation.", ex); + } + } + + if (sun_AnnotationType_members == null && !sun_AnnotationType_error) { + try { + sun_AnnotationType_members = sun_AnnotationType.getMethod("members"); + } catch (Throwable ex) { + sun_AnnotationType_error = true; + throw new JSONException("not support Type Annotation.", ex); + } + } + + if (sun_AnnotationType_getInstance == null || sun_AnnotationType_error) { + throw new JSONException("not support Type Annotation."); + } + + Object type; + try { + type = sun_AnnotationType_getInstance.invoke(null, annotationClass); + } catch (Throwable ex) { + sun_AnnotationType_error = true; + throw new JSONException("not support Type Annotation.", ex); + } + + Map members; + try { + members = (Map) sun_AnnotationType_members.invoke(type); + } catch (Throwable ex) { + sun_AnnotationType_error = true; + throw new JSONException("not support Type Annotation.", ex); + } + JSONObject json = new JSONObject(members.size()); Iterator> iterator = members.entrySet().iterator(); Map.Entry entry; diff --git a/src/main/java/com/alibaba/fastjson/serializer/AppendableSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AppendableSerializer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java old mode 100755 new mode 100644 index 43ec5df57f..dedad4d4d1 --- a/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/AtomicCodec.java b/src/main/java/com/alibaba/fastjson/serializer/AtomicCodec.java old mode 100755 new mode 100644 index eae108c76f..1b309cfafc --- a/src/main/java/com/alibaba/fastjson/serializer/AtomicCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AtomicCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java old mode 100755 new mode 100644 index 00d97848e7..7bc3e1db7f --- a/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/BeforeFilter.java b/src/main/java/com/alibaba/fastjson/serializer/BeforeFilter.java index 34ed06041d..7b4de56c5d 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/BeforeFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/BeforeFilter.java @@ -8,17 +8,24 @@ public abstract class BeforeFilter implements SerializeFilter { private final static Character COMMA = Character.valueOf(','); final char writeBefore(JSONSerializer serializer, Object object, char seperator) { + JSONSerializer last = serializerLocal.get(); serializerLocal.set(serializer); seperatorLocal.set(seperator); writeBefore(object); - serializerLocal.set(null); + serializerLocal.set(last); return seperatorLocal.get(); } protected final void writeKeyValue(String key, Object value) { JSONSerializer serializer = serializerLocal.get(); char seperator = seperatorLocal.get(); + + boolean ref = serializer.references.containsKey(value); serializer.writeKeyValue(seperator, key, value); + if (!ref) { + serializer.references.remove(value); + } + if (seperator != ',') { seperatorLocal.set(COMMA); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/BigDecimalCodec.java b/src/main/java/com/alibaba/fastjson/serializer/BigDecimalCodec.java old mode 100755 new mode 100644 index 7431a4066f..92defb01d5 --- a/src/main/java/com/alibaba/fastjson/serializer/BigDecimalCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/BigDecimalCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,8 @@ * @author wenshao[szujobs@hotmail.com] */ public class BigDecimalCodec implements ObjectSerializer, ObjectDeserializer { + final static BigDecimal LOW = BigDecimal.valueOf(-9007199254740991L); + final static BigDecimal HIGH = BigDecimal.valueOf(9007199254740991L); public final static BigDecimalCodec instance = new BigDecimalCodec(); @@ -40,13 +42,27 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty out.writeNull(SerializerFeature.WriteNullNumberAsZero); } else { BigDecimal val = (BigDecimal) object; + int scale = val.scale(); String outText; - if (out.isEnabled(SerializerFeature.WriteBigDecimalAsPlain)) { + if (SerializerFeature.isEnabled(features, out.features, SerializerFeature.WriteBigDecimalAsPlain) + && scale >= -100 && scale < 100) { outText = val.toPlainString(); } else { outText = val.toString(); } + + if (scale == 0) { + if (outText.length() >= 16 + && SerializerFeature.isEnabled(features, out.features, SerializerFeature.BrowserCompatible) + && (val.compareTo(LOW) < 0 + || val.compareTo(HIGH) > 0)) + { + out.writeString(outText); + return; + } + } + out.write(outText); if (out.isEnabled(SerializerFeature.WriteClassName) && fieldType != BigDecimal.class && val.scale() == 0) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/BigIntegerCodec.java b/src/main/java/com/alibaba/fastjson/serializer/BigIntegerCodec.java old mode 100755 new mode 100644 index 55e3cbf891..45b30a1b8b --- a/src/main/java/com/alibaba/fastjson/serializer/BigIntegerCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/BigIntegerCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.lang.reflect.Type; import java.math.BigInteger; +import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; @@ -29,10 +30,16 @@ * @author wenshao[szujobs@hotmail.com] */ public class BigIntegerCodec implements ObjectSerializer, ObjectDeserializer { + private final static BigInteger LOW = BigInteger.valueOf(-9007199254740991L); + private final static BigInteger HIGH = BigInteger.valueOf(9007199254740991L); public final static BigIntegerCodec instance = new BigIntegerCodec(); - public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + public void write(JSONSerializer serializer + , Object object + , Object fieldName + , Type fieldType, int features) throws IOException + { SerializeWriter out = serializer.out; if (object == null) { @@ -41,7 +48,16 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty } BigInteger val = (BigInteger) object; - out.write(val.toString()); + String str = val.toString(); + if (str.length() >= 16 + && SerializerFeature.isEnabled(features, out.features, SerializerFeature.BrowserCompatible) + && (val.compareTo(LOW) < 0 + || val.compareTo(HIGH) > 0)) + { + out.writeString(str); + return; + } + out.write(str); } @SuppressWarnings("unchecked") @@ -55,6 +71,11 @@ public static T deserialze(DefaultJSONParser parser) { if (lexer.token() == JSONToken.LITERAL_INT) { String val = lexer.numberString(); lexer.nextToken(JSONToken.COMMA); + + if (val.length() > 65535) { + throw new JSONException("decimal overflow"); + } + return (T) new BigInteger(val); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/BooleanCodec.java b/src/main/java/com/alibaba/fastjson/serializer/BooleanCodec.java old mode 100755 new mode 100644 index f9b732ba4a..c485172eb0 --- a/src/main/java/com/alibaba/fastjson/serializer/BooleanCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/BooleanCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/ByteBufferCodec.java b/src/main/java/com/alibaba/fastjson/serializer/ByteBufferCodec.java new file mode 100644 index 0000000000..f58913bdc4 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/ByteBufferCodec.java @@ -0,0 +1,54 @@ +package com.alibaba.fastjson.serializer; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.ByteBuffer; + +public class ByteBufferCodec implements ObjectSerializer, ObjectDeserializer { + public final static ByteBufferCodec instance = new ByteBufferCodec(); + + @Override + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + ByteBufferBean bean = parser.parseObject(ByteBufferBean.class); + return (T) bean.byteBuffer(); + } + + @Override + public int getFastMatchToken() { + return JSONToken.LBRACKET; + } + + @Override + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + ByteBuffer byteBuf = (ByteBuffer) object; + + byte[] array = byteBuf.array(); + + SerializeWriter out = serializer.out; + out.write('{'); + + out.writeFieldName("array"); + out.writeByteArray(array); + out.writeFieldValue(',', "limit", byteBuf.limit()); + out.writeFieldValue(',', "position", byteBuf.position()); + + out.write('}'); + } + + public static class ByteBufferBean { + public byte[] array; + public int limit; + public int position; + + public ByteBuffer byteBuffer() { + ByteBuffer buf = ByteBuffer.wrap(array); + buf.limit(limit); + buf.position(position); + return buf; + } + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java old mode 100755 new mode 100644 index a29a1666a0..6ae90ceff2 --- a/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java @@ -2,13 +2,17 @@ import java.io.IOException; import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ContextObjectDeserializer; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import com.alibaba.fastjson.util.IOUtils; @@ -16,12 +20,33 @@ import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -public class CalendarCodec implements ObjectSerializer, ObjectDeserializer { +public class CalendarCodec extends ContextObjectDeserializer implements ObjectSerializer, ObjectDeserializer, ContextObjectSerializer { public final static CalendarCodec instance = new CalendarCodec(); private DatatypeFactory dateFactory; + public void write(JSONSerializer serializer, Object object, BeanContext context) throws IOException { + SerializeWriter out = serializer.out; + String format = context.getFormat(); + Calendar calendar = (Calendar) object; + + if (format.equals("unixtime")) { + long seconds = calendar.getTimeInMillis() / 1000L; + out.writeInt((int) seconds); + return; + } + + DateFormat dateFormat = new SimpleDateFormat(format); + if (dateFormat == null) { + dateFormat = new SimpleDateFormat(JSON.DEFFAULT_DATE_FORMAT, serializer.locale); + } + dateFormat.setTimeZone(serializer.timeZone); + String text = dateFormat.format(calendar.getTime()); + out.writeString(text); + } + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.out; @@ -82,13 +107,31 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty out.write(buf); - int timeZone = calendar.getTimeZone().getRawOffset() / (3600 * 1000); - if (timeZone == 0) { - out.append("Z"); - } else if (timeZone > 0) { - out.append("+").append(String.format("%02d", timeZone)).append(":00"); + float timeZoneF = calendar.getTimeZone().getOffset(calendar.getTimeInMillis()) / (3600.0f * 1000); + int timeZone = (int)timeZoneF; + if (timeZone == 0.0) { + out.write('Z'); } else { - out.append("-").append(String.format("%02d", -timeZone)).append(":00"); + if (timeZone > 9) { + out.write('+'); + out.writeInt(timeZone); + } else if (timeZone > 0) { + out.write('+'); + out.write('0'); + out.writeInt(timeZone); + } else if (timeZone < -9) { + out.write('-'); + out.writeInt(timeZone); + } else if (timeZone < 0) { + out.write('-'); + out.write('0'); + out.writeInt(-timeZone); + } + out.write(':'); + // handles uneven timeZones 30 mins, 45 mins + // this would always be less than 60 + int offSet = (int)((timeZoneF - timeZone) * 60); + out.append(String.format("%02d", offSet)); } out.append(quote); @@ -98,9 +141,14 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty } } + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + return deserialze(parser, clazz, fieldName, null, 0); + } + + @Override @SuppressWarnings("unchecked") - public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { - Object value = DateCodec.instance.deserialze(parser, type, fieldName); + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName, String format, int features) { + Object value = DateCodec.instance.deserialze(parser, type, fieldName, format, features); if (value instanceof Calendar) { return (T) value; diff --git a/src/main/java/com/alibaba/fastjson/serializer/CharArrayCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CharArrayCodec.java old mode 100755 new mode 100644 index afafcc1eab..d6a31e7786 --- a/src/main/java/com/alibaba/fastjson/serializer/CharArrayCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/CharArrayCodec.java @@ -2,7 +2,6 @@ import java.lang.reflect.Type; import java.util.Collection; -import java.util.List; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; diff --git a/src/main/java/com/alibaba/fastjson/serializer/CharacterCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CharacterCodec.java old mode 100755 new mode 100644 index 24aaab8140..6f82c4f2ca --- a/src/main/java/com/alibaba/fastjson/serializer/CharacterCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/CharacterCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/ClobSeriliazer.java b/src/main/java/com/alibaba/fastjson/serializer/ClobSerializer.java old mode 100755 new mode 100644 similarity index 91% rename from src/main/java/com/alibaba/fastjson/serializer/ClobSeriliazer.java rename to src/main/java/com/alibaba/fastjson/serializer/ClobSerializer.java index 0605dd6600..078b89c6bb --- a/src/main/java/com/alibaba/fastjson/serializer/ClobSeriliazer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ClobSerializer.java @@ -8,9 +8,9 @@ import com.alibaba.fastjson.JSONException; -public class ClobSeriliazer implements ObjectSerializer { +public class ClobSerializer implements ObjectSerializer { - public final static ClobSeriliazer instance = new ClobSeriliazer(); + public final static ClobSerializer instance = new ClobSerializer(); public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { try { diff --git a/src/main/java/com/alibaba/fastjson/serializer/CollectionCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CollectionCodec.java old mode 100755 new mode 100644 index 5e88f7140f..95d5c3e3eb --- a/src/main/java/com/alibaba/fastjson/serializer/CollectionCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/CollectionCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,9 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; -import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.lang.reflect.WildcardType; import java.util.Collection; import java.util.HashSet; -import java.util.Map; import java.util.TreeSet; import com.alibaba.fastjson.JSONArray; @@ -58,7 +55,7 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty serializer.setContext(context, object, fieldName, 0); if (out.isEnabled(SerializerFeature.WriteClassName)) { - if (HashSet.class == collection.getClass()) { + if (HashSet.class.isAssignableFrom(collection.getClass())) { out.append("Set"); } else if (TreeSet.class == collection.getClass()) { out.append("TreeSet"); @@ -123,7 +120,13 @@ public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { return (T) array; } - Collection list = TypeUtils.createCollection(type); + Collection list; + if (parser.lexer.token() == JSONToken.SET) { + parser.lexer.nextToken(); + list = TypeUtils.createSet(type); + } else { + list = TypeUtils.createCollection(type); + } Type itemType = TypeUtils.getCollectionItemType(type); parser.parseArray(itemType, list, fieldName); diff --git a/src/main/java/com/alibaba/fastjson/serializer/DateCodec.java b/src/main/java/com/alibaba/fastjson/serializer/DateCodec.java index f1e5ee2570..31df03ae4f 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/DateCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/DateCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.io.IOException; import java.lang.reflect.Type; +import java.math.BigDecimal; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -48,6 +49,45 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty out.writeNull(); return; } + + Class clazz = object.getClass(); + if (clazz == java.sql.Date.class && !out.isEnabled(SerializerFeature.WriteDateUseDateFormat)) { + long millis = ((java.sql.Date) object).getTime(); + TimeZone timeZone = serializer.timeZone; + int offset = timeZone.getOffset(millis); + // + if ((millis + offset) % (24 * 1000 * 3600) == 0 + && !SerializerFeature.isEnabled(out.features, features, SerializerFeature.WriteClassName)) { + out.writeString(object.toString()); + return; + } + } + + if (clazz == java.sql.Time.class) { + long millis = ((java.sql.Time) object).getTime(); + if ("unixtime".equals(serializer.getDateFormatPattern())) { + long seconds = millis / 1000; + out.writeLong(seconds); + return; + } + + if ("millis".equals(serializer.getDateFormatPattern())) { + long seconds = millis; + out.writeLong(millis); + return; + } + + if (millis < 24L * 60L * 60L * 1000L) { + out.writeString(object.toString()); + return; + } + } + + int nanos = 0; + if (clazz == java.sql.Timestamp.class) { + java.sql.Timestamp ts = (java.sql.Timestamp) object; + nanos = ts.getNanos(); + } Date date; if (object instanceof Date) { @@ -55,11 +95,29 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty } else { date = TypeUtils.castToDate(object); } - + + if ("unixtime".equals(serializer.getDateFormatPattern())) { + long seconds = date.getTime() / 1000; + out.writeLong(seconds); + return; + } + + if ("millis".equals(serializer.getDateFormatPattern())) { + long millis = date.getTime(); + out.writeLong(millis); + return; + } + if (out.isEnabled(SerializerFeature.WriteDateUseDateFormat)) { DateFormat format = serializer.getDateFormat(); if (format == null) { - format = new SimpleDateFormat(JSON.DEFFAULT_DATE_FORMAT, serializer.locale); + // 如果是通过FastJsonConfig进行设置,优先从FastJsonConfig获取 + String dateFormatPattern = serializer.getFastJsonConfigDateFormatPattern(); + if(dateFormatPattern == null) { + dateFormatPattern = JSON.DEFFAULT_DATE_FORMAT; + } + + format = new SimpleDateFormat(dateFormatPattern, serializer.locale); format.setTimeZone(serializer.timeZone); } String text = format.format(date); @@ -68,15 +126,15 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty } if (out.isEnabled(SerializerFeature.WriteClassName)) { - if (object.getClass() != fieldType) { - if (object.getClass() == java.util.Date.class) { + if (clazz != fieldType) { + if (clazz == java.util.Date.class) { out.write("new Date("); out.writeLong(((Date) object).getTime()); out.write(')'); } else { out.write('{'); out.writeFieldName(JSON.DEFAULT_TYPE_KEY); - serializer.write(object.getClass().getName()); + serializer.write(clazz.getName()); out.writeFieldValue(',', "val", ((Date) object).getTime()); out.write('}'); } @@ -101,7 +159,16 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty int millis = calendar.get(Calendar.MILLISECOND); char[] buf; - if (millis != 0) { + if (nanos > 0) { + buf = "0000-00-00 00:00:00.000000000".toCharArray(); + IOUtils.getChars(nanos, 29, buf); + IOUtils.getChars(second, 19, buf); + IOUtils.getChars(minute, 16, buf); + IOUtils.getChars(hour, 13, buf); + IOUtils.getChars(day, 10, buf); + IOUtils.getChars(month, 7, buf); + IOUtils.getChars(year, 4, buf); + } else if (millis != 0) { buf = "0000-00-00T00:00:00.000".toCharArray(); IOUtils.getChars(millis, 23, buf); IOUtils.getChars(second, 19, buf); @@ -127,11 +194,26 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty IOUtils.getChars(year, 4, buf); } } - + + + if (nanos > 0) { // java.sql.Timestamp + int i = 0; + for (; i < 9; ++i) { + int off = buf.length - i - 1; + if (buf[off] != '0') { + break; + } + } + out.write(buf, 0, buf.length - i); + out.write(quote); + return; + } + out.write(buf); - - int timeZone = calendar.getTimeZone().getRawOffset()/(3600*1000); - if (timeZone == 0) { + + float timeZoneF = calendar.getTimeZone().getOffset(calendar.getTimeInMillis()) / (3600.0f * 1000); + int timeZone = (int)timeZoneF; + if (timeZone == 0.0) { out.write('Z'); } else { if (timeZone > 9) { @@ -143,14 +225,17 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty out.writeInt(timeZone); } else if (timeZone < -9) { out.write('-'); - out.writeInt(timeZone); + out.writeInt(-timeZone); } else if (timeZone < 0) { out.write('-'); out.write('0'); - out.writeInt(timeZone); + out.writeInt(-timeZone); } - - out.append(":00"); + out.write(':'); + // handles uneven timeZones 30 mins, 45 mins + // this would always be less than 60 + int offSet = (int)(Math.abs(timeZoneF - timeZone) * 60); + out.append(String.format("%02d", offSet)); } out.write(quote); @@ -168,6 +253,8 @@ public T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object if (val instanceof java.util.Date) { return (T) val; + } else if (val instanceof BigDecimal) { + return (T) new java.util.Date(TypeUtils.longValue((BigDecimal) val)); } else if (val instanceof Number) { return (T) new java.util.Date(((Number) val).longValue()); } else if (val instanceof String) { @@ -176,6 +263,10 @@ public T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object return null; } + if (strVal.length() == 23 && strVal.endsWith(" 000")) { + strVal = strVal.substring(0, 19); + } + { JSONScanner dateLexer = new JSONScanner(strVal); try { @@ -192,9 +283,13 @@ public T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object dateLexer.close(); } } - - if (strVal.length() == parser.getDateFomartPattern().length() - || (strVal.length() == 22 && parser.getDateFomartPattern().equals("yyyyMMddHHmmssSSSZ"))) { + + String dateFomartPattern = parser.getDateFomartPattern(); + boolean formatMatch = strVal.length() == dateFomartPattern.length() + || (strVal.length() == 22 && dateFomartPattern.equals("yyyyMMddHHmmssSSSZ")) + || (strVal.indexOf('T') != -1 && dateFomartPattern.contains("'T'") && strVal.length() + 2 == dateFomartPattern.length()) + ; + if (formatMatch) { DateFormat dateFormat = parser.getDateFormat(); try { return (T) dateFormat.parse(strVal); diff --git a/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java old mode 100755 new mode 100644 index 8f3ac0836d..d7c05699e1 --- a/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java old mode 100755 new mode 100644 index 2a055144af..08eb7e2910 --- a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,18 +15,46 @@ */ package com.alibaba.fastjson.serializer; +import com.alibaba.fastjson.JSONException; + import java.io.IOException; -import java.lang.reflect.Type; +import java.lang.reflect.*; /** * @author wenshao[szujobs@hotmail.com] */ public class EnumSerializer implements ObjectSerializer { + private final Member member; + + public EnumSerializer() { + this.member = null; + } + + public EnumSerializer(Member member) { + this.member = member; + } + public final static EnumSerializer instance = new EnumSerializer(); public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { - SerializeWriter out = serializer.out; - out.writeEnum((Enum) object); + if (member == null) { + SerializeWriter out = serializer.out; + out.writeEnum((Enum) object); + return; + } + + Object fieldValue = null; + try { + if (member instanceof Field) { + fieldValue = ((Field) member).get(object); + } else { + fieldValue = ((Method) member).invoke(object); + } + } catch (Exception e) { + throw new JSONException("getEnumValue error", e); + } + + serializer.write(fieldValue); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/EnumerationSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/EnumerationSerializer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java old mode 100755 new mode 100644 index acfebe8ab7..2a438cfdd2 --- a/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import java.lang.reflect.InvocationTargetException; import java.text.SimpleDateFormat; import java.util.Collection; -import java.util.Date; /** * @author wenshao[szujobs@hotmail.com] @@ -50,6 +49,7 @@ public class FieldSerializer implements Comparable { protected boolean serializeUsing = false; protected boolean persistenceXToMany = false; // OneToMany or ManyToMany + protected boolean browserCompatible; private RuntimeSerializerInfo runtimeInfo; @@ -57,16 +57,21 @@ public FieldSerializer(Class beanType, FieldInfo fieldInfo) { this.fieldInfo = fieldInfo; this.fieldContext = new BeanContext(beanType, fieldInfo); - if (beanType != null && fieldInfo.isEnum) { + if (beanType != null) { JSONType jsonType = TypeUtils.getAnnotation(beanType,JSONType.class); if (jsonType != null) { for (SerializerFeature feature : jsonType.serialzeFeatures()) { if (feature == SerializerFeature.WriteEnumUsingToString) { writeEnumUsingToString = true; - }else if(feature == SerializerFeature.WriteEnumUsingName){ + } else if(feature == SerializerFeature.WriteEnumUsingName){ writeEnumUsingName = true; - }else if(feature == SerializerFeature.DisableCircularReferenceDetect){ + } else if(feature == SerializerFeature.DisableCircularReferenceDetect){ disableCircularReferenceDetect = true; + } else if(feature == SerializerFeature.BrowserCompatible){ + features |= SerializerFeature.BrowserCompatible.mask; + browserCompatible = true; + } else if (feature == SerializerFeature.WriteMapNullValue) { + features |= SerializerFeature.WriteMapNullValue.mask; } } } @@ -95,14 +100,16 @@ public FieldSerializer(Class beanType, FieldInfo fieldInfo) { for (SerializerFeature feature : annotation.serialzeFeatures()) { if (feature == SerializerFeature.WriteEnumUsingToString) { writeEnumUsingToString = true; - }else if(feature == SerializerFeature.WriteEnumUsingName){ + } else if(feature == SerializerFeature.WriteEnumUsingName){ writeEnumUsingName = true; - }else if(feature == SerializerFeature.DisableCircularReferenceDetect){ + } else if(feature == SerializerFeature.DisableCircularReferenceDetect){ disableCircularReferenceDetect = true; + } else if(feature == SerializerFeature.BrowserCompatible){ + browserCompatible = true; } } - features = SerializerFeature.of(annotation.serialzeFeatures()); + features |= SerializerFeature.of(annotation.serialzeFeatures()); } this.writeNull = writeNull; @@ -115,7 +122,8 @@ public void writePrefix(JSONSerializer serializer) throws IOException { SerializeWriter out = serializer.out; if (out.quoteFieldNames) { - if (out.useSingleQuotes) { + boolean useSingleQuotes = SerializerFeature.isEnabled(out.features, fieldInfo.serialzeFeatures, SerializerFeature.UseSingleQuotes); + if (useSingleQuotes) { if (single_quoted_fieldPrefix == null) { single_quoted_fieldPrefix = '\'' + fieldInfo.name + "\':"; } @@ -142,8 +150,8 @@ public Object getPropertyValueDirect(Object object) throws InvocationTargetExcep public Object getPropertyValue(Object object) throws InvocationTargetException, IllegalAccessException { Object propertyValue = fieldInfo.get(object); if (format != null && propertyValue != null) { - if (fieldInfo.fieldClass == Date.class) { - SimpleDateFormat dateFormat = new SimpleDateFormat(format); + if (fieldInfo.fieldClass == java.util.Date.class || fieldInfo.fieldClass == java.sql.Date.class) { + SimpleDateFormat dateFormat = new SimpleDateFormat(format, JSON.defaultLocale); dateFormat.setTimeZone(JSON.defaultTimeZone); return dateFormat.format(propertyValue); } @@ -162,6 +170,21 @@ public void writeValue(JSONSerializer serializer, Object propertyValue) throws E Class runtimeFieldClass; if (propertyValue == null) { runtimeFieldClass = this.fieldInfo.fieldClass; + if (runtimeFieldClass == byte.class) { + runtimeFieldClass = Byte.class; + } else if (runtimeFieldClass == short.class) { + runtimeFieldClass = Short.class; + } else if (runtimeFieldClass == int.class) { + runtimeFieldClass = Integer.class; + } else if (runtimeFieldClass == long.class) { + runtimeFieldClass = Long.class; + } else if (runtimeFieldClass == float.class) { + runtimeFieldClass = Float.class; + } else if (runtimeFieldClass == double.class) { + runtimeFieldClass = Double.class; + } else if (runtimeFieldClass == boolean.class) { + runtimeFieldClass = Boolean.class; + } } else { runtimeFieldClass = propertyValue.getClass(); } @@ -191,8 +214,10 @@ public void writeValue(JSONSerializer serializer, Object propertyValue) throws E final RuntimeSerializerInfo runtimeInfo = this.runtimeInfo; - final int fieldFeatures = disableCircularReferenceDetect? - (fieldInfo.serialzeFeatures|SerializerFeature.DisableCircularReferenceDetect.getMask()):fieldInfo.serialzeFeatures; + final int fieldFeatures + = (disableCircularReferenceDetect + ? (fieldInfo.serialzeFeatures | SerializerFeature.DisableCircularReferenceDetect.mask) + : fieldInfo.serialzeFeatures) | features; if (propertyValue == null) { SerializeWriter out = serializer.out; @@ -214,7 +239,8 @@ public void writeValue(JSONSerializer serializer, Object propertyValue) throws E } else if (Boolean.class == runtimeFieldClass) { out.writeNull(features, SerializerFeature.WriteNullBooleanAsFalse.mask); return; - } else if (Collection.class.isAssignableFrom(runtimeFieldClass)) { + } else if (Collection.class.isAssignableFrom(runtimeFieldClass) + || runtimeFieldClass.isArray()) { out.writeNull(features, SerializerFeature.WriteNullListAsEmpty.mask); return; } @@ -276,11 +302,19 @@ public void writeValue(JSONSerializer serializer, Object propertyValue) throws E if ((features & SerializerFeature.WriteClassName.mask) != 0 && valueClass != fieldInfo.fieldClass - && JavaBeanSerializer.class.isInstance(valueSerializer)) { + && valueSerializer instanceof JavaBeanSerializer) { ((JavaBeanSerializer) valueSerializer).write(serializer, propertyValue, fieldInfo.name, fieldInfo.fieldType, fieldFeatures, false); return; } + if (browserCompatible && (fieldInfo.fieldClass == long.class || fieldInfo.fieldClass == Long.class)) { + long value = (Long) propertyValue; + if (value > 9007199254740991L || value < -9007199254740991L) { + serializer.getWriter().writeString(Long.toString(value)); + return; + } + } + valueSerializer.write(serializer, propertyValue, fieldInfo.name, fieldInfo.fieldType, fieldFeatures); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/FloatCodec.java b/src/main/java/com/alibaba/fastjson/serializer/FloatCodec.java old mode 100755 new mode 100644 index 5fad6fc8d9..5f80019b13 --- a/src/main/java/com/alibaba/fastjson/serializer/FloatCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/FloatCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/GuavaCodec.java b/src/main/java/com/alibaba/fastjson/serializer/GuavaCodec.java index 45c21f0492..4917886ebc 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/GuavaCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/GuavaCodec.java @@ -1,16 +1,22 @@ package com.alibaba.fastjson.serializer; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import java.io.IOException; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collection; +import java.util.List; import java.util.Map; /** * Created by wenshao on 15/01/2017. */ -public class GuavaCodec implements ObjectSerializer { +public class GuavaCodec implements ObjectSerializer, ObjectDeserializer { public static GuavaCodec instance = new GuavaCodec(); public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { @@ -20,4 +26,31 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty serializer.write(multimap.asMap()); } } + + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + Type rawType = type; + if (type instanceof ParameterizedType) { + rawType = ((ParameterizedType) type).getRawType(); + } + + if (rawType == ArrayListMultimap.class) { + ArrayListMultimap multimap = ArrayListMultimap.create(); + JSONObject object = parser.parseObject(); + for (Map.Entry entry : object.entrySet()) { + Object value = entry.getValue(); + if (value instanceof Collection) { + multimap.putAll(entry.getKey(), (List) value); + } else { + multimap.put(entry.getKey(), value); + } + } + + return (T) multimap; + } + return null; + } + + public int getFastMatchToken() { + return 0; + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/IntegerCodec.java b/src/main/java/com/alibaba/fastjson/serializer/IntegerCodec.java old mode 100755 new mode 100644 index 158d5094e5..c734600b81 --- a/src/main/java/com/alibaba/fastjson/serializer/IntegerCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/IntegerCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,7 @@ import java.io.IOException; import java.lang.reflect.Type; import java.math.BigDecimal; -import java.util.Iterator; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; @@ -82,9 +80,9 @@ public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) lexer.nextToken(JSONToken.COMMA); intObj = Integer.valueOf(val); } else if (token == JSONToken.LITERAL_FLOAT) { - BigDecimal decimalValue = lexer.decimalValue(); + BigDecimal number = lexer.decimalValue(); + intObj = TypeUtils.intValue(number); lexer.nextToken(JSONToken.COMMA); - intObj = Integer.valueOf(decimalValue.intValue()); } else { if (token == JSONToken.LBRACE) { JSONObject jsonObject = new JSONObject(true); @@ -96,7 +94,11 @@ public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) } } } catch (Exception ex) { - throw new JSONException("parseInt error, field : " + fieldName, ex); + String message = "parseInt error"; + if (fieldName != null) { + message += (", field : " + fieldName); + } + throw new JSONException(message, ex); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java old mode 100755 new mode 100644 index 6192ccca5d..64c9e1e005 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONLibDataFormatSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONLibDataFormatSerializer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONObjectCodec.java b/src/main/java/com/alibaba/fastjson/serializer/JSONObjectCodec.java new file mode 100644 index 0000000000..0736cbefa4 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONObjectCodec.java @@ -0,0 +1,29 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; + +public class JSONObjectCodec implements ObjectSerializer { + public final static JSONObjectCodec instance = new JSONObjectCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { + SerializeWriter out = serializer.out; + MapSerializer mapSerializer = MapSerializer.instance; + + try { + Field mapField = object.getClass().getDeclaredField("map"); + if (Modifier.isPrivate(mapField.getModifiers())) { + mapField.setAccessible(true); + } + + Object map = mapField.get(object); + mapSerializer.write(serializer, map, fieldName, fieldType, features); + + } catch (Exception e) { + out.writeNull(); + } + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializable.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializable.java index 401217fb59..a19adfebf4 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializable.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializable.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializableSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializableSerializer.java index 5967125675..88dc1354b6 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializableSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializableSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,10 @@ public class JSONSerializableSerializer implements ObjectSerializer { public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { JSONSerializable jsonSerializable = ((JSONSerializable) object); + if (jsonSerializable == null) { + serializer.writeNull(); + return; + } jsonSerializable.write(serializer, fieldName, fieldType, features); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java old mode 100755 new mode 100644 index 756bc8d99f..8c5ce51c0a --- a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,7 @@ import java.lang.reflect.Type; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.IdentityHashMap; -import java.util.Locale; -import java.util.TimeZone; +import java.util.*; import java.util.zip.GZIPOutputStream; import com.alibaba.fastjson.JSON; @@ -42,9 +39,17 @@ public class JSONSerializer extends SerializeFilterable { private int indentCount = 0; private String indent = "\t"; + /** + * #1868 为了区分全局配置(FastJsonConfig)的日期格式配置以及toJSONString传入的日期格式配置 + * 建议使用以下调整: + * 1. dateFormatPattern、dateFormat只作为toJSONString传入配置使用; + * 2. 新增fastJsonConfigDateFormatPattern,用于存储通过(FastJsonConfig)配置的日期格式 + */ private String dateFormatPattern; private DateFormat dateFormat; + private String fastJsonConfigDateFormatPattern; + protected IdentityHashMap references = null; protected SerialContext context; @@ -78,14 +83,20 @@ public String getDateFormatPattern() { public DateFormat getDateFormat() { if (dateFormat == null) { if (dateFormatPattern != null) { - dateFormat = new SimpleDateFormat(dateFormatPattern, locale); - dateFormat.setTimeZone(timeZone); + dateFormat = this.generateDateFormat( dateFormatPattern ); } } return dateFormat; } + private DateFormat generateDateFormat(String dateFormatPattern) { + DateFormat dateFormat = new SimpleDateFormat(dateFormatPattern, locale); + dateFormat.setTimeZone(timeZone); + + return dateFormat; + } + public void setDateFormat(DateFormat dateFormat) { this.dateFormat = dateFormat; if (dateFormatPattern != null) { @@ -100,6 +111,19 @@ public void setDateFormat(String dateFormat) { } } + /** + * Set global date format pattern in FastJsonConfig + * + * @param dateFormatPattern global date format pattern + */ + public void setFastJsonConfigDateFormatPattern(String dateFormatPattern) { + this.fastJsonConfigDateFormatPattern = dateFormatPattern; + } + + public String getFastJsonConfigDateFormatPattern() { + return this.fastJsonConfigDateFormatPattern; + } + public SerialContext getContext() { return context; } @@ -151,6 +175,10 @@ public boolean containsReference(Object value) { return false; } + if (value == Collections.emptyMap()) { + return false; + } + Object fieldName = refContext.fieldName; return fieldName == null || fieldName instanceof Integer || fieldName instanceof String; @@ -186,7 +214,8 @@ public void writeReference(Object object) { out.write("{\"$ref\":\"$\"}"); } else { out.write("{\"$ref\":\""); - out.write(references.get(object).toString()); + String path = references.get(object).toString(); + out.write(path); out.write("\"}"); } } @@ -204,6 +233,11 @@ public boolean hasNameFilters(SerializeFilterable filterable) { || (filterable.nameFilters != null && filterable.nameFilters.size() > 0); } + public boolean hasPropertyFilters(SerializeFilterable filterable) { + return (propertyFilters != null && propertyFilters.size() > 0) // + || (filterable.propertyFilters != null && filterable.propertyFilters.size() > 0); + } + public int getIndentCount() { return indentCount; } @@ -281,6 +315,25 @@ public final void write(Object object) { } } + /** + * @since 1.2.57 + * + */ + public final void writeAs(Object object, Class type) { + if (object == null) { + out.writeNull(); + return; + } + + ObjectSerializer writer = getObjectWriter(type); + + try { + writer.write(this, object, null, null, 0); + } catch (IOException e) { + throw new JSONException(e.getMessage(), e); + } + } + public final void writeWithFieldName(Object object, Object fieldName) { writeWithFieldName(object, fieldName, null, 0); } @@ -312,10 +365,31 @@ public final void writeWithFieldName(Object object, Object fieldName, Type field public final void writeWithFormat(Object object, String format) { if (object instanceof Date) { + if ("unixtime".equals(format)) { + long seconds = ((Date) object).getTime() / 1000L; + out.writeInt((int) seconds); + return; + } + + if ("millis".equals(format)) { + out.writeLong(((Date) object).getTime()); + return; + } + DateFormat dateFormat = this.getDateFormat(); if (dateFormat == null) { - dateFormat = new SimpleDateFormat(format, locale); - dateFormat.setTimeZone(timeZone); + if (format != null) { + try { + dateFormat = this.generateDateFormat(format); + } catch (IllegalArgumentException e) { + String format2 = format.replaceAll("T", "'T'"); + dateFormat = this.generateDateFormat(format2); + } + } else if (fastJsonConfigDateFormatPattern != null) { + dateFormat = this.generateDateFormat(fastJsonConfigDateFormatPattern); + } else { + dateFormat = this.generateDateFormat(JSON.DEFFAULT_DATE_FORMAT); + } } String text = dateFormat.format((Date) object); out.writeString(text); @@ -348,6 +422,21 @@ public final void writeWithFormat(Object object, String format) { } return; } + + if (object instanceof Collection) { + Collection collection = (Collection) object; + Iterator iterator = collection.iterator(); + out.write('['); + for (int i = 0; i < collection.size(); i++) { + Object item = iterator.next(); + if (i != 0) { + out.write(','); + } + writeWithFormat(item, format); + } + out.write(']'); + return; + } write(object); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerMap.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerMap.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java index 3708369998..fcd713d7f9 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +20,22 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.PropertyNamingStrategy; import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.util.FieldInfo; import com.alibaba.fastjson.util.TypeUtils; @@ -37,7 +47,7 @@ public class JavaBeanSerializer extends SerializeFilterable implements ObjectSer protected final FieldSerializer[] getters; protected final FieldSerializer[] sortedGetters; - protected SerializeBeanInfo beanInfo; + protected final SerializeBeanInfo beanInfo; private transient volatile long[] hashArray; private transient volatile short[] hashArrayMapping; @@ -59,6 +69,17 @@ static Map createAliasMap(String... aliasList) { return aliasMap; } + public JSONType getJSONType() { + return beanInfo.jsonType; + } + + /** + * @since 1.2.42 + */ + public Class getType() { + return beanInfo.beanType; + } + public JavaBeanSerializer(Class beanType, Map aliasMap){ this(TypeUtils.buildBeanInfo(beanType, aliasMap, null)); } @@ -74,9 +95,29 @@ public JavaBeanSerializer(SerializeBeanInfo beanInfo) { if (beanInfo.fields == beanInfo.sortedFields) { getters = sortedGetters; } else { - getters = new FieldSerializer[beanInfo.fields.length]; + getters = new FieldSerializer[beanInfo.fields.length]; + boolean hashNotMatch = false; for (int i = 0; i < getters.length; ++i) { - getters[i] = getFieldSerializer(beanInfo.fields[i].name); + FieldSerializer fieldSerializer = getFieldSerializer(beanInfo.fields[i].name); + if (fieldSerializer == null) { + hashNotMatch = true; + break; + } + getters[i] = fieldSerializer; + } + if (hashNotMatch) { + System.arraycopy(sortedGetters, 0, getters, 0, sortedGetters.length); + } + } + + if (beanInfo.jsonType != null) { + for (Class filterClass : beanInfo.jsonType.serialzeFilters()) { + try { + SerializeFilter filter = filterClass.getConstructor().newInstance(); + this.addFilter(filter); + } catch (Exception e) { + // skip + } } } } @@ -154,6 +195,7 @@ protected void write(JSONSerializer serializer, // final boolean writeAsArray = isWriteAsArray(serializer, features); + FieldSerializer errorFieldSerializer = null; try { final char startSeperator = writeAsArray ? '[' : '{'; final char endSeperator = writeAsArray ? ']' : '}'; @@ -188,7 +230,7 @@ protected void write(JSONSerializer serializer, // char seperator = commaFlag ? ',' : '\0'; - final boolean directWritePrefix = out.quoteFieldNames && !out.useSingleQuotes; + final boolean writeClassName = out.isEnabled(SerializerFeature.WriteClassName); char newSeperator = this.writeBefore(serializer, object, seperator); commaFlag = newSeperator == ','; @@ -203,11 +245,12 @@ protected void write(JSONSerializer serializer, // String fieldInfoName = fieldInfo.name; Class fieldClass = fieldInfo.fieldClass; + final boolean fieldUseSingleQuotes = SerializerFeature.isEnabled(out.features, fieldInfo.serialzeFeatures, SerializerFeature.UseSingleQuotes); + final boolean directWritePrefix = out.quoteFieldNames && !fieldUseSingleQuotes; + if (skipTransient) { - if (field != null) { - if (fieldInfo.fieldTransient) { - continue; - } + if (fieldInfo.fieldTransient) { + continue; } } @@ -217,26 +260,35 @@ protected void write(JSONSerializer serializer, // } } + boolean notApply = false; if ((!this.applyName(serializer, object, fieldInfoName)) // || !this.applyLabel(serializer, fieldInfo.label)) { - continue; + if (writeAsArray) { + notApply = true; + } else { + continue; + } } - if (beanInfo.typeKey != null - && fieldInfoName.equals(beanInfo.typeKey) + if (fieldInfoName.equals(beanInfo.typeKey) && serializer.isWriteClassName(fieldType, object)) { continue; } Object propertyValue; - - try { - propertyValue = fieldSerializer.getPropertyValueDirect(object); - } catch (InvocationTargetException ex) { - if (out.isEnabled(SerializerFeature.IgnoreErrorGetter)) { - propertyValue = null; - } else { - throw ex; + + if (notApply) { + propertyValue = null; + } else { + try { + propertyValue = fieldSerializer.getPropertyValueDirect(object); + } catch (InvocationTargetException ex) { + errorFieldSerializer = fieldSerializer; + if (out.isEnabled(SerializerFeature.IgnoreErrorGetter)) { + propertyValue = null; + } else { + throw ex; + } } } @@ -255,30 +307,64 @@ protected void write(JSONSerializer serializer, // Object originalValue = propertyValue; propertyValue = this.processValue(serializer, fieldSerializer.fieldContext, object, fieldInfoName, - propertyValue); + propertyValue, features); - if (propertyValue == null && !writeAsArray) { - if (fieldClass == Boolean.class) { - final int mask = SerializerFeature.WriteNullBooleanAsFalse.mask | SerializerFeature.WriteMapNullValue.mask; - if ((fieldInfo.serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { + if (propertyValue == null) { + int serialzeFeatures = fieldInfo.serialzeFeatures; + JSONField jsonField = fieldInfo.getAnnotation(); + if (beanInfo.jsonType != null) { + serialzeFeatures |= SerializerFeature.of(beanInfo.jsonType.serialzeFeatures()); + } + // beanInfo.jsonType + if (jsonField != null && !"".equals(jsonField.defaultValue())) { + propertyValue = jsonField.defaultValue(); + } else if (fieldClass == Boolean.class) { + int defaultMask = SerializerFeature.WriteNullBooleanAsFalse.mask; + final int mask = defaultMask | SerializerFeature.WriteMapNullValue.mask; + if ((!writeAsArray) && (serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { continue; + } else if ((serialzeFeatures & defaultMask) != 0) { + propertyValue = false; + } else if ((out.features & defaultMask) != 0 + && (serialzeFeatures & SerializerFeature.WriteMapNullValue.mask) == 0) { + propertyValue = false; } } else if (fieldClass == String.class) { - final int mask = SerializerFeature.WriteNullStringAsEmpty.mask | SerializerFeature.WriteMapNullValue.mask; - if ((fieldInfo.serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { + int defaultMask = SerializerFeature.WriteNullStringAsEmpty.mask; + final int mask = defaultMask | SerializerFeature.WriteMapNullValue.mask; + if ((!writeAsArray) && (serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { continue; + } else if ((serialzeFeatures & defaultMask) != 0) { + propertyValue = ""; + } else if ((out.features & defaultMask) != 0 + && (serialzeFeatures & SerializerFeature.WriteMapNullValue.mask) == 0) { + propertyValue = ""; } } else if (Number.class.isAssignableFrom(fieldClass)) { - final int mask = SerializerFeature.WriteNullNumberAsZero.mask | SerializerFeature.WriteMapNullValue.mask; - if ((fieldInfo.serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { + int defaultMask = SerializerFeature.WriteNullNumberAsZero.mask; + final int mask = defaultMask | SerializerFeature.WriteMapNullValue.mask; + if ((!writeAsArray) && (serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { continue; + } else if ((serialzeFeatures & defaultMask) != 0) { + propertyValue = 0; + } else if ((out.features & defaultMask) != 0 + && (serialzeFeatures & SerializerFeature.WriteMapNullValue.mask) == 0) { + propertyValue = 0; } } else if (Collection.class.isAssignableFrom(fieldClass)) { - final int mask = SerializerFeature.WriteNullListAsEmpty.mask | SerializerFeature.WriteMapNullValue.mask; - if ((fieldInfo.serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { + int defaultMask = SerializerFeature.WriteNullListAsEmpty.mask; + final int mask = defaultMask | SerializerFeature.WriteMapNullValue.mask; + if ((!writeAsArray) && (serialzeFeatures & mask) == 0 && (out.features & mask) == 0) { continue; + } else if ((serialzeFeatures & defaultMask) != 0) { + propertyValue = Collections.emptyList(); + } else if ((out.features & defaultMask) != 0 + && (serialzeFeatures & SerializerFeature.WriteMapNullValue.mask) == 0) { + propertyValue = Collections.emptyList(); } - } else if ((!fieldSerializer.writeNull) && !out.isEnabled(SerializerFeature.WriteMapNullValue.mask)){ + } else if ((!writeAsArray) && (!fieldSerializer.writeNull) + && !out.isEnabled(SerializerFeature.WriteMapNullValue.mask) + && (serialzeFeatures & SerializerFeature.WriteMapNullValue.mask) == 0) { continue; } } @@ -339,7 +425,9 @@ protected void write(JSONSerializer serializer, // serializer.write(propertyValue); } else { if (!writeAsArray) { - if (!fieldInfo.unwrapped) { + boolean isMap = Map.class.isAssignableFrom(fieldClass); + boolean isJavaBean = !fieldClass.isPrimitive() && !fieldClass.getName().startsWith("java.") || fieldClass == Object.class; + if (writeClassName || !fieldInfo.unwrapped || !(isMap || isJavaBean)) { if (directWritePrefix) { out.write(fieldInfo.name_chars, 0, fieldInfo.name_chars.length); } else { @@ -352,8 +440,14 @@ protected void write(JSONSerializer serializer, // JSONField fieldAnnotation = fieldInfo.getAnnotation(); if (fieldClass == String.class && (fieldAnnotation == null || fieldAnnotation.serializeUsing() == Void.class)) { if (propertyValue == null) { + int serialzeFeatures = fieldSerializer.features; + if (beanInfo.jsonType != null) { + serialzeFeatures |= SerializerFeature.of(beanInfo.jsonType.serialzeFeatures()); + } if ((out.features & SerializerFeature.WriteNullStringAsEmpty.mask) != 0 - || (fieldSerializer.features & SerializerFeature.WriteNullStringAsEmpty.mask) != 0) { + && (serialzeFeatures & SerializerFeature.WriteMapNullValue.mask) == 0) { + out.writeString(""); + } else if ((serialzeFeatures & SerializerFeature.WriteNullStringAsEmpty.mask) != 0) { out.writeString(""); } else { out.writeNull(); @@ -361,7 +455,7 @@ protected void write(JSONSerializer serializer, // } else { String propertyValueString = (String) propertyValue; - if (out.useSingleQuotes) { + if (fieldUseSingleQuotes) { out.writeStringWithSingleQuote(propertyValueString); } else { out.writeStringWithDoubleQuote(propertyValueString, (char) 0); @@ -424,12 +518,27 @@ protected void write(JSONSerializer serializer, // } if (fieldName != null) { errorMessage += ", fieldName : " + fieldName; + } else if (errorFieldSerializer != null && errorFieldSerializer.fieldInfo != null) { + FieldInfo fieldInfo = errorFieldSerializer.fieldInfo; + if (fieldInfo.method != null) { + errorMessage += ", method : " + fieldInfo.method.getName(); + } else { + errorMessage += ", fieldName : " + errorFieldSerializer.fieldInfo.name; + } } if (e.getMessage() != null) { errorMessage += (", " + e.getMessage()); } - throw new JSONException(errorMessage, e); + Throwable cause = null; + if (e instanceof InvocationTargetException) { + cause = e.getCause(); + } + if (cause == null) { + cause = e; + } + + throw new JSONException(errorMessage, cause); } finally { serializer.context = parent; } @@ -646,13 +755,51 @@ public int getSize(Object object) throws Exception { return size; } + /** + * Get field names of not null fields. Keep the same logic as getSize. + * + * @param object the object to be checked + * @return field name set + * @throws Exception + * @see #getSize(Object) + */ + public Set getFieldNames(Object object) throws Exception { + Set fieldNames = new HashSet(); + for (FieldSerializer getter : sortedGetters) { + Object value = getter.getPropertyValueDirect(object); + if (value != null) { + fieldNames.add(getter.fieldInfo.name); + } + } + return fieldNames; + } + public Map getFieldValuesMap(Object object) throws Exception { Map map = new LinkedHashMap(sortedGetters.length); - + boolean skipTransient = true; + FieldInfo fieldInfo = null; + for (FieldSerializer getter : sortedGetters) { - map.put(getter.fieldInfo.name, getter.getPropertyValue(object)); + skipTransient = SerializerFeature.isEnabled(getter.features, SerializerFeature.SkipTransientField); + fieldInfo = getter.fieldInfo; + + if (skipTransient && fieldInfo != null && fieldInfo.fieldTransient) { + continue; + } + + if (getter.fieldInfo.unwrapped) { + Object unwrappedValue = getter.getPropertyValue(object); + Object map1 = JSON.toJSON(unwrappedValue); + if (map1 instanceof Map) { + map.putAll((Map) map1); + } else { + map.put(getter.fieldInfo.name, getter.getPropertyValue(object)); + } + } else { + map.put(getter.fieldInfo.name, getter.getPropertyValue(object)); + } } - + return map; } diff --git a/src/main/java/com/alibaba/fastjson/serializer/JodaCodec.java b/src/main/java/com/alibaba/fastjson/serializer/JodaCodec.java new file mode 100644 index 0000000000..4413b78f11 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/JodaCodec.java @@ -0,0 +1,503 @@ +package com.alibaba.fastjson.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Locale; +import java.util.TimeZone; + +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; +import org.joda.time.*; +import org.joda.time.format.*; + +public class JodaCodec implements ObjectSerializer, ContextObjectSerializer, ObjectDeserializer { + public final static JodaCodec instance = new JodaCodec(); + + private final static String defaultPatttern = "yyyy-MM-dd HH:mm:ss"; + private final static DateTimeFormatter defaultFormatter = DateTimeFormat.forPattern(defaultPatttern); + private final static DateTimeFormatter defaultFormatter_23 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS"); + private final static DateTimeFormatter formatter_dt19_tw = DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_cn = DateTimeFormat.forPattern("yyyy年M月d日 HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_cn_1 = DateTimeFormat.forPattern("yyyy年M月d日 H时m分s秒"); + private final static DateTimeFormatter formatter_dt19_kr = DateTimeFormat.forPattern("yyyy년M월d일 HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_us = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_eur = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_de = DateTimeFormat.forPattern("dd.MM.yyyy HH:mm:ss"); + private final static DateTimeFormatter formatter_dt19_in = DateTimeFormat.forPattern("dd-MM-yyyy HH:mm:ss"); + + private final static DateTimeFormatter formatter_d8 = DateTimeFormat.forPattern("yyyyMMdd"); + private final static DateTimeFormatter formatter_d10_tw = DateTimeFormat.forPattern("yyyy/MM/dd"); + private final static DateTimeFormatter formatter_d10_cn = DateTimeFormat.forPattern("yyyy年M月d日"); + private final static DateTimeFormatter formatter_d10_kr = DateTimeFormat.forPattern("yyyy년M월d일"); + private final static DateTimeFormatter formatter_d10_us = DateTimeFormat.forPattern("MM/dd/yyyy"); + private final static DateTimeFormatter formatter_d10_eur = DateTimeFormat.forPattern("dd/MM/yyyy"); + private final static DateTimeFormatter formatter_d10_de = DateTimeFormat.forPattern("dd.MM.yyyy"); + private final static DateTimeFormatter formatter_d10_in = DateTimeFormat.forPattern("dd-MM-yyyy"); + + private final static DateTimeFormatter ISO_FIXED_FORMAT = + DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZone(DateTimeZone.getDefault()); + + private final static String formatter_iso8601_pattern = "yyyy-MM-dd'T'HH:mm:ss"; + private final static String formatter_iso8601_pattern_23 = "yyyy-MM-dd'T'HH:mm:ss.SSS"; + private final static String formatter_iso8601_pattern_29 = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS"; + private final static DateTimeFormatter formatter_iso8601 = DateTimeFormat.forPattern(formatter_iso8601_pattern); + + + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + return deserialze(parser, type, fieldName, null, 0); + } + + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName, String format, int feature) { + JSONLexer lexer = parser.lexer; + if (lexer.token() == JSONToken.NULL){ + lexer.nextToken(); + return null; + } + + if (lexer.token() == JSONToken.LITERAL_STRING) { + String text = lexer.stringVal(); + lexer.nextToken(); + + DateTimeFormatter formatter = null; + if (format != null) { + if (defaultPatttern.equals(format)) { + formatter = defaultFormatter; + } else { + formatter = DateTimeFormat.forPattern(format); + } + } + + if ("".equals(text)) { + return null; + } + + if (type == LocalDateTime.class) { + LocalDateTime localDateTime; + if (text.length() == 10 || text.length() == 8) { + LocalDate localDate = parseLocalDate(text, format, formatter); + localDateTime = localDate.toLocalDateTime(LocalTime.MIDNIGHT); + } else { + localDateTime = parseDateTime(text, formatter); + } + return (T) localDateTime; + } else if (type == LocalDate.class) { + LocalDate localDate; + if (text.length() == 23) { + LocalDateTime localDateTime = LocalDateTime.parse(text); + localDate = localDateTime.toLocalDate(); + } else { + localDate = parseLocalDate(text, format, formatter); + } + + return (T) localDate; + } else if (type == LocalTime.class) { + LocalTime localDate; + if (text.length() == 23) { + LocalDateTime localDateTime = LocalDateTime.parse(text); + localDate = localDateTime.toLocalTime(); + } else { + localDate = LocalTime.parse(text); + } + return (T) localDate; + } else if (type == DateTime.class) { + if (formatter == defaultFormatter) { + formatter = ISO_FIXED_FORMAT; + } + + DateTime zonedDateTime = parseZonedDateTime(text, formatter); + + return (T) zonedDateTime; + } else if (type == DateTimeZone.class) { + DateTimeZone offsetTime = DateTimeZone.forID(text); + + return (T) offsetTime; + } else if (type == Period.class) { + Period period = Period.parse(text); + + return (T) period; + } else if (type == Duration.class) { + Duration duration = Duration.parse(text); + + return (T) duration; + } else if (type == Instant.class) { + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + return (T) new Instant(epochMillis); + } + + Instant instant = Instant.parse(text); + + return (T) instant; + } else if (type == DateTimeFormatter.class) { + return (T) DateTimeFormat.forPattern(text); + } + } else if (lexer.token() == JSONToken.LITERAL_INT) { + long millis = lexer.longValue(); + lexer.nextToken(); + + TimeZone timeZone = JSON.defaultTimeZone; + if (timeZone == null) { + timeZone = TimeZone.getDefault(); + } + + if (type == DateTime.class) { + return (T) new DateTime(millis, DateTimeZone.forTimeZone(timeZone)); + } + + LocalDateTime localDateTime = new LocalDateTime(millis, DateTimeZone.forTimeZone(timeZone)); + if (type == LocalDateTime.class) { + return (T) localDateTime; + } + + if (type == LocalDate.class) { + return (T) localDateTime.toLocalDate(); + } + + if (type == LocalTime.class) { + return (T) localDateTime.toLocalTime(); + } + + if (type == Instant.class) { + Instant instant = new Instant(millis); + + return (T) instant; + } + + throw new UnsupportedOperationException(); + } else if (lexer.token() == JSONToken.LBRACE) { + JSONObject object = parser.parseObject(); + + if (type == Instant.class) { + Object epochSecond = object.get("epochSecond"); + + if (epochSecond instanceof Number) { + return (T) Instant.ofEpochSecond( + TypeUtils.longExtractValue((Number) epochSecond)); + } + + Object millis = object.get("millis"); + if (millis instanceof Number) { + return (T) Instant.ofEpochMilli( + TypeUtils.longExtractValue((Number) millis)); + } + } + } else { + throw new UnsupportedOperationException(); + } + return null; + } + + protected LocalDateTime parseDateTime(String text, DateTimeFormatter formatter) { + if (formatter == null) { + if (text.length() == 19) { + char c4 = text.charAt(4); + char c7 = text.charAt(7); + char c10 = text.charAt(10); + char c13 = text.charAt(13); + char c16 = text.charAt(16); + if (c13 == ':' && c16 == ':') { + if (c4 == '-' && c7 == '-') { // yyyy-MM-dd or yyyy-MM-dd'T' + if (c10 == 'T') { + formatter = formatter_iso8601; + } else if (c10 == ' ') { + formatter = defaultFormatter; + } + } else if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd + formatter = formatter_dt19_tw; + } else { + char c0 = text.charAt(0); + char c1 = text.charAt(1); + char c2 = text.charAt(2); + char c3 = text.charAt(3); + char c5 = text.charAt(5); + if (c2 == '/' && c5 == '/') { // mm/dd/yyyy or mm/dd/yyyy + int v0 = (c0 - '0') * 10 + (c1 - '0'); + int v1 = (c3 - '0') * 10 + (c4 - '0'); + if (v0 > 12) { + formatter = formatter_dt19_eur; + } else if (v1 > 12) { + formatter = formatter_dt19_us; + } else { + String country = Locale.getDefault().getCountry(); + + if (country.equals("US")) { + formatter = formatter_dt19_us; + } else if (country.equals("BR") // + || country.equals("AU")) { + formatter = formatter_dt19_eur; + } + } + } else if (c2 == '.' && c5 == '.') { // dd.mm.yyyy + formatter = formatter_dt19_de; + } else if (c2 == '-' && c5 == '-') { // dd-mm-yyyy + formatter = formatter_dt19_in; + } + } + } + } else if (text.length() == 23) { + char c4 = text.charAt(4); + char c7 = text.charAt(7); + char c10 = text.charAt(10); + char c13 = text.charAt(13); + char c16 = text.charAt(16); + char c19 = text.charAt(19); + + if (c13 == ':' + && c16 == ':' + && c4 == '-' + && c7 == '-' + && c10 == ' ' + && c19 == '.' + ) { + formatter = defaultFormatter_23; + } + } + + if (text.length() >= 17) { + char c4 = text.charAt(4); + if (c4 == '年') { + if (text.charAt(text.length() - 1) == '秒') { + formatter = formatter_dt19_cn_1; + } else { + formatter = formatter_dt19_cn; + } + } else if (c4 == '년') { + formatter = formatter_dt19_kr; + } + } + + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + return new LocalDateTime(epochMillis, DateTimeZone.forTimeZone(JSON.defaultTimeZone)); + } + } + + return formatter == null ? // + LocalDateTime.parse(text) // + : LocalDateTime.parse(text, formatter); + } + + protected LocalDate parseLocalDate(String text, String format, DateTimeFormatter formatter) { + if (formatter == null) { + if (text.length() == 8) { + formatter = formatter_d8; + } + + if (text.length() == 10) { + char c4 = text.charAt(4); + char c7 = text.charAt(7); + if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd + formatter = formatter_d10_tw; + } + + char c0 = text.charAt(0); + char c1 = text.charAt(1); + char c2 = text.charAt(2); + char c3 = text.charAt(3); + char c5 = text.charAt(5); + if (c2 == '/' && c5 == '/') { // mm/dd/yyyy or mm/dd/yyyy + int v0 = (c0 - '0') * 10 + (c1 - '0'); + int v1 = (c3 - '0') * 10 + (c4 - '0'); + if (v0 > 12) { + formatter = formatter_d10_eur; + } else if (v1 > 12) { + formatter = formatter_d10_us; + } else { + String country = Locale.getDefault().getCountry(); + + if (country.equals("US")) { + formatter = formatter_d10_us; + } else if (country.equals("BR") // + || country.equals("AU")) { + formatter = formatter_d10_eur; + } + } + } else if (c2 == '.' && c5 == '.') { // dd.mm.yyyy + formatter = formatter_d10_de; + } else if (c2 == '-' && c5 == '-') { // dd-mm-yyyy + formatter = formatter_d10_in; + } + } + + if (text.length() >= 9) { + char c4 = text.charAt(4); + if (c4 == '年') { + formatter = formatter_d10_cn; + } else if (c4 == '년') { + formatter = formatter_d10_kr; + } + } + + boolean digit = true; + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch < '0' || ch > '9') { + digit = false; + break; + } + } + if (digit && text.length() > 8 && text.length() < 19) { + long epochMillis = Long.parseLong(text); + return new LocalDateTime(epochMillis, DateTimeZone.forTimeZone(JSON.defaultTimeZone)) + .toLocalDate(); + } + } + + return formatter == null ? // + LocalDate.parse(text) // + : LocalDate.parse(text, formatter); + } + + protected DateTime parseZonedDateTime(String text, DateTimeFormatter formatter) { + if (formatter == null) { + if (text.length() == 19) { + char c4 = text.charAt(4); + char c7 = text.charAt(7); + char c10 = text.charAt(10); + char c13 = text.charAt(13); + char c16 = text.charAt(16); + if (c13 == ':' && c16 == ':') { + if (c4 == '-' && c7 == '-') { // yyyy-MM-dd or yyyy-MM-dd'T' + if (c10 == 'T') { + formatter = formatter_iso8601; + } else if (c10 == ' ') { + formatter = defaultFormatter; + } + } else if (c4 == '/' && c7 == '/') { // tw yyyy/mm/dd + formatter = formatter_dt19_tw; + } else { + char c0 = text.charAt(0); + char c1 = text.charAt(1); + char c2 = text.charAt(2); + char c3 = text.charAt(3); + char c5 = text.charAt(5); + if (c2 == '/' && c5 == '/') { // mm/dd/yyyy or mm/dd/yyyy + int v0 = (c0 - '0') * 10 + (c1 - '0'); + int v1 = (c3 - '0') * 10 + (c4 - '0'); + if (v0 > 12) { + formatter = formatter_dt19_eur; + } else if (v1 > 12) { + formatter = formatter_dt19_us; + } else { + String country = Locale.getDefault().getCountry(); + + if (country.equals("US")) { + formatter = formatter_dt19_us; + } else if (country.equals("BR") // + || country.equals("AU")) { + formatter = formatter_dt19_eur; + } + } + } else if (c2 == '.' && c5 == '.') { // dd.mm.yyyy + formatter = formatter_dt19_de; + } else if (c2 == '-' && c5 == '-') { // dd-mm-yyyy + formatter = formatter_dt19_in; + } + } + } + } + + if (text.length() >= 17) { + char c4 = text.charAt(4); + if (c4 == '年') { + if (text.charAt(text.length() - 1) == '秒') { + formatter = formatter_dt19_cn_1; + } else { + formatter = formatter_dt19_cn; + } + } else if (c4 == '년') { + formatter = formatter_dt19_kr; + } + } + } + + return formatter == null ? // + DateTime.parse(text) // + : DateTime.parse(text, formatter); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, + int features) throws IOException { + SerializeWriter out = serializer.out; + if (object == null) { + out.writeNull(); + } else { + if (fieldType == null) { + fieldType = object.getClass(); + } + + if (fieldType == LocalDateTime.class) { + final int mask = SerializerFeature.UseISO8601DateFormat.getMask(); + LocalDateTime dateTime = (LocalDateTime) object; + String format = serializer.getDateFormatPattern(); + + if (format == null) { + if ((features & mask) != 0 || serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) { + format = formatter_iso8601_pattern; + } else if (serializer.isEnabled(SerializerFeature.WriteDateUseDateFormat)) { + format = JSON.DEFFAULT_DATE_FORMAT; + } else { + int millis = dateTime.getMillisOfSecond(); + if (millis == 0) { + format = formatter_iso8601_pattern_23; + } else { + format = formatter_iso8601_pattern_29; + } + } + } + + if (format != null) { + write(out, dateTime, format); + } else { + out.writeLong(dateTime.toDateTime(DateTimeZone.forTimeZone(JSON.defaultTimeZone)).toInstant().getMillis()); + } + } else { + out.writeString(object.toString()); + } + } + } + + public void write(JSONSerializer serializer, Object object, BeanContext context) throws IOException { + SerializeWriter out = serializer.out; + String format = context.getFormat(); + write(out, (ReadablePartial) object, format); + } + + private void write(SerializeWriter out, ReadablePartial object, String format) { + DateTimeFormatter formatter; + if (format.equals(formatter_iso8601_pattern)) { + formatter = formatter_iso8601; + } else { + formatter = DateTimeFormat.forPattern(format); + } + + String text = formatter.print(object); + out.writeString(text); + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/LabelFilter.java b/src/main/java/com/alibaba/fastjson/serializer/LabelFilter.java index 5dd4d58d3d..744eeb416f 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/LabelFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/LabelFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/Labels.java b/src/main/java/com/alibaba/fastjson/serializer/Labels.java index 669974b5dd..c149512a59 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/Labels.java +++ b/src/main/java/com/alibaba/fastjson/serializer/Labels.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public DefaultLabelFilter(String[] includes, String[] excludes){ public boolean apply(String label) { if (excludes != null) { - return Arrays.binarySearch(excludes, label) == -1; + return Arrays.binarySearch(excludes, label) < 0; } return includes != null // diff --git a/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java index aa758ac1a6..8938de42f5 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,7 @@ import com.alibaba.fastjson.util.TypeUtils; import java.io.IOException; -import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.lang.reflect.WildcardType; import java.util.List; /** diff --git a/src/main/java/com/alibaba/fastjson/serializer/LongCodec.java b/src/main/java/com/alibaba/fastjson/serializer/LongCodec.java old mode 100755 new mode 100644 index 1d2365e2a6..0a509c489f --- a/src/main/java/com/alibaba/fastjson/serializer/LongCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/LongCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import java.io.IOException; import java.lang.reflect.Type; -import java.util.concurrent.atomic.AtomicInteger; +import java.math.BigDecimal; import java.util.concurrent.atomic.AtomicLong; import com.alibaba.fastjson.JSONException; @@ -64,6 +64,10 @@ public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) long longValue = lexer.longValue(); lexer.nextToken(JSONToken.COMMA); longObject = Long.valueOf(longValue); + } else if (token == JSONToken.LITERAL_FLOAT) { + BigDecimal number = lexer.decimalValue(); + longObject = TypeUtils.longValue(number); + lexer.nextToken(JSONToken.COMMA); } else { if (token == JSONToken.LBRACE) { JSONObject jsonObject = new JSONObject(true); diff --git a/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java old mode 100755 new mode 100644 index f8aded9c32..ef6d73d7a1 --- a/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -197,18 +197,18 @@ public void write(JSONSerializer serializer { if (entryKey == null || entryKey instanceof String) { - value = this.processValue(serializer, null, object, (String) entryKey, value); + value = this.processValue(serializer, null, object, (String) entryKey, value, features); } else { boolean objectOrArray = entryKey instanceof Map || entryKey instanceof Collection; if (!objectOrArray) { String strKey = JSON.toJSONString(entryKey); - value = this.processValue(serializer, null, object, strKey, value); + value = this.processValue(serializer, null, object, strKey, value, features); } } } if (value == null) { - if (!out.isEnabled(SerializerFeature.WRITE_MAP_NULL_FEATURES)) { + if (!SerializerFeature.isEnabled(out.features, features, SerializerFeature.WriteMapNullValue)) { continue; } } @@ -229,7 +229,8 @@ public void write(JSONSerializer serializer out.write(','); } - if (out.isEnabled(NON_STRINGKEY_AS_STRING) && !(entryKey instanceof Enum)) { + if ((out.isEnabled(NON_STRINGKEY_AS_STRING) || SerializerFeature.isEnabled(features, SerializerFeature.WriteNonStringKeyAsString)) + && !(entryKey instanceof Enum)) { String strEntryKey = JSON.toJSONString(entryKey); serializer.write(strEntryKey); } else { diff --git a/src/main/java/com/alibaba/fastjson/serializer/MiscCodec.java b/src/main/java/com/alibaba/fastjson/serializer/MiscCodec.java old mode 100755 new mode 100644 index e1ff2f713d..6735274c74 --- a/src/main/java/com/alibaba/fastjson/serializer/MiscCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/MiscCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.io.File; import java.io.IOException; +import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; @@ -41,6 +42,13 @@ import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import com.alibaba.fastjson.util.IOUtils; import com.alibaba.fastjson.util.TypeUtils; +import org.w3c.dom.Node; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; /** * @author wenshao[szujobs@hotmail.com] @@ -149,6 +157,8 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty } else if (object.getClass().getName().equals("net.sf.json.JSONNull")) { out.writeNull(); return; + } else if (object instanceof org.w3c.dom.Node) { + strVal = toString((Node) object); } else { throw new JSONException("not support class : " + objClass); } @@ -156,6 +166,20 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty out.writeString(strVal); } + private static String toString(org.w3c.dom.Node node) { + try { + TransformerFactory transFactory = TransformerFactory.newInstance(); + Transformer transformer = transFactory.newTransformer(); + DOMSource domSource = new DOMSource(node); + + StringWriter out = new StringWriter(); + transformer.transform(domSource, new StreamResult(out)); + return out.toString(); + } catch (TransformerException e) { + throw new JSONException("xml node to string error", e); + } + } + protected void writeIterator(JSONSerializer serializer, SerializeWriter out, Iterator it) { int i = 0; out.write('['); @@ -332,7 +356,7 @@ public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) } if (clazz == Class.class) { - return (T) TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader()); + return (T) TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader(), false); } if (clazz == Charset.class) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java b/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java old mode 100755 new mode 100644 index c530997fb3..265e082794 --- a/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectArrayCodec.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectArrayCodec.java old mode 100755 new mode 100644 index 4a09a89cbd..bc63e95c54 --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectArrayCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ObjectArrayCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,7 +75,7 @@ public final void write(JSONSerializer serializer, Object object, Object fieldNa out.write(','); serializer.println(); } - serializer.write(array[i]); + serializer.writeWithFieldName(array[i], Integer.valueOf(i)); } serializer.decrementIdent(); serializer.println(); @@ -95,12 +95,12 @@ public final void write(JSONSerializer serializer, Object object, Object fieldNa Class clazz = item.getClass(); if (clazz == preClazz) { - preWriter.write(serializer, item, null, null, 0); + preWriter.write(serializer, item, i, null, 0); } else { preClazz = clazz; preWriter = serializer.getObjectWriter(clazz); - preWriter.write(serializer, item, null, null, 0); + preWriter.write(serializer, item, i, null, 0); } } out.append(','); diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java old mode 100755 new mode 100644 index 0d4f3b2967..97af830a0a --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/PascalNameFilter.java b/src/main/java/com/alibaba/fastjson/serializer/PascalNameFilter.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/serializer/PrimitiveArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/PrimitiveArraySerializer.java old mode 100755 new mode 100644 index a93ae97c3a..9d08875e00 --- a/src/main/java/com/alibaba/fastjson/serializer/PrimitiveArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/PrimitiveArraySerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java b/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java old mode 100755 new mode 100644 index 8b5941d65c..d920fccf43 --- a/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/PropertyPreFilter.java b/src/main/java/com/alibaba/fastjson/serializer/PropertyPreFilter.java old mode 100755 new mode 100644 index 9e875d7713..c4019f8df3 --- a/src/main/java/com/alibaba/fastjson/serializer/PropertyPreFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/PropertyPreFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/ReferenceCodec.java b/src/main/java/com/alibaba/fastjson/serializer/ReferenceCodec.java index 3e241d0e9c..2e71967cb6 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/ReferenceCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ReferenceCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerialContext.java b/src/main/java/com/alibaba/fastjson/serializer/SerialContext.java old mode 100755 new mode 100644 index 2814f948d8..a65a9fe88a --- a/src/main/java/com/alibaba/fastjson/serializer/SerialContext.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerialContext.java @@ -18,12 +18,61 @@ public String toString() { if (parent == null) { return "$"; } else { - if (fieldName instanceof Integer) { - return parent.toString() + "[" + fieldName + "]"; + StringBuilder buf = new StringBuilder(); + toString(buf); + return buf.toString(); + } + } + + protected void toString(StringBuilder buf) { + if (parent == null) { + buf.append('$'); + } else { + parent.toString(buf); + if (fieldName == null) { + buf.append(".null"); + } else if (fieldName instanceof Integer) { + buf.append('['); + buf.append(((Integer)fieldName).intValue()); + buf.append(']'); } else { - return parent.toString() + "." + fieldName; - } + buf.append('.'); + String fieldName = this.fieldName.toString(); + boolean special = false; + for (int i = 0; i < fieldName.length(); ++i) { + char ch = fieldName.charAt(i); + if ((ch >= '0' && ch <='9') || (ch >= 'A' && ch <='Z') || (ch >= 'a' && ch <='z') || ch > 128) { + continue; + } + special = true; + break; + } + + if (special) { + for (int i = 0; i < fieldName.length(); ++i) { + char ch = fieldName.charAt(i); + if (ch == '\\') { + buf.append('\\'); + buf.append('\\'); + buf.append('\\'); + } else if ((ch >= '0' && ch <='9') || (ch >= 'A' && ch <='Z') || (ch >= 'a' && ch <='z') || ch > 128) { + buf.append(ch); + continue; + } else if(ch == '\"'){ + buf.append('\\'); + buf.append('\\'); + buf.append('\\'); + } else { + buf.append('\\'); + buf.append('\\'); + } + buf.append(ch); + } + } else { + buf.append(fieldName); + } + } } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java index b3a542d824..8ca467442a 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.parser.deserializer.Jdk8DateCodec; import com.alibaba.fastjson.parser.deserializer.OptionalCodec; +import com.alibaba.fastjson.spi.Module; +import com.alibaba.fastjson.support.moneta.MonetaCodec; import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer; import com.alibaba.fastjson.util.*; import com.alibaba.fastjson.util.IdentityHashMap; @@ -36,7 +38,6 @@ import java.math.BigInteger; import java.net.*; import java.nio.charset.Charset; -import java.sql.Clob; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.atomic.*; @@ -56,7 +57,8 @@ public class SerializeConfig { private static boolean oracleJdbcError = false; private static boolean springfoxError = false; private static boolean guavaError = false; - private static boolean jsonnullError = false; + + private static boolean jodaError = false; private boolean asm = !ASMUtils.IS_ANDROID; private ASMSerializerFactory asmFactory; @@ -64,9 +66,18 @@ public class SerializeConfig { public PropertyNamingStrategy propertyNamingStrategy; private final IdentityHashMap serializers; + private final IdentityHashMap> mixInSerializers; private final boolean fieldBased; - + + private long[] denyClasses = + { + 4165360493669296979L, + 4446674157046724083L + }; + + private List modules = new ArrayList(); + public String getTypeKey() { return typeKey; } @@ -93,6 +104,12 @@ private final JavaBeanSerializer createASMSerializer(SerializeBeanInfo beanInfo) } public final ObjectSerializer createJavaBeanSerializer(Class clazz) { + String className = clazz.getName(); + long hashCode64 = TypeUtils.fnv1a_64(className); + if (Arrays.binarySearch(denyClasses, hashCode64) >= 0) { + throw new JSONException("not support class : " + className); + } + SerializeBeanInfo beanInfo = TypeUtils.buildBeanInfo(clazz, null, propertyNamingStrategy, fieldBased); if (beanInfo.fields.length == 0 && Iterable.class.isAssignableFrom(clazz)) { return MiscCodec.instance; @@ -123,12 +140,22 @@ public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) { asm = false; } - for (SerializerFeature feature : jsonType.serialzeFeatures()) { - if (SerializerFeature.WriteNonStringValueAsString == feature // - || SerializerFeature.WriteEnumUsingToString == feature // - || SerializerFeature.NotWriteDefaultValue == feature) { + if (asm) { + for (SerializerFeature feature : jsonType.serialzeFeatures()) { + if (SerializerFeature.WriteNonStringValueAsString == feature // + || SerializerFeature.WriteEnumUsingToString == feature // + || SerializerFeature.NotWriteDefaultValue == feature + || SerializerFeature.BrowserCompatible == feature) { + asm = false; + break; + } + } + } + + if (asm) { + final Class[] filterClasses = jsonType.serialzeFilters(); + if (filterClasses.length != 0) { asm = false; - break; } } } @@ -167,6 +194,12 @@ public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) { break; } + if (fieldInfo.fieldClass.isEnum() + && get(fieldInfo.fieldClass) != EnumSerializer.instance) { + asm = false; + break; + } + JSONField annotation = fieldInfo.getAnnotation(); if (annotation == null) { @@ -196,6 +229,7 @@ public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) { if (SerializerFeature.WriteNonStringValueAsString == feature // || SerializerFeature.WriteEnumUsingToString == feature // || SerializerFeature.NotWriteDefaultValue == feature + || SerializerFeature.BrowserCompatible == feature || SerializerFeature.WriteClassName == feature) { asm = false; break; @@ -203,9 +237,13 @@ public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) { } if (TypeUtils.isAnnotationPresentOneToMany(method) || TypeUtils.isAnnotationPresentManyToMany(method)) { - asm = true; + asm = false; break; } + if (annotation.defaultValue() != null && !"".equals(annotation.defaultValue())) { + asm = false; + break; + } } } @@ -220,10 +258,14 @@ public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) { } catch (ClassFormatError e) { // skip } catch (ClassCastException e) { - // skip + // skip + } catch (OutOfMemoryError e) { + if (e.getMessage().indexOf("Metaspace") != -1) { + throw e; + } + // skip } catch (Throwable e) { - throw new JSONException("create asm serializer error, class " - + clazz, e); + throw new JSONException("create asm serializer error, verson " + JSON.VERSION + ", class " + clazz, e); } } @@ -260,7 +302,7 @@ public SerializeConfig(int tableSize) { public SerializeConfig(int tableSize, boolean fieldBase) { this.fieldBased = fieldBase; serializers = new IdentityHashMap(tableSize); - + this.mixInSerializers = new IdentityHashMap>(16); try { if (asm) { asmFactory = new ASMSerializerFactory(); @@ -269,61 +311,65 @@ public SerializeConfig(int tableSize, boolean fieldBase) { asm = false; } - put(Boolean.class, BooleanCodec.instance); - put(Character.class, CharacterCodec.instance); - put(Byte.class, IntegerCodec.instance); - put(Short.class, IntegerCodec.instance); - put(Integer.class, IntegerCodec.instance); - put(Long.class, LongCodec.instance); - put(Float.class, FloatCodec.instance); - put(Double.class, DoubleSerializer.instance); - put(BigDecimal.class, BigDecimalCodec.instance); - put(BigInteger.class, BigIntegerCodec.instance); - put(String.class, StringCodec.instance); - put(byte[].class, PrimitiveArraySerializer.instance); - put(short[].class, PrimitiveArraySerializer.instance); - put(int[].class, PrimitiveArraySerializer.instance); - put(long[].class, PrimitiveArraySerializer.instance); - put(float[].class, PrimitiveArraySerializer.instance); - put(double[].class, PrimitiveArraySerializer.instance); - put(boolean[].class, PrimitiveArraySerializer.instance); - put(char[].class, PrimitiveArraySerializer.instance); - put(Object[].class, ObjectArrayCodec.instance); - put(Class.class, MiscCodec.instance); - - put(SimpleDateFormat.class, MiscCodec.instance); - put(Currency.class, new MiscCodec()); - put(TimeZone.class, MiscCodec.instance); - put(InetAddress.class, MiscCodec.instance); - put(Inet4Address.class, MiscCodec.instance); - put(Inet6Address.class, MiscCodec.instance); - put(InetSocketAddress.class, MiscCodec.instance); - put(File.class, MiscCodec.instance); - put(Appendable.class, AppendableSerializer.instance); - put(StringBuffer.class, AppendableSerializer.instance); - put(StringBuilder.class, AppendableSerializer.instance); - put(Charset.class, ToStringSerializer.instance); - put(Pattern.class, ToStringSerializer.instance); - put(Locale.class, ToStringSerializer.instance); - put(URI.class, ToStringSerializer.instance); - put(URL.class, ToStringSerializer.instance); - put(UUID.class, ToStringSerializer.instance); - - // atomic - put(AtomicBoolean.class, AtomicCodec.instance); - put(AtomicInteger.class, AtomicCodec.instance); - put(AtomicLong.class, AtomicCodec.instance); - put(AtomicReference.class, ReferenceCodec.instance); - put(AtomicIntegerArray.class, AtomicCodec.instance); - put(AtomicLongArray.class, AtomicCodec.instance); - - put(WeakReference.class, ReferenceCodec.instance); - put(SoftReference.class, ReferenceCodec.instance); + initSerializers(); + } + + private void initSerializers() { + put(Boolean.class, BooleanCodec.instance); + put(Character.class, CharacterCodec.instance); + put(Byte.class, IntegerCodec.instance); + put(Short.class, IntegerCodec.instance); + put(Integer.class, IntegerCodec.instance); + put(Long.class, LongCodec.instance); + put(Float.class, FloatCodec.instance); + put(Double.class, DoubleSerializer.instance); + put(BigDecimal.class, BigDecimalCodec.instance); + put(BigInteger.class, BigIntegerCodec.instance); + put(String.class, StringCodec.instance); + put(byte[].class, PrimitiveArraySerializer.instance); + put(short[].class, PrimitiveArraySerializer.instance); + put(int[].class, PrimitiveArraySerializer.instance); + put(long[].class, PrimitiveArraySerializer.instance); + put(float[].class, PrimitiveArraySerializer.instance); + put(double[].class, PrimitiveArraySerializer.instance); + put(boolean[].class, PrimitiveArraySerializer.instance); + put(char[].class, PrimitiveArraySerializer.instance); + put(Object[].class, ObjectArrayCodec.instance); + put(Class.class, MiscCodec.instance); + + put(SimpleDateFormat.class, MiscCodec.instance); + put(Currency.class, new MiscCodec()); + put(TimeZone.class, MiscCodec.instance); + put(InetAddress.class, MiscCodec.instance); + put(Inet4Address.class, MiscCodec.instance); + put(Inet6Address.class, MiscCodec.instance); + put(InetSocketAddress.class, MiscCodec.instance); + put(File.class, MiscCodec.instance); + put(Appendable.class, AppendableSerializer.instance); + put(StringBuffer.class, AppendableSerializer.instance); + put(StringBuilder.class, AppendableSerializer.instance); + put(Charset.class, ToStringSerializer.instance); + put(Pattern.class, ToStringSerializer.instance); + put(Locale.class, ToStringSerializer.instance); + put(URI.class, ToStringSerializer.instance); + put(URL.class, ToStringSerializer.instance); + put(UUID.class, ToStringSerializer.instance); + + // atomic + put(AtomicBoolean.class, AtomicCodec.instance); + put(AtomicInteger.class, AtomicCodec.instance); + put(AtomicLong.class, AtomicCodec.instance); + put(AtomicReference.class, ReferenceCodec.instance); + put(AtomicIntegerArray.class, AtomicCodec.instance); + put(AtomicLongArray.class, AtomicCodec.instance); + + put(WeakReference.class, ReferenceCodec.instance); + put(SoftReference.class, ReferenceCodec.instance); put(LinkedList.class, CollectionCodec.instance); - } - - /** + } + + /** * add class level serialize filter * @since 1.2.10 */ @@ -394,29 +440,31 @@ public ObjectSerializer getObjectWriter(Class clazz) { return getObjectWriter(clazz, true); } - private ObjectSerializer getObjectWriter(Class clazz, boolean create) { - ObjectSerializer writer = serializers.get(clazz); + public ObjectSerializer getObjectWriter(Class clazz, boolean create) { + ObjectSerializer writer = get(clazz); - if (writer == null) { - try { - final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { - if (!(o instanceof AutowiredObjectSerializer)) { - continue; - } + if (writer != null) { + return writer; + } - AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; - for (Type forType : autowired.getAutowiredFor()) { - put(forType, autowired); - } + try { + final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { + if (!(o instanceof AutowiredObjectSerializer)) { + continue; } - } catch (ClassCastException ex) { - // skip - } - writer = serializers.get(clazz); + AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; + for (Type forType : autowired.getAutowiredFor()) { + put(forType, autowired); + } + } + } catch (ClassCastException ex) { + // skip } + writer = get(clazz); + if (writer == null) { final ClassLoader classLoader = JSON.class.getClassLoader(); if (classLoader != Thread.currentThread().getContextClassLoader()) { @@ -436,7 +484,15 @@ private ObjectSerializer getObjectWriter(Class clazz, boolean create) { // skip } - writer = serializers.get(clazz); + writer = get(clazz); + } + } + + for (Module module : modules) { + writer = module.createSerializer(this, clazz); + if (writer != null) { + put(clazz, writer); + return writer; } } @@ -459,18 +515,46 @@ private ObjectSerializer getObjectWriter(Class clazz, boolean create) { } else if (JSONStreamAware.class.isAssignableFrom(clazz)) { put(clazz, writer = MiscCodec.instance); } else if (clazz.isEnum()) { - JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class); + Class mixedInType = (Class) JSON.getMixInAnnotations(clazz); + + JSONType jsonType; + if (mixedInType != null) { + jsonType = TypeUtils.getAnnotation(mixedInType, JSONType.class); + } else { + jsonType = TypeUtils.getAnnotation(clazz, JSONType.class); + } + if (jsonType != null && jsonType.serializeEnumAsJavaBean()) { put(clazz, writer = createJavaBeanSerializer(clazz)); } else { - put(clazz, writer = EnumSerializer.instance); + Member member = null; + if (mixedInType != null) { + Member mixedInMember = getEnumValueField(mixedInType); + if (mixedInMember != null) { + try { + if (mixedInMember instanceof Method) { + Method mixedInMethod = (Method) mixedInMember; + member = clazz.getMethod(mixedInMethod.getName(), mixedInMethod.getParameterTypes()); + } + } catch (Exception e) { + // skip + } + } + } else { + member = getEnumValueField(clazz); + } + if (member != null) { + put(clazz, writer = new EnumSerializer(member)); + } else { + put(clazz, writer = getEnumSerializer()); + } } } else if ((superClass = clazz.getSuperclass()) != null && superClass.isEnum()) { JSONType jsonType = TypeUtils.getAnnotation(superClass, JSONType.class); if (jsonType != null && jsonType.serializeEnumAsJavaBean()) { put(clazz, writer = createJavaBeanSerializer(clazz)); } else { - put(clazz, writer = EnumSerializer.instance); + put(clazz, writer = getEnumSerializer()); } } else if (clazz.isArray()) { Class componentType = clazz.getComponentType(); @@ -491,12 +575,14 @@ private ObjectSerializer getObjectWriter(Class clazz, boolean create) { } else if (Calendar.class.isAssignableFrom(clazz) // || XMLGregorianCalendar.class.isAssignableFrom(clazz)) { put(clazz, writer = CalendarCodec.instance); - } else if (Clob.class.isAssignableFrom(clazz)) { - put(clazz, writer = ClobSeriliazer.instance); + } else if (TypeUtils.isClob(clazz)) { + put(clazz, writer = ClobSerializer.instance); } else if (TypeUtils.isPath(clazz)) { put(clazz, writer = ToStringSerializer.instance); } else if (Iterator.class.isAssignableFrom(clazz)) { put(clazz, writer = MiscCodec.instance); + } else if (org.w3c.dom.Node.class.isAssignableFrom(clazz)) { + put(clazz, writer = MiscCodec.instance); } else { if (className.startsWith("java.awt.") // && AwtCodec.support(clazz) // @@ -622,6 +708,7 @@ private ObjectSerializer getObjectWriter(Class clazz, boolean create) { String[] names = new String[] { "com.google.common.collect.HashMultimap", "com.google.common.collect.LinkedListMultimap", + "com.google.common.collect.LinkedHashMultimap", "com.google.common.collect.ArrayListMultimap", "com.google.common.collect.TreeMultimap" }; @@ -638,18 +725,62 @@ private ObjectSerializer getObjectWriter(Class clazz, boolean create) { } } - if ((!jsonnullError) && className.equals("net.sf.json.JSONNull")) { + if (className.equals("net.sf.json.JSONNull")) { + put(clazz, writer = MiscCodec.instance); + return writer; + } + + if (className.equals("org.json.JSONObject")) { + put(clazz, writer = JSONObjectCodec.instance); + return writer; + } + + if ((!jodaError) && className.startsWith("org.joda.")) { try { - put(Class.forName("net.sf.json.JSONNull"), writer = MiscCodec.instance); - return writer; + String[] names = new String[] { + "org.joda.time.LocalDate", + "org.joda.time.LocalDateTime", + "org.joda.time.LocalTime", + "org.joda.time.Instant", + "org.joda.time.DateTime", + "org.joda.time.Period", + "org.joda.time.Duration", + "org.joda.time.DateTimeZone", + "org.joda.time.UTCDateTimeZone", + "org.joda.time.tz.CachedDateTimeZone", + "org.joda.time.tz.FixedDateTimeZone", + }; + + for (String name : names) { + if (name.equals(className)) { + put(Class.forName(name), writer = JodaCodec.instance); + return writer; + } + } } catch (ClassNotFoundException e) { // skip - jsonnullError = true; + jodaError = true; } } + if ("java.nio.HeapByteBuffer".equals(className)) { + put(clazz, writer = ByteBufferCodec.instance); + return writer; + } + + if ("org.javamoney.moneta.Money".equals(className)) { + put(clazz, writer = MonetaCodec.instance); + return writer; + } + + if ("com.google.protobuf.Descriptors$FieldDescriptor".equals(className)) { + put(clazz, writer = ToStringSerializer.instance); + return writer; + } + Class[] interfaces = clazz.getInterfaces(); if (interfaces.length == 1 && interfaces[0].isAnnotation()) { + put(clazz, AnnotationSerializer.instance); return AnnotationSerializer.instance; } @@ -693,23 +824,85 @@ private ObjectSerializer getObjectWriter(Class clazz, boolean create) { } if (writer == null) { - writer = serializers.get(clazz); + writer = get(clazz); } } return writer; } + + private static Member getEnumValueField(Class clazz) { + Member member = null; + + Method[] methods = clazz.getMethods(); + + for (Method method : methods) { + if (method.getReturnType() == Void.class) { + continue; + } + JSONField jsonField = method.getAnnotation(JSONField.class); + if (jsonField != null) { + if (member != null) { + return null; + } + + member = method; + } + } + + for (Field field : clazz.getFields()) { + JSONField jsonField = field.getAnnotation(JSONField.class); + + if (jsonField != null) { + if (member != null) { + return null; + } + + member = field; + } + } + + return member; + } + + /** + * 可以通过重写这个方法,定义自己的枚举序列化实现 + * @return 返回一个枚举的反序列化实现 + * @author zhu.xiaojie + * @time 2020-4-5 + */ + protected ObjectSerializer getEnumSerializer(){ + return EnumSerializer.instance; + } - public final ObjectSerializer get(Type key) { - return this.serializers.get(key); - } + public final ObjectSerializer get(Type type) { + Type mixin = JSON.getMixInAnnotations(type); + if (null == mixin) { + return this.serializers.get(type); + } + IdentityHashMap mixInClasses = this.mixInSerializers.get(type); + if (mixInClasses == null) { + return null; + } + return mixInClasses.get(mixin); + } public boolean put(Object type, Object value) { return put((Type)type, (ObjectSerializer)value); } - public boolean put(Type type, ObjectSerializer value) { + public boolean put(Type type, ObjectSerializer value) { + Type mixin = JSON.getMixInAnnotations(type); + if (mixin != null) { + IdentityHashMap mixInClasses = this.mixInSerializers.get(type); + if (mixInClasses == null) { + //多线程下可能会重复创建,但不影响正确性 + mixInClasses = new IdentityHashMap(4); + mixInSerializers.put(type, mixInClasses); + } + return mixInClasses.put(mixin, value); + } return this.serializers.put(type, value); - } + } /** * 1.2.24 @@ -728,4 +921,13 @@ public void configEnumAsJavaBean(Class... enumClasses) { public void setPropertyNamingStrategy(PropertyNamingStrategy propertyNamingStrategy) { this.propertyNamingStrategy = propertyNamingStrategy; } + + public void clearSerializers() { + this.serializers.clear(); + this.initSerializers(); + } + + public void register(Module module) { + this.modules.add(module); + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeFilter.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeFilter.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeFilterable.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeFilterable.java index efe60a5aee..007c443964 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializeFilterable.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeFilterable.java @@ -1,7 +1,6 @@ package com.alibaba.fastjson.serializer; import java.text.DecimalFormat; -import java.text.NumberFormat; import java.util.ArrayList; import java.util.List; @@ -194,15 +193,24 @@ protected String processKey(JSONSerializer jsonBeanDeser, // return key; } + + protected Object processValue(JSONSerializer jsonBeanDeser, // + BeanContext beanContext, + Object object, // + String key, // + Object propertyValue) { + return processValue(jsonBeanDeser, beanContext, object, key, propertyValue, 0); + } protected Object processValue(JSONSerializer jsonBeanDeser, // BeanContext beanContext, Object object, // String key, // - Object propertyValue) { + Object propertyValue, // + int features) { if (propertyValue != null) { - if ((jsonBeanDeser.out.writeNonStringValueAsString // + if ((SerializerFeature.isEnabled(jsonBeanDeser.out.features, features, SerializerFeature.WriteNonStringValueAsString) // || (beanContext != null && (beanContext.getFeatures() & SerializerFeature.WriteNonStringValueAsString.mask) != 0)) && (propertyValue instanceof Number || propertyValue instanceof Boolean)) { String format = null; diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java old mode 100755 new mode 100644 index b57ac5e6f0..9d9e362bba --- a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,13 +18,14 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.util.IOUtils; +import com.alibaba.fastjson.util.RyuDouble; +import com.alibaba.fastjson.util.RyuFloat; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; import java.math.BigDecimal; import java.nio.charset.Charset; -import java.util.Arrays; import java.util.List; import static com.alibaba.fastjson.util.IOUtils.replaceChars; @@ -33,8 +34,25 @@ * @author wenshao[szujobs@hotmail.com] */ public final class SerializeWriter extends Writer { - private final static ThreadLocal bufLocal = new ThreadLocal(); - private final static ThreadLocal bytesBufLocal = new ThreadLocal(); + private final static ThreadLocal bufLocal = new ThreadLocal(); + private final static ThreadLocal bytesBufLocal = new ThreadLocal(); + private static final char[] VALUE_TRUE = ":true".toCharArray(); + private static final char[] VALUE_FALSE = ":false".toCharArray(); + private static int BUFFER_THRESHOLD = 1024 * 128; + + static { + try { + String prop = IOUtils.getStringProperty("fastjson.serializer_buffer_threshold"); + if (prop != null && prop.length() > 0) { + int serializer_buffer_threshold = Integer.parseInt(prop); + if (serializer_buffer_threshold >= 64 && serializer_buffer_threshold <= 1024 * 64) { + BUFFER_THRESHOLD = serializer_buffer_threshold * 1024; + } + } + } catch (Throwable error) { + // skip + } + } protected char buf[]; @@ -289,6 +307,14 @@ public void expandCapacity(int minimumCapacity) { } char newValue[] = new char[newCapacity]; System.arraycopy(buf, 0, newValue, 0, count); + + if (buf.length < BUFFER_THRESHOLD) { + char[] charsLocal = bufLocal.get(); + if (charsLocal == null || charsLocal.length < buf.length) { + bufLocal.set(buf); + } + } + buf = newValue; } @@ -428,6 +454,7 @@ private int encodeToUTF8(OutputStream out) throws IOException { bytes = new byte[1024 * 8]; bytesBufLocal.set(bytes); } + byte[] bytesLocal = bytes; if (bytes.length < bytesLength) { bytes = new byte[bytesLength]; @@ -435,6 +462,11 @@ private int encodeToUTF8(OutputStream out) throws IOException { int position = IOUtils.encodeUTF8(buf, 0, count, bytes); out.write(bytes, 0, position); + + if (bytes != bytesLocal && bytes.length <= BUFFER_THRESHOLD) { + bytesBufLocal.set(bytes); + } + return position; } @@ -446,6 +478,7 @@ private byte[] encodeToUTF8Bytes() { bytes = new byte[1024 * 8]; bytesBufLocal.set(bytes); } + byte[] bytesLocal = bytes; if (bytes.length < bytesLength) { bytes = new byte[bytesLength]; @@ -454,6 +487,11 @@ private byte[] encodeToUTF8Bytes() { int position = IOUtils.encodeUTF8(buf, 0, count, bytes); byte[] copy = new byte[position]; System.arraycopy(bytes, 0, copy, 0, position); + + if (bytes != bytesLocal && bytes.length <= BUFFER_THRESHOLD) { + bytesBufLocal.set(bytes); + } + return copy; } @@ -473,7 +511,7 @@ public void close() { if (writer != null && count > 0) { flush(); } - if (buf.length <= 1024 * 128) { + if (buf.length <= BUFFER_THRESHOLD) { bufLocal.set(buf); } @@ -530,6 +568,7 @@ public void writeByteArray(byte[] bytes) { final char[] CA = IOUtils.CA; + // base64 algorithm author Mikael Grev int eLen = (bytesLen / 3) * 3; // Length of even 24-bits. int charsLen = ((bytesLen - 1) / 3 + 1) << 2; // base64 character count // char[] chars = new char[charsLen]; @@ -601,30 +640,6 @@ public void writeByteArray(byte[] bytes) { public void writeHex(byte[] bytes) { int newcount = count + bytes.length * 2 + 3; if (newcount > buf.length) { - if (writer != null) { - char[] chars = new char[bytes.length + 3]; - int pos = 0; - chars[pos++] = 'x'; - chars[pos++] = '\''; - - for (int i = 0; i < bytes.length; ++i) { - byte b = bytes[i]; - - int a = b & 0xFF; - int b0 = a >> 4; - int b1 = a & 0xf; - - chars[pos++] = (char) (b0 + (b0 < 10 ? 48 : 55)); - chars[pos++] = (char) (b1 + (b1 < 10 ? 48 : 55)); - } - chars[pos++] = '\''; - try { - writer.write(chars); - } catch (IOException ex) { - throw new JSONException("writeBytes error.", ex); - } - return; - } expandCapacity(newcount); } @@ -645,38 +660,61 @@ public void writeHex(byte[] bytes) { } public void writeFloat(float value, boolean checkWriteClassName) { - if (Float.isNaN(value) // - || Float.isInfinite(value)) { + if (value != value || value == Float.POSITIVE_INFINITY || value == Float.NEGATIVE_INFINITY) { writeNull(); } else { - String floatText= Float.toString(value); - if (isEnabled(SerializerFeature.WriteNullNumberAsZero) && floatText.endsWith(".0")) { - floatText = floatText.substring(0, floatText.length() - 2); + int newcount = count + 15; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + String str = RyuFloat.toString(value); + write(str, 0, str.length()); + + if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) { + write('F'); + } + return; + } } - write(floatText); - + + int len = RyuFloat.toString(value, buf, count); + count += len; + if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) { write('F'); } } } - public void writeDouble(double doubleValue, boolean checkWriteClassName) { - if (Double.isNaN(doubleValue) // - || Double.isInfinite(doubleValue)) { + public void writeDouble(double value, boolean checkWriteClassName) { + if (Double.isNaN(value) + || Double.isInfinite(value)) { writeNull(); - } else { - String doubleText = Double.toString(doubleValue); - if (isEnabled(SerializerFeature.WriteNullNumberAsZero) && doubleText.endsWith(".0")) { - doubleText = doubleText.substring(0, doubleText.length() - 2); - } - - write(doubleText); + return; + } - if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) { - write('D'); + int newcount = count + 24; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + String str = RyuDouble.toString(value); + write(str, 0, str.length()); + + if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) { + write('D'); + } + return; } } + + int len = RyuDouble.toString(value, buf, count); + count += len; + + if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) { + write('D'); + } } public void writeEnum(Enum value) { @@ -689,7 +727,7 @@ public void writeEnum(Enum value) { if (writeEnumUsingName && !writeEnumUsingToString) { strVal = value.name(); } else if (writeEnumUsingToString) { - strVal = value.toString();; + strVal = value.toString(); } if (strVal != null) { @@ -702,14 +740,25 @@ public void writeEnum(Enum value) { } } + /** + * @deprecated + */ + public void writeLongAndChar(long i, char c) throws IOException { + writeLong(i); + write(c); + } + public void writeLong(long i) { boolean needQuotationMark = isEnabled(SerializerFeature.BrowserCompatible) // && (!isEnabled(SerializerFeature.WriteClassName)) // && (i > 9007199254740991L || i < -9007199254740991L); if (i == Long.MIN_VALUE) { - if (needQuotationMark) write("\"-9223372036854775808\""); - else write("-9223372036854775808"); + if (needQuotationMark) { + write("\"-9223372036854775808\""); + } else { + write("-9223372036854775808"); + } return; } @@ -759,6 +808,12 @@ public void writeNull(int beanFeatures , int feature) { writeNull(); return; } + if ((beanFeatures & SerializerFeature.WriteMapNullValue.mask) != 0 + && (beanFeatures & ~SerializerFeature.WriteMapNullValue.mask + & SerializerFeature.WRITE_MAP_NULL_FEATURES) == 0) { + writeNull(); + return; + } if (feature == SerializerFeature.WriteNullListAsEmpty.mask) { write("[]"); @@ -800,8 +855,8 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { write('\\'); write('u'); write(IOUtils.DIGITS[(ch >>> 12) & 15]); - write(IOUtils.DIGITS[(ch >>> 8) & 15]); - write(IOUtils.DIGITS[(ch >>> 4) & 15]); + write(IOUtils.DIGITS[(ch >>> 8 ) & 15]); + write(IOUtils.DIGITS[(ch >>> 4 ) & 15]); write(IOUtils.DIGITS[ch & 15]); continue; } @@ -826,7 +881,7 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { write('u'); write('0'); write('0'); - write(IOUtils.ASCII_CHARS[ch * 2]); + write(IOUtils.ASCII_CHARS[ch * 2 ]); write(IOUtils.ASCII_CHARS[ch * 2 + 1]); continue; } @@ -835,9 +890,9 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { write('\\'); write('u'); write(IOUtils.DIGITS[(ch >>> 12) & 15]); - write(IOUtils.DIGITS[(ch >>> 8) & 15]); - write(IOUtils.DIGITS[(ch >>> 4) & 15]); - write(IOUtils.DIGITS[ch & 15]); + write(IOUtils.DIGITS[(ch >>> 8 ) & 15]); + write(IOUtils.DIGITS[(ch >>> 4 ) & 15]); + write(IOUtils.DIGITS[ ch & 15]); continue; } } else { @@ -848,9 +903,9 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) { write('u'); write(IOUtils.DIGITS[ch >>> 12 & 15]); - write(IOUtils.DIGITS[ch >>> 8 & 15]); - write(IOUtils.DIGITS[ch >>> 4 & 15]); - write(IOUtils.DIGITS[ch & 15]); + write(IOUtils.DIGITS[ch >>> 8 & 15]); + write(IOUtils.DIGITS[ch >>> 4 & 15]); + write(IOUtils.DIGITS[ch & 15]); } else { write(IOUtils.replaceChars[ch]); } @@ -927,7 +982,8 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { || ch == '\f'// || ch == '\n' // || ch == '\r' // - || ch == '\t') { + || ch == '\t' + ) { System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); buf[i] = '\\'; buf[i + 1] = replaceChars[(int) ch]; @@ -937,7 +993,8 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { if (ch == '"' // || ch == '/' // - || ch == '\\') { + || ch == '\\' + ) { System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); buf[i] = '\\'; buf[i + 1] = ch; @@ -947,7 +1004,7 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { if (ch < 32) { System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1); - buf[i] = '\\'; + buf[i ] = '\\'; buf[i + 1] = 'u'; buf[i + 2] = '0'; buf[i + 3] = '0'; @@ -959,7 +1016,7 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { if (ch >= 127) { System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1); - buf[i] = '\\'; + buf[i ] = '\\'; buf[i + 1] = 'u'; buf[i + 2] = IOUtils.DIGITS[(ch >>> 12) & 15]; buf[i + 3] = IOUtils.DIGITS[(ch >>> 8) & 15]; @@ -979,10 +1036,10 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { return; } - int specialCount = 0; - int lastSpecialIndex = -1; + int specialCount = 0; + int lastSpecialIndex = -1; int firstSpecialIndex = -1; - char lastSpecial = '\0'; + char lastSpecial = '\0'; for (int i = start; i < end; ++i) { char ch = buf[i]; @@ -1038,24 +1095,28 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { int srcPos = lastSpecialIndex + 1; int destPos = lastSpecialIndex + 6; int LengthOfCopy = end - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); - buf[lastSpecialIndex] = '\\'; + buf[lastSpecialIndex ] = '\\'; buf[++lastSpecialIndex] = 'u'; buf[++lastSpecialIndex] = '2'; buf[++lastSpecialIndex] = '0'; buf[++lastSpecialIndex] = '2'; buf[++lastSpecialIndex] = '8'; + } else if (lastSpecial == '\u2029') { int srcPos = lastSpecialIndex + 1; int destPos = lastSpecialIndex + 6; int LengthOfCopy = end - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); - buf[lastSpecialIndex] = '\\'; + buf[lastSpecialIndex ] = '\\'; buf[++lastSpecialIndex] = 'u'; buf[++lastSpecialIndex] = '2'; buf[++lastSpecialIndex] = '0'; buf[++lastSpecialIndex] = '2'; buf[++lastSpecialIndex] = '9'; + } else if (lastSpecial == '(' || lastSpecial == ')' || lastSpecial == '<' || lastSpecial == '>') { int srcPos = lastSpecialIndex + 1; int destPos = lastSpecialIndex + 6; @@ -1107,9 +1168,9 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { buf[bufIndex++] = '\\'; buf[bufIndex++] = 'u'; buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; end += 5; } else if (ch < IOUtils.specicalFlags_doubleQuotes.length // && IOUtils.specicalFlags_doubleQuotes[ch] != 0 // @@ -1118,9 +1179,9 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) { buf[bufIndex++] = 'u'; buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; end += 5; } else { buf[bufIndex++] = replaceChars[(int) ch]; @@ -1131,9 +1192,9 @@ public void writeStringWithDoubleQuote(String text, final char seperator) { buf[bufIndex++] = '\\'; buf[bufIndex++] = 'u'; buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; end += 5; } else { buf[bufIndex++] = ch; @@ -1174,13 +1235,17 @@ public void writeStringWithDoubleQuote(char[] text, final char seperator) { char ch = text[i]; if (isEnabled(SerializerFeature.BrowserSecure)) { - if (ch == '(' || ch == ')' || ch == '<' || ch == '>') { + if (ch == '(' + || ch == ')' + || ch == '<' + || ch == '>' + ) { write('\\'); write('u'); write(IOUtils.DIGITS[(ch >>> 12) & 15]); - write(IOUtils.DIGITS[(ch >>> 8) & 15]); - write(IOUtils.DIGITS[(ch >>> 4) & 15]); - write(IOUtils.DIGITS[ch & 15]); + write(IOUtils.DIGITS[(ch >>> 8 ) & 15]); + write(IOUtils.DIGITS[(ch >>> 4 ) & 15]); + write(IOUtils.DIGITS[ch & 15]); continue; } } @@ -1204,7 +1269,7 @@ public void writeStringWithDoubleQuote(char[] text, final char seperator) { write('u'); write('0'); write('0'); - write(IOUtils.ASCII_CHARS[ch * 2]); + write(IOUtils.ASCII_CHARS[ch * 2 ]); write(IOUtils.ASCII_CHARS[ch * 2 + 1]); continue; } @@ -1213,9 +1278,9 @@ public void writeStringWithDoubleQuote(char[] text, final char seperator) { write('\\'); write('u'); write(IOUtils.DIGITS[(ch >>> 12) & 15]); - write(IOUtils.DIGITS[(ch >>> 8) & 15]); - write(IOUtils.DIGITS[(ch >>> 4) & 15]); - write(IOUtils.DIGITS[ch & 15]); + write(IOUtils.DIGITS[(ch >>> 8 ) & 15]); + write(IOUtils.DIGITS[(ch >>> 4 ) & 15]); + write(IOUtils.DIGITS[ch & 15]); continue; } } else { @@ -1226,9 +1291,9 @@ public void writeStringWithDoubleQuote(char[] text, final char seperator) { if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) { write('u'); write(IOUtils.DIGITS[ch >>> 12 & 15]); - write(IOUtils.DIGITS[ch >>> 8 & 15]); - write(IOUtils.DIGITS[ch >>> 4 & 15]); - write(IOUtils.DIGITS[ch & 15]); + write(IOUtils.DIGITS[ch >>> 8 & 15]); + write(IOUtils.DIGITS[ch >>> 4 & 15]); + write(IOUtils.DIGITS[ch & 15]); } else { write(IOUtils.replaceChars[ch]); } @@ -1418,7 +1483,7 @@ public void writeStringWithDoubleQuote(char[] text, final char seperator) { int destPos = lastSpecialIndex + 6; int LengthOfCopy = end - lastSpecialIndex - 1; System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); - buf[lastSpecialIndex] = '\\'; + buf[lastSpecialIndex ] = '\\'; buf[++lastSpecialIndex] = 'u'; buf[++lastSpecialIndex] = '2'; buf[++lastSpecialIndex] = '0'; @@ -1429,7 +1494,7 @@ public void writeStringWithDoubleQuote(char[] text, final char seperator) { int destPos = lastSpecialIndex + 6; int LengthOfCopy = end - lastSpecialIndex - 1; System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); - buf[lastSpecialIndex] = '\\'; + buf[lastSpecialIndex ] = '\\'; buf[++lastSpecialIndex] = 'u'; buf[++lastSpecialIndex] = '2'; buf[++lastSpecialIndex] = '0'; @@ -1663,9 +1728,9 @@ public void writeFieldValue(char seperator, String name, boolean value) { buf[nameEnd + 1] = keySeperator; if (value) { - System.arraycopy(":true".toCharArray(), 0, buf, nameEnd + 2, 5); + System.arraycopy(VALUE_TRUE, 0, buf, nameEnd + 2, 5); } else { - System.arraycopy(":false".toCharArray(), 0, buf, nameEnd + 2, 6); + System.arraycopy(VALUE_FALSE, 0, buf, nameEnd + 2, 6); } } @@ -1717,7 +1782,10 @@ public void writeFieldValue(char seperator, String name, int value) { } public void writeFieldValue(char seperator, String name, long value) { - if (value == Long.MIN_VALUE || !quoteFieldNames) { + if (value == Long.MIN_VALUE + || !quoteFieldNames + || isEnabled(SerializerFeature.BrowserCompatible.mask) + ) { write(seperator); writeFieldName(name); writeLong(value); @@ -1980,9 +2048,9 @@ public void writeFieldValueStringWithDoubleQuoteCheck(char seperator, String nam buf[bufIndex++] = '\\'; buf[bufIndex++] = 'u'; buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; valueEnd += 5; } else if (ch < IOUtils.specicalFlags_doubleQuotes.length // && IOUtils.specicalFlags_doubleQuotes[ch] != 0 // @@ -1991,9 +2059,9 @@ public void writeFieldValueStringWithDoubleQuoteCheck(char seperator, String nam if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) { buf[bufIndex++] = 'u'; buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; valueEnd += 5; } else { buf[bufIndex++] = replaceChars[(int) ch]; @@ -2004,9 +2072,9 @@ public void writeFieldValueStringWithDoubleQuoteCheck(char seperator, String nam buf[bufIndex++] = '\\'; buf[bufIndex++] = 'u'; buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; - buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; valueEnd += 5; } else { buf[bufIndex++] = ch; @@ -2093,7 +2161,11 @@ public void writeFieldValue(char seperator, String name, BigDecimal value) { if (value == null) { writeNull(); } else { - write(value.toString()); + int scale = value.scale(); + write(isEnabled(SerializerFeature.WriteBigDecimalAsPlain) && scale >= -100 && scale < 100 + ? value.toPlainString() + : value.toString() + ); } } @@ -2445,5 +2517,10 @@ public void flush() { count = 0; } - + /** + * @deprecated + */ + public void reset() { + count = 0; + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java old mode 100755 new mode 100644 index 14b404b0b4..21a0ee949e --- a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,10 +168,10 @@ public static boolean isEnabled(int features, SerializerFeature feature) { return (features & feature.mask) != 0; } - public static boolean isEnabled(int features, int fieaturesB, SerializerFeature feature) { + public static boolean isEnabled(int features, int featuresB, SerializerFeature feature) { int mask = feature.mask; - return (features & mask) != 0 || (fieaturesB & mask) != 0; + return (features & mask) != 0 || (featuresB & mask) != 0; } public static int config(int features, SerializerFeature feature, boolean state) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/SimpleDateFormatSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/SimpleDateFormatSerializer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/serializer/SimplePropertyPreFilter.java b/src/main/java/com/alibaba/fastjson/serializer/SimplePropertyPreFilter.java old mode 100755 new mode 100644 index 987f152a92..7eb69aa137 --- a/src/main/java/com/alibaba/fastjson/serializer/SimplePropertyPreFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SimplePropertyPreFilter.java @@ -4,7 +4,7 @@ import java.util.Set; /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,11 +90,8 @@ public boolean apply(JSONSerializer serializer, Object source, String name) { } } - if (includes.size() == 0 || includes.contains(name)) { - return true; - } - - return false; + return includes.size() == 0 + || includes.contains(name); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java b/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java old mode 100755 new mode 100644 index 84cd7250eb..693670f17a --- a/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java b/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java old mode 100755 new mode 100644 index 81d97d685d..b63206b55b --- a/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 Alibaba Group. + * Copyright 1999-2018 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/alibaba/fastjson/spi/Module.java b/src/main/java/com/alibaba/fastjson/spi/Module.java new file mode 100644 index 0000000000..e09ebb97ef --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/spi/Module.java @@ -0,0 +1,11 @@ +package com.alibaba.fastjson.spi; + +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; + +public interface Module { + ObjectDeserializer createDeserializer(ParserConfig config, Class type); + ObjectSerializer createSerializer(SerializeConfig config, Class type); +} diff --git a/src/main/java/com/alibaba/fastjson/support/config/FastJsonConfig.java b/src/main/java/com/alibaba/fastjson/support/config/FastJsonConfig.java index c3666f757c..8701fe287e 100644 --- a/src/main/java/com/alibaba/fastjson/support/config/FastJsonConfig.java +++ b/src/main/java/com/alibaba/fastjson/support/config/FastJsonConfig.java @@ -3,6 +3,7 @@ import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ParseProcess; import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson.serializer.SerializerFeature; @@ -18,6 +19,7 @@ * @author VictorZeng * @see SerializeConfig * @see ParserConfig + * @see ParseProcess * @see SerializerFeature * @see SerializeFilter * @see Feature @@ -41,6 +43,11 @@ public class FastJsonConfig { */ private ParserConfig parserConfig; + /** + * parseProcess + */ + private ParseProcess parseProcess; + /** * serializerFeatures */ @@ -66,17 +73,20 @@ public class FastJsonConfig { */ private String dateFormat; - protected boolean writeContentLength = true; + /** + * The Write content length. + */ + private boolean writeContentLength; /** * init param. */ public FastJsonConfig() { - this.charset = Charset.forName("UTF-8"); + this.charset = IOUtils.UTF8; this.serializeConfig = SerializeConfig.getGlobalInstance(); - this.parserConfig = new ParserConfig(); + this.parserConfig = ParserConfig.getGlobalInstance(); this.serializerFeatures = new SerializerFeature[] { SerializerFeature.BrowserSecure @@ -84,6 +94,8 @@ public FastJsonConfig() { this.serializeFilters = new SerializeFilter[0]; this.features = new Feature[0]; + + this.writeContentLength = true; } /** @@ -207,11 +219,39 @@ public void setCharset(Charset charset) { this.charset = charset; } + /** + * Is write content length boolean. + * + * @return the boolean + */ public boolean isWriteContentLength() { return writeContentLength; } + /** + * Sets write content length. + * + * @param writeContentLength the write content length + */ public void setWriteContentLength(boolean writeContentLength) { this.writeContentLength = writeContentLength; } + + /** + * Gets parse process. + * + * @return the parse process + */ + public ParseProcess getParseProcess() { + return parseProcess; + } + + /** + * Sets parse process. + * + * @param parseProcess the parse process + */ + public void setParseProcess(ParseProcess parseProcess) { + this.parseProcess = parseProcess; + } } diff --git a/src/main/java/com/alibaba/fastjson/support/geo/Feature.java b/src/main/java/com/alibaba/fastjson/support/geo/Feature.java new file mode 100644 index 0000000000..ed4497b66b --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/Feature.java @@ -0,0 +1,45 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "Feature", orders = {"type", "id", "bbox", "coordinates", "properties"}) +public class Feature + extends Geometry { + private String id; + private Geometry geometry; + private Map properties = new LinkedHashMap(); + + public Feature() { + super("Feature"); + } + + public Geometry getGeometry() { + return geometry; + } + + public void setGeometry(Geometry geometry) { + this.geometry = geometry; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/FeatureCollection.java b/src/main/java/com/alibaba/fastjson/support/geo/FeatureCollection.java new file mode 100644 index 0000000000..607c0f2646 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/FeatureCollection.java @@ -0,0 +1,23 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +import java.util.ArrayList; +import java.util.List; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "FeatureCollection", orders = {"type", "bbox", "coordinates"}) +public class FeatureCollection + extends Geometry { + private List features = new ArrayList(); + + public FeatureCollection() { + super("FeatureCollection"); + } + + public List getFeatures() { + return features; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/Geometry.java b/src/main/java/com/alibaba/fastjson/support/geo/Geometry.java new file mode 100644 index 0000000000..8611bbf23a --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/Geometry.java @@ -0,0 +1,37 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +/** + * @since 1.2.68 + */ +@JSONType(seeAlso = {GeometryCollection.class + , LineString.class + , MultiLineString.class + , Point.class + , MultiPoint.class + , Polygon.class + , MultiPolygon.class + , Feature.class + , FeatureCollection.class} + , typeKey = "type") +public abstract class Geometry { + private final String type; + private double[] bbox; + + protected Geometry(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public double[] getBbox() { + return bbox; + } + + public void setBbox(double[] bbox) { + this.bbox = bbox; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/GeometryCollection.java b/src/main/java/com/alibaba/fastjson/support/geo/GeometryCollection.java new file mode 100644 index 0000000000..df9200ca07 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/GeometryCollection.java @@ -0,0 +1,21 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; +import java.util.ArrayList; +import java.util.List; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "GeometryCollection", orders = {"type", "bbox", "geometries"}) +public class GeometryCollection extends Geometry { + private List geometries = new ArrayList(); + + public GeometryCollection() { + super("GeometryCollection"); + } + + public List getGeometries() { + return geometries; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/LineString.java b/src/main/java/com/alibaba/fastjson/support/geo/LineString.java new file mode 100644 index 0000000000..5e79d243e2 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/LineString.java @@ -0,0 +1,23 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "LineString", orders = {"type", "bbox", "coordinates"}) +public class LineString extends Geometry { + private double[][] coordinates; + + public LineString() { + super("LineString"); + } + + public double[][] getCoordinates() { + return coordinates; + } + + public void setCoordinates(double[][] coordinates) { + this.coordinates = coordinates; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/MultiLineString.java b/src/main/java/com/alibaba/fastjson/support/geo/MultiLineString.java new file mode 100644 index 0000000000..782a61d4cf --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/MultiLineString.java @@ -0,0 +1,23 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "MultiLineString", orders = {"type", "bbox", "coordinates"}) +public class MultiLineString extends Geometry { + private double[][][] coordinates; + + public MultiLineString() { + super("MultiLineString"); + } + + public double[][][] getCoordinates() { + return coordinates; + } + + public void setCoordinates(double[][][] coordinates) { + this.coordinates = coordinates; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/MultiPoint.java b/src/main/java/com/alibaba/fastjson/support/geo/MultiPoint.java new file mode 100644 index 0000000000..7cbe37db02 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/MultiPoint.java @@ -0,0 +1,23 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "MultiPoint", orders = {"type", "bbox", "coordinates"}) +public class MultiPoint extends Geometry { + private double[][] coordinates; + + public MultiPoint() { + super("MultiPoint"); + } + + public double[][] getCoordinates() { + return coordinates; + } + + public void setCoordinates(double[][] coordinates) { + this.coordinates = coordinates; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/MultiPolygon.java b/src/main/java/com/alibaba/fastjson/support/geo/MultiPolygon.java new file mode 100644 index 0000000000..1969c94ae2 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/MultiPolygon.java @@ -0,0 +1,24 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "MultiPolygon", orders = {"type", "bbox", "coordinates"}) +public class MultiPolygon + extends Geometry { + private double[][][][] coordinates; + + public MultiPolygon() { + super("MultiPolygon"); + } + + public double[][][][] getCoordinates() { + return coordinates; + } + + public void setCoordinates(double[][][][] coordinates) { + this.coordinates = coordinates; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/Point.java b/src/main/java/com/alibaba/fastjson/support/geo/Point.java new file mode 100644 index 0000000000..634016f007 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/Point.java @@ -0,0 +1,57 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "Point", orders = {"type", "bbox", "coordinates"}) +public class Point extends Geometry { + private double longitude; + private double latitude; + + public Point() { + super("Point"); + } + + public double[] getCoordinates() { + return new double[] {longitude, latitude}; + } + + public void setCoordinates(double[] coordinates) { + if (coordinates == null || coordinates.length == 0) { + this.longitude = 0; + this.latitude = 0; + return; + } + + if (coordinates.length == 1) { + this.longitude = coordinates[0]; + return; + } + + this.longitude = coordinates[0]; + this.latitude = coordinates[1]; + } + + @JSONField(serialize = false) + public double getLongitude() { + return longitude; + } + + @JSONField(serialize = false) + public double getLatitude() { + return latitude; + } + + @JSONField(deserialize = false) + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + @JSONField(deserialize = false) + public void setLatitude(double latitude) { + this.latitude = latitude; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/geo/Polygon.java b/src/main/java/com/alibaba/fastjson/support/geo/Polygon.java new file mode 100644 index 0000000000..23cff6b862 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/geo/Polygon.java @@ -0,0 +1,23 @@ +package com.alibaba.fastjson.support.geo; + +import com.alibaba.fastjson.annotation.JSONType; + +/** + * @since 1.2.68 + */ +@JSONType(typeName = "Polygon", orders = {"type", "bbox", "coordinates"}) +public class Polygon extends Geometry { + private double[][][] coordinates; + + public Polygon() { + super("Polygon"); + } + + public double[][][] getCoordinates() { + return coordinates; + } + + public void setCoordinates(double[][][] coordinates) { + this.coordinates = coordinates; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonAutoDiscoverable.java b/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonAutoDiscoverable.java index 308483b254..226f9a83f7 100644 --- a/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonAutoDiscoverable.java +++ b/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonAutoDiscoverable.java @@ -17,9 +17,19 @@ @Priority(AutoDiscoverable.DEFAULT_PRIORITY - 1) public class FastJsonAutoDiscoverable implements AutoDiscoverable { + public static final String FASTJSON_AUTO_DISCOVERABLE = "fastjson.auto.discoverable"; + public volatile static boolean autoDiscover = true; - @Override + static { + try { + autoDiscover = Boolean.parseBoolean( + System.getProperty(FASTJSON_AUTO_DISCOVERABLE, String.valueOf(autoDiscover))); + } catch (Throwable ex) { + //skip + } + } + public void configure(final FeatureContext context) { final Configuration config = context.getConfiguration(); @@ -30,4 +40,5 @@ public void configure(final FeatureContext context) { context.register(FastJsonFeature.class); } } + } diff --git a/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonFeature.java b/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonFeature.java index 1712c7fef9..aa3faa525c 100644 --- a/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonFeature.java +++ b/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonFeature.java @@ -24,24 +24,33 @@ public class FastJsonFeature implements Feature { @Override public boolean configure(final FeatureContext context) { - - final Configuration config = context.getConfiguration(); - - final String jsonFeature = CommonProperties.getValue(config.getProperties(), config.getRuntimeType(), InternalProperties.JSON_FEATURE, JSON_FEATURE, - String.class); - - // Other JSON providers registered. - if (!JSON_FEATURE.equalsIgnoreCase(jsonFeature)) - - return false; - - // Disable other JSON providers. - context.property(PropertiesHelper.getPropertyNameForRuntime(InternalProperties.JSON_FEATURE, config.getRuntimeType()), JSON_FEATURE); - - // Register FastJson. - if (!config.isRegistered(FastJsonProvider.class)) - - context.register(FastJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class); + try { + final Configuration config = context.getConfiguration(); + + final String jsonFeature = CommonProperties.getValue( + config.getProperties() + , config.getRuntimeType() + , InternalProperties.JSON_FEATURE, JSON_FEATURE, + String.class + ); + + // Other JSON providers registered. + if (!JSON_FEATURE.equalsIgnoreCase(jsonFeature)) { + return false; + } + + // Disable other JSON providers. + context.property( + PropertiesHelper.getPropertyNameForRuntime(InternalProperties.JSON_FEATURE, config.getRuntimeType()) + , JSON_FEATURE); + + // Register FastJson. + if (!config.isRegistered(FastJsonProvider.class)) { + context.register(FastJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class); + } + } catch (NoSuchMethodError e) { + // skip + } return true; } diff --git a/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonProvider.java b/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonProvider.java index 54e8d6bbe9..36881520d2 100644 --- a/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonProvider.java +++ b/src/main/java/com/alibaba/fastjson/support/jaxrs/FastJsonProvider.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; @@ -9,13 +10,9 @@ import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.*; import javax.ws.rs.ext.*; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.nio.charset.Charset; @@ -38,6 +35,25 @@ @Produces({MediaType.WILDCARD}) public class FastJsonProvider // implements MessageBodyReader, MessageBodyWriter { + + /** + * These are classes that we never use for reading + * (never try to deserialize instances of these types). + */ + public final static Class[] DEFAULT_UNREADABLES = new Class[]{ + InputStream.class, Reader.class + }; + + /** + * These are classes that we never use for writing + * (never try to serialize instances of these types). + */ + public final static Class[] DEFAULT_UNWRITABLES = new Class[]{ + InputStream.class, + OutputStream.class, Writer.class, + StreamingOutput.class, Response.class + }; + @Deprecated protected Charset charset = Charset.forName("UTF-8"); @@ -113,53 +129,134 @@ public FastJsonProvider setPretty(boolean p) { } /** - * Set charset. the default charset is UTF-8 + * Instantiates a new Fast json provider. + * + * @param charset the charset + * @see FastJsonConfig#setCharset(Charset) + * @deprecated */ @Deprecated public FastJsonProvider(String charset) { this.fastJsonConfig.setCharset(Charset.forName(charset)); } + /** + * Gets charset. + * + * @return the charset + * @see FastJsonConfig#getCharset() + * @deprecated + */ @Deprecated public Charset getCharset() { return this.fastJsonConfig.getCharset(); } + /** + * Sets charset. + * + * @param charset the charset + * @see FastJsonConfig#setCharset(Charset) + * @deprecated + */ @Deprecated public void setCharset(Charset charset) { this.fastJsonConfig.setCharset(charset); } + /** + * Gets date format. + * + * @return the date format + * @see FastJsonConfig#getDateFormat() + * @deprecated + */ @Deprecated public String getDateFormat() { return this.fastJsonConfig.getDateFormat(); } + /** + * Sets date format. + * + * @param dateFormat the date format + * @see FastJsonConfig#setDateFormat(String) + * @deprecated + */ @Deprecated public void setDateFormat(String dateFormat) { this.fastJsonConfig.setDateFormat(dateFormat); } + /** + * Get features serializer feature []. + * + * @return the serializer feature [] + * @see FastJsonConfig#getFeatures() + * @deprecated + */ @Deprecated public SerializerFeature[] getFeatures() { return this.fastJsonConfig.getSerializerFeatures(); } + /** + * Sets features. + * + * @param features the features + * @see FastJsonConfig#setFeatures(Feature...) + * @deprecated + */ @Deprecated public void setFeatures(SerializerFeature... features) { this.fastJsonConfig.setSerializerFeatures(features); } + /** + * Get filters serialize filter []. + * + * @return the serialize filter [] + * @see FastJsonConfig#getSerializeFilters() + * @deprecated + */ @Deprecated public SerializeFilter[] getFilters() { return this.fastJsonConfig.getSerializeFilters(); } + /** + * Sets filters. + * + * @param filters the filters + * @see FastJsonConfig#setSerializeFilters(SerializeFilter...) + * @deprecated + */ @Deprecated public void setFilters(SerializeFilter... filters) { this.fastJsonConfig.setSerializeFilters(filters); } + /** + * Check some are interface/abstract classes to exclude. + * + * @param type the type + * @param classes the classes + * @return the boolean + */ + protected boolean isAssignableFrom(Class type, Class[] classes) { + + if (type == null) + return false; + + // there are some other abstract/interface types to exclude too: + for (Class cls : classes) { + if (cls.isAssignableFrom(type)) { + return false; + } + } + + return true; + } /** * Check whether a class can be serialized or deserialized. It can check @@ -206,12 +303,6 @@ protected boolean hasMatchingMediaType(MediaType mediaType) { return true; } - /* - * /********************************************************** /* Partial - * MessageBodyWriter impl - * /********************************************************** - */ - /** * Method that JAX-RS container calls to try to check whether given value * (of specified type) can be serialized by this provider. @@ -224,6 +315,9 @@ public boolean isWriteable(Class type, // return false; } + if (!isAssignableFrom(type, DEFAULT_UNWRITABLES)) + return false; + return isValidType(type, annotations); } @@ -254,12 +348,12 @@ public void writeTo(Object obj, // FastJsonConfig fastJsonConfig = locateConfigProvider(type, mediaType); SerializerFeature[] serializerFeatures = fastJsonConfig.getSerializerFeatures(); + if (pretty) { if (serializerFeatures == null) serializerFeatures = new SerializerFeature[]{SerializerFeature.PrettyFormat}; else { - List featureList = new ArrayList(Arrays - .asList(serializerFeatures)); + List featureList = new ArrayList(Arrays.asList(serializerFeatures)); featureList.add(SerializerFeature.PrettyFormat); serializerFeatures = featureList.toArray(serializerFeatures); } @@ -267,7 +361,7 @@ public void writeTo(Object obj, // } try { - int len = JSON.writeJSONString(entityStream, // + JSON.writeJSONStringWithFastJsonConfig(entityStream, // fastJsonConfig.getCharset(), // obj, // fastJsonConfig.getSerializeConfig(), // @@ -276,25 +370,14 @@ public void writeTo(Object obj, // JSON.DEFAULT_GENERATE_FEATURE, // fastJsonConfig.getSerializerFeatures()); -// // add Content-Length -// if (fastJsonConfig.isWriteContentLength()) { -// httpHeaders.add("Content-Length", String.valueOf(len)); -// } - entityStream.flush(); } catch (JSONException ex) { - throw new WebApplicationException("Could not write JSON: " + ex.getMessage(), ex); + throw new WebApplicationException(ex); } } - /* - * /********************************************************** /* - * MessageBodyReader impl - * /********************************************************** - */ - /** * Method that JAX-RS container calls to try to check whether values of * given type (and media type) can be deserialized by this provider. @@ -308,6 +391,9 @@ public boolean isReadable(Class type, // return false; } + if (!isAssignableFrom(type, DEFAULT_UNREADABLES)) + return false; + return isValidType(type, annotations); } @@ -324,11 +410,17 @@ public Object readFrom(Class type, // try { FastJsonConfig fastJsonConfig = locateConfigProvider(type, mediaType); - return JSON.parseObject(entityStream, fastJsonConfig.getCharset(), genericType, fastJsonConfig.getFeatures()); + return JSON.parseObject(entityStream, + fastJsonConfig.getCharset(), + genericType, + fastJsonConfig.getParserConfig(), + fastJsonConfig.getParseProcess(), + JSON.DEFAULT_PARSER_FEATURE, + fastJsonConfig.getFeatures()); } catch (JSONException ex) { - throw new WebApplicationException("JSON parse error: " + ex.getMessage(), ex); + throw new WebApplicationException(ex); } } diff --git a/src/main/java/com/alibaba/fastjson/support/moneta/MonetaCodec.java b/src/main/java/com/alibaba/fastjson/support/moneta/MonetaCodec.java new file mode 100644 index 0000000000..6c44999a0a --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/moneta/MonetaCodec.java @@ -0,0 +1,57 @@ +package com.alibaba.fastjson.support.moneta; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import org.javamoney.moneta.Money; + +import javax.money.Monetary; +import java.io.IOException; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; + +public class MonetaCodec implements ObjectSerializer, ObjectDeserializer { + public static final MonetaCodec instance = new MonetaCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + Money money = (Money) object; + if (money == null) { + serializer.writeNull(); + return; + } + + SerializeWriter out = serializer.out; + out.writeFieldValue('{', "numberStripped", money.getNumberStripped()); + out.writeFieldValue(',', "currency", money.getCurrency().getCurrencyCode()); + out.write('}'); + } + + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONObject object = parser.parseObject(); + Object currency = object.get("currency"); + + String currencyCode = null; + if (currency instanceof JSONObject) { + currencyCode = ((JSONObject) currency).getString("currencyCode"); + } else if (currency instanceof String) { + currencyCode = (String) currency; + } + + Object numberStripped = object.get("numberStripped"); + + if (numberStripped instanceof BigDecimal + || numberStripped instanceof Integer || numberStripped instanceof BigInteger) { + return (T) Money.of((Number) numberStripped, Monetary.getCurrency(currencyCode)); + } + + throw new UnsupportedOperationException(); + } + + public int getFastMatchToken() { + return 0; + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/retrofit/Retrofit2ConverterFactory.java b/src/main/java/com/alibaba/fastjson/support/retrofit/Retrofit2ConverterFactory.java index 1774f29a49..f7ee2642a4 100644 --- a/src/main/java/com/alibaba/fastjson/support/retrofit/Retrofit2ConverterFactory.java +++ b/src/main/java/com/alibaba/fastjson/support/retrofit/Retrofit2ConverterFactory.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; @@ -17,78 +18,194 @@ /** * @author ligboy, wenshao + * @author Victor.Zxy */ public class Retrofit2ConverterFactory extends Converter.Factory { + private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); - private static final Feature[] EMPTY_SERIALIZER_FEATURES = new Feature[0]; + private FastJsonConfig fastJsonConfig; + + @Deprecated + private static final Feature[] EMPTY_SERIALIZER_FEATURES = new Feature[0]; + @Deprecated private ParserConfig parserConfig = ParserConfig.getGlobalInstance(); + @Deprecated private int featureValues = JSON.DEFAULT_PARSER_FEATURE; + @Deprecated private Feature[] features; - + @Deprecated private SerializeConfig serializeConfig; + @Deprecated private SerializerFeature[] serializerFeatures; public Retrofit2ConverterFactory() { + this.fastJsonConfig = new FastJsonConfig(); + } + + public Retrofit2ConverterFactory(FastJsonConfig fastJsonConfig) { + this.fastJsonConfig = fastJsonConfig; + } + + public static Retrofit2ConverterFactory create() { + return create(new FastJsonConfig()); + } + + public static Retrofit2ConverterFactory create(FastJsonConfig fastJsonConfig) { + if (fastJsonConfig == null) throw new NullPointerException("fastJsonConfig == null"); + return new Retrofit2ConverterFactory(fastJsonConfig); } @Override - public Converter responseBodyConverter(Type type, // - Annotation[] annotations, // - Retrofit retrofit) { - return new ResponseBodyConverter(type); + public Converter responseBodyConverter(Type type, // + Annotation[] annotations, // + Retrofit retrofit) { + return new ResponseBodyConverter(type); } @Override - public Converter requestBodyConverter(Type type, // - Annotation[] parameterAnnotations, // - Annotation[] methodAnnotations, // - Retrofit retrofit) { - return new RequestBodyConverter(); + public Converter requestBodyConverter(Type type, // + Annotation[] parameterAnnotations, // + Annotation[] methodAnnotations, // + Retrofit retrofit) { + return new RequestBodyConverter(); + } + + public FastJsonConfig getFastJsonConfig() { + return fastJsonConfig; } + public Retrofit2ConverterFactory setFastJsonConfig(FastJsonConfig fastJsonConfig) { + this.fastJsonConfig = fastJsonConfig; + return this; + } + + /** + * Gets parser config. + * + * @return the parser config + * @see FastJsonConfig#getParserConfig() + * @deprecated + */ + @Deprecated public ParserConfig getParserConfig() { - return parserConfig; + return fastJsonConfig.getParserConfig(); } + /** + * Sets parser config. + * + * @param config the config + * @return the parser config + * @see FastJsonConfig#setParserConfig(ParserConfig) + * @deprecated + */ + @Deprecated public Retrofit2ConverterFactory setParserConfig(ParserConfig config) { - this.parserConfig = config; + fastJsonConfig.setParserConfig(config); return this; } + /** + * Gets parser feature values. + * + * @return the parser feature values + * @see JSON#DEFAULT_PARSER_FEATURE + * @deprecated + */ + @Deprecated public int getParserFeatureValues() { - return featureValues; + return JSON.DEFAULT_PARSER_FEATURE; } + /** + * Sets parser feature values. + * + * @param featureValues the feature values + * @return the parser feature values + * @see JSON#DEFAULT_PARSER_FEATURE + * @deprecated + */ + @Deprecated public Retrofit2ConverterFactory setParserFeatureValues(int featureValues) { - this.featureValues = featureValues; return this; } + /** + * Get parser features feature []. + * + * @return the feature [] + * @see FastJsonConfig#getFeatures() + * @deprecated + */ + @Deprecated public Feature[] getParserFeatures() { - return features; + return fastJsonConfig.getFeatures(); } + /** + * Sets parser features. + * + * @param features the features + * @return the parser features + * @see FastJsonConfig#setFeatures(Feature...) + * @deprecated + */ + @Deprecated public Retrofit2ConverterFactory setParserFeatures(Feature[] features) { - this.features = features; + fastJsonConfig.setFeatures(features); return this; } + /** + * Gets serialize config. + * + * @return the serialize config + * @see FastJsonConfig#getSerializeConfig() + * @deprecated + */ + @Deprecated public SerializeConfig getSerializeConfig() { - return serializeConfig; + return fastJsonConfig.getSerializeConfig(); } + /** + * Sets serialize config. + * + * @param serializeConfig the serialize config + * @return the serialize config + * @see FastJsonConfig#setSerializeConfig(SerializeConfig) + * @deprecated + */ + @Deprecated public Retrofit2ConverterFactory setSerializeConfig(SerializeConfig serializeConfig) { - this.serializeConfig = serializeConfig; + fastJsonConfig.setSerializeConfig(serializeConfig); return this; } + /** + * Get serializer features serializer feature []. + * + * @return the serializer feature [] + * @see FastJsonConfig#getSerializerFeatures() + * @deprecated + */ + @Deprecated public SerializerFeature[] getSerializerFeatures() { - return serializerFeatures; + return fastJsonConfig.getSerializerFeatures(); } + /** + * Sets serializer features. + * + * @param features the features + * @return the serializer features + * @see FastJsonConfig#setSerializerFeatures(SerializerFeature...) + * @deprecated + */ + @Deprecated public Retrofit2ConverterFactory setSerializerFeatures(SerializerFeature[] features) { - this.serializerFeatures = features; + fastJsonConfig.setSerializerFeatures(features); return this; } @@ -101,14 +218,16 @@ final class ResponseBodyConverter implements Converter { public T convert(ResponseBody value) throws IOException { try { - return JSON.parseObject(value.string() - , type - , parserConfig - , featureValues - , features != null - ? features - : EMPTY_SERIALIZER_FEATURES + return JSON.parseObject(value.bytes() + , fastJsonConfig.getCharset() + , type + , fastJsonConfig.getParserConfig() + , fastJsonConfig.getParseProcess() + , JSON.DEFAULT_PARSER_FEATURE + , fastJsonConfig.getFeatures() ); + } catch (Exception e) { + throw new IOException("JSON parse error: " + e.getMessage(), e); } finally { value.close(); } @@ -120,16 +239,19 @@ final class RequestBodyConverter implements Converter { } public RequestBody convert(T value) throws IOException { - byte[] content = JSON.toJSONBytes(value - , serializeConfig == null - ? SerializeConfig.globalInstance - : serializeConfig - , serializerFeatures == null - ? SerializerFeature.EMPTY - : serializerFeatures - ); - - return RequestBody.create(MEDIA_TYPE, content); + try { + byte[] content = JSON.toJSONBytesWithFastJsonConfig(fastJsonConfig.getCharset() + , value + , fastJsonConfig.getSerializeConfig() + , fastJsonConfig.getSerializeFilters() + , fastJsonConfig.getDateFormat() + , JSON.DEFAULT_GENERATE_FEATURE + , fastJsonConfig.getSerializerFeatures() + ); + return RequestBody.create(MEDIA_TYPE, content); + } catch (Exception e) { + throw new IOException("Could not write JSON: " + e.getMessage(), e); + } } } } diff --git a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonContainer.java b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonContainer.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonHttpMessageConverter.java b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonHttpMessageConverter.java index cd8cb4a05c..044dc758c1 100644 --- a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonHttpMessageConverter.java +++ b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonHttpMessageConverter.java @@ -6,7 +6,6 @@ import com.alibaba.fastjson.serializer.SerializeFilter; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; -import com.alibaba.fastjson.util.IOUtils; import org.springframework.core.ResolvableType; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; @@ -59,8 +58,6 @@ public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter clazz) { } - @Override public boolean canRead(Type type, Class contextClass, MediaType mediaType) { return super.canRead(contextClass, mediaType); } @@ -191,17 +252,23 @@ public void write(Object o, Type type, MediaType contentType, HttpOutputMessage * @see org.springframework.http.converter.AbstractHttpMessageConverter#readInternal(java.lang.Class, org.springframework.http.HttpInputMessage) */ @Override - protected Object readInternal(Class clazz, // + protected Object readInternal(Class clazz, // HttpInputMessage inputMessage // ) throws IOException, HttpMessageNotReadableException { return readType(getType(clazz, null), inputMessage); } - private Object readType(Type type, HttpInputMessage inputMessage) throws IOException { + private Object readType(Type type, HttpInputMessage inputMessage) { try { InputStream in = inputMessage.getBody(); - return JSON.parseObject(in, fastJsonConfig.getCharset(), type, fastJsonConfig.getFeatures()); + return JSON.parseObject(in, + fastJsonConfig.getCharset(), + type, + fastJsonConfig.getParserConfig(), + fastJsonConfig.getParseProcess(), + JSON.DEFAULT_PARSER_FEATURE, + fastJsonConfig.getFeatures()); } catch (JSONException ex) { throw new HttpMessageNotReadableException("JSON parse error: " + ex.getMessage(), ex); } catch (IOException ex) { @@ -236,7 +303,7 @@ protected void writeInternal(Object object, HttpOutputMessage outputMessage) thr // 保持原有的MappingFastJsonValue对象的contentType不做修改 保持旧版兼容。 // 但是新的JSONPObject将返回标准的contentType:application/javascript ,不对是否有function进行判断 if (value instanceof MappingFastJsonValue) { - if(!StringUtils.isEmpty(((MappingFastJsonValue) value).getJsonpFunction())){ + if (!StringUtils.isEmpty(((MappingFastJsonValue) value).getJsonpFunction())) { isJsonp = true; } } else if (value instanceof JSONPObject) { @@ -244,7 +311,7 @@ protected void writeInternal(Object object, HttpOutputMessage outputMessage) thr } - int len = JSON.writeJSONString(outnew, // + int len = JSON.writeJSONStringWithFastJsonConfig(outnew, // fastJsonConfig.getCharset(), // value, // fastJsonConfig.getSerializeConfig(), // @@ -258,8 +325,13 @@ protected void writeInternal(Object object, HttpOutputMessage outputMessage) thr headers.setContentType(APPLICATION_JAVASCRIPT); } - if (fastJsonConfig.isWriteContentLength()) { - headers.setContentLength(len); + if (fastJsonConfig.isWriteContentLength() && !setLengthError) { + try { + headers.setContentLength(len); + } catch (UnsupportedOperationException ex) { + // skip + setLengthError = true; + } } outnew.writeTo(outputMessage.getBody()); diff --git a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonJsonView.java b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonJsonView.java old mode 100755 new mode 100644 index ce0fab3726..76c5bbef11 --- a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonJsonView.java +++ b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonJsonView.java @@ -8,7 +8,6 @@ import com.alibaba.fastjson.util.IOUtils; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.web.servlet.view.AbstractView; @@ -17,7 +16,9 @@ import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.nio.charset.Charset; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import java.util.regex.Pattern; /** @@ -114,46 +115,109 @@ public void setFastJsonConfig(FastJsonConfig fastJsonConfig) { this.fastJsonConfig = fastJsonConfig; } + /** + * Sets serializer feature. + * + * @param features the features + * @see FastJsonConfig#setSerializerFeatures(SerializerFeature...) + * @deprecated + */ @Deprecated public void setSerializerFeature(SerializerFeature... features) { this.fastJsonConfig.setSerializerFeatures(features); } + /** + * Gets charset. + * + * @return the charset + * @see FastJsonConfig#getCharset() + * @deprecated + */ @Deprecated public Charset getCharset() { return this.fastJsonConfig.getCharset(); } + /** + * Sets charset. + * + * @param charset the charset + * @see FastJsonConfig#setCharset(Charset) + * @deprecated + */ @Deprecated public void setCharset(Charset charset) { this.fastJsonConfig.setCharset(charset); } + /** + * Gets date format. + * + * @return the date format + * @see FastJsonConfig#getDateFormat() + * @deprecated + */ @Deprecated public String getDateFormat() { return this.fastJsonConfig.getDateFormat(); } + /** + * Sets date format. + * + * @param dateFormat the date format + * @see FastJsonConfig#setDateFormat(String) + * @deprecated + */ @Deprecated public void setDateFormat(String dateFormat) { this.fastJsonConfig.setDateFormat(dateFormat); } + /** + * Get features serializer feature []. + * + * @return the serializer feature [] + * @see FastJsonConfig#getSerializerFeatures() + * @deprecated + */ @Deprecated public SerializerFeature[] getFeatures() { return this.fastJsonConfig.getSerializerFeatures(); } + /** + * Sets features. + * + * @param features the features + * @see FastJsonConfig#setSerializerFeatures(SerializerFeature...) + * @deprecated + */ @Deprecated public void setFeatures(SerializerFeature... features) { this.fastJsonConfig.setSerializerFeatures(features); } + /** + * Get filters serialize filter []. + * + * @return the serialize filter [] + * @see FastJsonConfig#getSerializeFilters() + * @deprecated + */ @Deprecated public SerializeFilter[] getFilters() { return this.fastJsonConfig.getSerializeFilters(); } + /** + * Sets filters. + * + * @param filters the filters + * @see FastJsonConfig#setSerializeFilters(SerializeFilter...) + * @deprecated + */ @Deprecated public void setFilters(SerializeFilter... filters) { this.fastJsonConfig.setSerializeFilters(filters); @@ -182,8 +246,7 @@ public boolean isExtractValueFromSingleKeyModel() { * * @param extractValueFromSingleKeyModel */ - public void setExtractValueFromSingleKeyModel( - boolean extractValueFromSingleKeyModel) { + public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) { this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel; } @@ -192,8 +255,9 @@ public void setExtractValueFromSingleKeyModel( * parameters, the resulting JSON will be wrapped into a function named as * specified by the JSONP request parameter value. *

The parameter names configured by default are "jsonp" and "callback". - * @since 4.1 + * * @see JSONP Wikipedia article + * @since 4.1 */ public void setJsonpParameterNames(Set jsonpParameterNames) { Assert.notEmpty(jsonpParameterNames, "jsonpParameterName cannot be empty"); @@ -219,14 +283,13 @@ private String getJsonpParameterValue(HttpServletRequest request) { } - @Override protected void renderMergedOutputModel(Map model, // HttpServletRequest request, // HttpServletResponse response) throws Exception { Object value = filterModel(model); String jsonpParameterValue = getJsonpParameterValue(request); - if(jsonpParameterValue != null) { + if (jsonpParameterValue != null) { JSONPObject jsonpObject = new JSONPObject(jsonpParameterValue); jsonpObject.addParameter(value); value = jsonpObject; @@ -234,7 +297,7 @@ protected void renderMergedOutputModel(Map model, // ByteArrayOutputStream outnew = new ByteArrayOutputStream(); - int len = JSON.writeJSONString(outnew, // + int len = JSON.writeJSONStringWithFastJsonConfig(outnew, // fastJsonConfig.getCharset(), // value, // fastJsonConfig.getSerializeConfig(), // @@ -326,8 +389,7 @@ protected Object filterModel(Map model) { protected void setResponseContentType(HttpServletRequest request, HttpServletResponse response) { if (getJsonpParameterValue(request) != null) { response.setContentType(DEFAULT_JSONP_CONTENT_TYPE); - } - else { + } else { super.setResponseContentType(request, response); } } diff --git a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonRedisSerializer.java b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonRedisSerializer.java index ce2cb843e9..d37a5ac4c7 100644 --- a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonRedisSerializer.java +++ b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonRedisSerializer.java @@ -7,7 +7,9 @@ /** * {@link RedisSerializer} FastJson Impl + * * @author lihengming + * @author Victor.Zxy * @since 1.2.36 */ public class FastJsonRedisSerializer implements RedisSerializer { @@ -32,7 +34,15 @@ public byte[] serialize(T t) throws SerializationException { return new byte[0]; } try { - return JSON.toJSONBytes(t, fastJsonConfig.getSerializeConfig(), fastJsonConfig.getSerializerFeatures()); + return JSON.toJSONBytesWithFastJsonConfig( + fastJsonConfig.getCharset(), + t, + fastJsonConfig.getSerializeConfig(), + fastJsonConfig.getSerializeFilters(), + fastJsonConfig.getDateFormat(), + JSON.DEFAULT_GENERATE_FEATURE, + fastJsonConfig.getSerializerFeatures() + ); } catch (Exception ex) { throw new SerializationException("Could not serialize: " + ex.getMessage(), ex); } @@ -44,7 +54,15 @@ public T deserialize(byte[] bytes) throws SerializationException { return null; } try { - return (T) JSON.parseObject(bytes, type, fastJsonConfig.getFeatures()); + return (T) JSON.parseObject( + bytes, + fastJsonConfig.getCharset(), + type, + fastJsonConfig.getParserConfig(), + fastJsonConfig.getParseProcess(), + JSON.DEFAULT_PARSER_FEATURE, + fastJsonConfig.getFeatures() + ); } catch (Exception ex) { throw new SerializationException("Could not deserialize: " + ex.getMessage(), ex); } diff --git a/src/main/java/com/alibaba/fastjson/support/spring/GenericFastJsonRedisSerializer.java b/src/main/java/com/alibaba/fastjson/support/spring/GenericFastJsonRedisSerializer.java index 04fb6d0c3f..6d764ae67e 100644 --- a/src/main/java/com/alibaba/fastjson/support/spring/GenericFastJsonRedisSerializer.java +++ b/src/main/java/com/alibaba/fastjson/support/spring/GenericFastJsonRedisSerializer.java @@ -16,7 +16,6 @@ public class GenericFastJsonRedisSerializer implements RedisSerializer { private final static ParserConfig defaultRedisConfig = new ParserConfig(); static { defaultRedisConfig.setAutoTypeSupport(true);} - @Override public byte[] serialize(Object object) throws SerializationException { if (object == null) { return new byte[0]; @@ -28,7 +27,6 @@ public byte[] serialize(Object object) throws SerializationException { } } - @Override public Object deserialize(byte[] bytes) throws SerializationException { if (bytes == null || bytes.length == 0) { return null; diff --git a/src/main/java/com/alibaba/fastjson/support/spring/PropertyPreFilters.java b/src/main/java/com/alibaba/fastjson/support/spring/PropertyPreFilters.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/support/spring/messaging/MappingFastJsonMessageConverter.java b/src/main/java/com/alibaba/fastjson/support/spring/messaging/MappingFastJsonMessageConverter.java new file mode 100644 index 0000000000..ba8e375c4b --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/spring/messaging/MappingFastJsonMessageConverter.java @@ -0,0 +1,101 @@ +package com.alibaba.fastjson.support.spring.messaging; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.converter.AbstractMessageConverter; +import org.springframework.util.MimeType; + +import java.nio.charset.Charset; + +/** + * Fastjson for Spring Messaging Json Converter. + *

+ * Compatible Spring Messaging version 4+ + * + * @author KimmKing + * @author Victor.Zxy + * @see AbstractMessageConverter + * @since 1.2.47 + */ +public class MappingFastJsonMessageConverter extends AbstractMessageConverter { + + /** + * with fastJson config + */ + private FastJsonConfig fastJsonConfig = new FastJsonConfig(); + + /** + * @return the fastJsonConfig. + * @since 1.2.47 + */ + public FastJsonConfig getFastJsonConfig() { + return fastJsonConfig; + } + + /** + * @param fastJsonConfig the fastJsonConfig to set. + * @since 1.2.47 + */ + public void setFastJsonConfig(FastJsonConfig fastJsonConfig) { + this.fastJsonConfig = fastJsonConfig; + } + + public MappingFastJsonMessageConverter() { + super(new MimeType("application", "json", Charset.forName("UTF-8"))); + } + + protected boolean supports(Class clazz) { + return true; + } + + @Override + protected boolean canConvertFrom(Message message, Class targetClass) { + return supports(targetClass); + } + + @Override + protected boolean canConvertTo(Object payload, MessageHeaders headers) { + return supports(payload.getClass()); + } + + @Override + protected Object convertFromInternal(Message message, Class targetClass, Object conversionHint) { + // parse byte[] or String payload to Java Object + Object payload = message.getPayload(); + Object obj = null; + if (payload instanceof byte[]) { + obj = JSON.parseObject((byte[]) payload, fastJsonConfig.getCharset(), targetClass, fastJsonConfig.getParserConfig(), + fastJsonConfig.getParseProcess(), JSON.DEFAULT_PARSER_FEATURE, fastJsonConfig.getFeatures()); + } else if (payload instanceof String) { + obj = JSON.parseObject((String) payload, targetClass, fastJsonConfig.getParserConfig(), + fastJsonConfig.getParseProcess(), JSON.DEFAULT_PARSER_FEATURE, fastJsonConfig.getFeatures()); + } + + return obj; + } + + @Override + protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) { + // encode payload to json string or byte[] + Object obj; + if (byte[].class == getSerializedPayloadClass()) { + if (payload instanceof String && JSON.isValid((String) payload)) { + obj = ((String) payload).getBytes(fastJsonConfig.getCharset()); + } else { + obj = JSON.toJSONBytesWithFastJsonConfig(fastJsonConfig.getCharset(), payload, fastJsonConfig.getSerializeConfig(), fastJsonConfig.getSerializeFilters(), + fastJsonConfig.getDateFormat(), JSON.DEFAULT_GENERATE_FEATURE, fastJsonConfig.getSerializerFeatures()); + } + } else { + if (payload instanceof String && JSON.isValid((String) payload)) { + obj = payload; + } else { + obj = JSON.toJSONString(payload, fastJsonConfig.getSerializeConfig(), fastJsonConfig.getSerializeFilters(), + fastJsonConfig.getDateFormat(), JSON.DEFAULT_GENERATE_FEATURE, fastJsonConfig.getSerializerFeatures()); + } + } + + return obj; + } +} diff --git a/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java b/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/util/ASMUtils.java b/src/main/java/com/alibaba/fastjson/util/ASMUtils.java old mode 100755 new mode 100644 index f212e8ddc4..c139a3c654 --- a/src/main/java/com/alibaba/fastjson/util/ASMUtils.java +++ b/src/main/java/com/alibaba/fastjson/util/ASMUtils.java @@ -1,10 +1,12 @@ package com.alibaba.fastjson.util; +import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.asm.ClassReader; import com.alibaba.fastjson.asm.TypeCollector; import java.io.IOException; import java.io.InputStream; +import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -119,16 +121,19 @@ public static String[] lookupParameterNames(AccessibleObject methodOrCtor) { final Class declaringClass; final String name; + Annotation[][] parameterAnnotations; if (methodOrCtor instanceof Method) { Method method = (Method) methodOrCtor; types = method.getParameterTypes(); name = method.getName(); declaringClass = method.getDeclaringClass(); + parameterAnnotations = TypeUtils.getParameterAnnotations(method); } else { Constructor constructor = (Constructor) methodOrCtor; types = constructor.getParameterTypes(); declaringClass = constructor.getDeclaringClass(); name = ""; + parameterAnnotations = TypeUtils.getParameterAnnotations(constructor); } if (types.length == 0) { @@ -149,10 +154,27 @@ public static String[] lookupParameterNames(AccessibleObject methodOrCtor) { } try { - ClassReader reader = new ClassReader(is); + ClassReader reader = new ClassReader(is, false); TypeCollector visitor = new TypeCollector(name, types); reader.accept(visitor); - return visitor.getParameterNamesForMethod(); + String[] parameterNames = visitor.getParameterNamesForMethod(); + + for (int i = 0; i < parameterNames.length; i++) { + Annotation[] annotations = parameterAnnotations[i]; + if (annotations != null) { + for (int j = 0; j < annotations.length; j++) { + if (annotations[j] instanceof JSONField) { + JSONField jsonField = (JSONField) annotations[j]; + String fieldName = jsonField.name(); + if (fieldName != null && fieldName.length() > 0) { + parameterNames[i] = fieldName; + } + } + } + } + } + + return parameterNames; } catch (IOException e) { return new String[0]; } finally { diff --git a/src/main/java/com/alibaba/fastjson/util/AntiCollisionHashMap.java b/src/main/java/com/alibaba/fastjson/util/AntiCollisionHashMap.java index a97ea0093e..6844901f11 100644 --- a/src/main/java/com/alibaba/fastjson/util/AntiCollisionHashMap.java +++ b/src/main/java/com/alibaba/fastjson/util/AntiCollisionHashMap.java @@ -310,7 +310,6 @@ public V put(K key, V value) { if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; - e.recordAccess(this); return oldValue; } } @@ -328,7 +327,6 @@ private V putForNullKey(V value) { if (e.key == null) { V oldValue = e.value; e.value = value; - e.recordAccess(this); return oldValue; } } @@ -503,7 +501,6 @@ final Entry removeEntryForKey(Object key) { table[i] = next; else prev.next = next; - e.recordRemoval(this); return e; } prev = e; @@ -538,7 +535,6 @@ final Entry removeMapping(Object o) { table[i] = next; else prev.next = next; - e.recordRemoval(this); return e; } prev = e; @@ -655,8 +651,7 @@ public final boolean equals(Object o) { if (k1 == k2 || (k1 != null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue(); - if (v1 == v2 || (v1 != null && v1.equals(v2))) - return true; + return (v1 == v2 || (v1 != null && v1.equals(v2))); } return false; } @@ -670,19 +665,6 @@ public final String toString() { return getKey() + "=" + getValue(); } - /** - * This method is invoked whenever the value in an entry is overwritten - * by an invocation of put(k,v) for a key k that's already in the - * SafelyHashMap. - */ - void recordAccess(AntiCollisionHashMap m) { - } - - /** - * This method is invoked whenever the entry is removed from the table. - */ - void recordRemoval(AntiCollisionHashMap m) { - } } /** @@ -980,13 +962,4 @@ private void readObject(java.io.ObjectInputStream s) throws IOException, } } - // These methods are used when serializing HashSets - int capacity() { - return table.length; - } - - float loadFactor() { - return loadFactor; - } - } \ No newline at end of file diff --git a/src/main/java/com/alibaba/fastjson/util/BiFunction.java b/src/main/java/com/alibaba/fastjson/util/BiFunction.java new file mode 100644 index 0000000000..ce4673a508 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/BiFunction.java @@ -0,0 +1,13 @@ +package com.alibaba.fastjson.util; + +public interface BiFunction { + + /** + * Applies this function to the given arguments. + * + * @param t the first function argument + * @param u the second function argument + * @return the function result + */ + R apply(T t, U u); +} diff --git a/src/main/java/com/alibaba/fastjson/util/FieldInfo.java b/src/main/java/com/alibaba/fastjson/util/FieldInfo.java old mode 100755 new mode 100644 index 7e510bee56..1bfa0162a7 --- a/src/main/java/com/alibaba/fastjson/util/FieldInfo.java +++ b/src/main/java/com/alibaba/fastjson/util/FieldInfo.java @@ -12,8 +12,9 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; -import java.util.Arrays; +import java.util.Map; +import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.annotation.JSONField; public class FieldInfo implements Comparable { @@ -46,6 +47,8 @@ public class FieldInfo implements Comparable { public final String format; public final String[] alternateNames; + + public final long nameHashCode; public FieldInfo(String name, // Class declaringClass, // @@ -55,6 +58,10 @@ public FieldInfo(String name, // int ordinal, // int serialzeFeatures, // int parserFeatures){ + if (ordinal < 0) { + ordinal = 0; + } + this.name = name; this.declaringClass = declaringClass; this.fieldClass = fieldClass; @@ -83,32 +90,54 @@ public FieldInfo(String name, // } this.label = ""; - fieldAnnotation = null; + fieldAnnotation = field == null ? null : TypeUtils.getAnnotation(field, JSONField.class); methodAnnotation = null; this.getOnly = false; this.jsonDirect = false; this.unwrapped = false; this.format = null; this.alternateNames = new String[0]; + + nameHashCode = nameHashCode64(name, fieldAnnotation); } - public FieldInfo(String name, // - Method method, // - Field field, // - Class clazz, // - Type type, // - int ordinal, // - int serialzeFeatures, // + public FieldInfo(String name, // + Method method, // + Field field, // + Class clazz, // + Type type, // + int ordinal, // + int serialzeFeatures, // int parserFeatures, // - JSONField fieldAnnotation, // + JSONField fieldAnnotation, // JSONField methodAnnotation, // String label){ + this(name, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, + fieldAnnotation, methodAnnotation, label, null); + } + + public FieldInfo(String name, // + Method method, // + Field field, // + Class clazz, // + Type type, // + int ordinal, // + int serialzeFeatures, // + int parserFeatures, // + JSONField fieldAnnotation, // + JSONField methodAnnotation, // + String label, + Map genericInfo){ if (field != null) { String fieldName = field.getName(); if (fieldName.equals(name)) { name = fieldName; } } + + if (ordinal < 0) { + ordinal = 0; + } this.name = name; this.method = method; @@ -118,7 +147,7 @@ public FieldInfo(String name, // this.parserFeatures = parserFeatures; this.fieldAnnotation = fieldAnnotation; this.methodAnnotation = methodAnnotation; - + if (field != null) { int modifiers = field.getModifiers(); fieldAccess = ((modifiers & Modifier.PUBLIC) != 0 || method == null); @@ -126,7 +155,7 @@ public FieldInfo(String name, // || TypeUtils.isTransient(method); } else { fieldAccess = false; - fieldTransient = false; + fieldTransient = TypeUtils.isTransient(method); } if (label != null && label.length() > 0) { @@ -138,6 +167,8 @@ public FieldInfo(String name, // String format = null; JSONField annotation = getAnnotation(); + nameHashCode = nameHashCode64(name, annotation); + boolean jsonDirect = false; if (annotation != null) { format = annotation.format(); @@ -205,8 +236,8 @@ public FieldInfo(String name, // Type genericFieldType = fieldType; if (!(fieldType instanceof Class)) { - genericFieldType = getFieldType(clazz, type != null ? type : clazz, fieldType); - + genericFieldType = getFieldType(clazz, type != null ? type : clazz, fieldType, genericInfo); + if (genericFieldType != fieldType) { if (genericFieldType instanceof ParameterizedType) { fieldClass = TypeUtils.getClass(genericFieldType); @@ -221,7 +252,15 @@ public FieldInfo(String name, // isEnum = fieldClass.isEnum(); } - + + private long nameHashCode64(String name, JSONField annotation) + { + if (annotation != null && annotation.name().length() != 0) { + return TypeUtils.fnv1a_64_lower(name); + } + return TypeUtils.fnv1a_64_extract(name); + } + protected char[] genFieldNameChars() { int nameLen = this.name.length(); char[] name_chars = new char[nameLen + 3]; @@ -240,17 +279,21 @@ public T getAnnation(Class annotationClass) { T annotatition = null; if (method != null) { - annotatition = method.getAnnotation(annotationClass); + annotatition = TypeUtils.getAnnotation(method, annotationClass); } if (annotatition == null && field != null) { - annotatition = field.getAnnotation(annotationClass); + annotatition = TypeUtils.getAnnotation(field, annotationClass); } return annotatition; } - public static Type getFieldType(final Class clazz, final Type type, Type fieldType) { + public static Type getFieldType(final Class clazz, final Type type, Type fieldType){ + return getFieldType(clazz, type, fieldType, null); + } + + public static Type getFieldType(final Class clazz, final Type type, Type fieldType, Map genericInfo) { if (clazz == null || type == null) { return fieldType; } @@ -258,7 +301,7 @@ public static Type getFieldType(final Class clazz, final Type type, Type fiel if (fieldType instanceof GenericArrayType) { GenericArrayType genericArrayType = (GenericArrayType) fieldType; Type componentType = genericArrayType.getGenericComponentType(); - Type componentTypeX = getFieldType(clazz, type, componentType); + Type componentTypeX = getFieldType(clazz, type, componentType, genericInfo); if (componentType != componentTypeX) { Type fieldTypeX = Array.newInstance(TypeUtils.getClass(componentTypeX), 0).getClass(); return fieldTypeX; @@ -291,21 +334,29 @@ public static Type getFieldType(final Class clazz, final Type type, Type fiel Type[] arguments = parameterizedFieldType.getActualTypeArguments(); TypeVariable[] typeVariables; ParameterizedType paramType; - if (type instanceof ParameterizedType) { - paramType = (ParameterizedType) type; - typeVariables = clazz.getTypeParameters(); - } else if(clazz.getGenericSuperclass() instanceof ParameterizedType) { - paramType = (ParameterizedType) clazz.getGenericSuperclass(); - typeVariables = clazz.getSuperclass().getTypeParameters(); - } else { - paramType = parameterizedFieldType; - typeVariables = type.getClass().getTypeParameters(); + + boolean changed = getArgument(arguments, genericInfo); + //if genericInfo is not working use the old path; + if(!changed){ + if (type instanceof ParameterizedType) { + paramType = (ParameterizedType) type; + typeVariables = clazz.getTypeParameters(); + } else if(clazz.getGenericSuperclass() instanceof ParameterizedType) { + paramType = (ParameterizedType) clazz.getGenericSuperclass(); + typeVariables = clazz.getSuperclass().getTypeParameters(); + } else { + paramType = parameterizedFieldType; + typeVariables = type.getClass().getTypeParameters(); + } + + changed = getArgument(arguments, typeVariables, paramType.getActualTypeArguments()); } - boolean changed = getArgument(arguments, typeVariables, paramType.getActualTypeArguments()); if (changed) { - fieldType = new ParameterizedTypeImpl(arguments, parameterizedFieldType.getOwnerType(), - parameterizedFieldType.getRawType()); + fieldType = TypeReference.intern( + new ParameterizedTypeImpl(arguments, parameterizedFieldType.getOwnerType(), + parameterizedFieldType.getRawType()) + ); return fieldType; } } @@ -313,6 +364,34 @@ public static Type getFieldType(final Class clazz, final Type type, Type fiel return fieldType; } + private static boolean getArgument(Type[] typeArgs, Map genericInfo){ + if(genericInfo == null || genericInfo.size() == 0){ + return false; + } + boolean changed = false; + for (int i = 0; i < typeArgs.length; ++i) { + Type typeArg = typeArgs[i]; + if (typeArg instanceof ParameterizedType) { + ParameterizedType p_typeArg = (ParameterizedType) typeArg; + Type[] p_typeArg_args = p_typeArg.getActualTypeArguments(); + boolean p_changed = getArgument(p_typeArg_args, genericInfo); + if (p_changed) { + typeArgs[i] = TypeReference.intern( + new ParameterizedTypeImpl(p_typeArg_args, p_typeArg.getOwnerType(), p_typeArg.getRawType()) + ); + changed = true; + } + } else if (typeArg instanceof TypeVariable) { + if (genericInfo.containsKey(typeArg)) { + typeArgs[i] = genericInfo.get(typeArg); + changed = true; + } + } + } + + return changed; + } + private static boolean getArgument(Type[] typeArgs, TypeVariable[] typeVariables, Type[] arguments) { if (arguments == null || typeVariables.length == 0) { return false; @@ -326,7 +405,9 @@ private static boolean getArgument(Type[] typeArgs, TypeVariable[] typeVariables Type[] p_typeArg_args = p_typeArg.getActualTypeArguments(); boolean p_changed = getArgument(p_typeArg_args, typeVariables, arguments); if (p_changed) { - typeArgs[i] = new ParameterizedTypeImpl(p_typeArg_args, p_typeArg.getOwnerType(), p_typeArg.getRawType()); + typeArgs[i] = TypeReference.intern( + new ParameterizedTypeImpl(p_typeArg_args, p_typeArg.getOwnerType(), p_typeArg.getRawType()) + ); changed = true; } } else if (typeArg instanceof TypeVariable) { @@ -369,7 +450,7 @@ private static Type getInheritGenericType(Class clazz, Type type, TypeVariabl } } - if (arguments == null) { + if (arguments == null || class_gd == null) { return null; } @@ -410,6 +491,13 @@ protected Class getDeclaredClass() { } public int compareTo(FieldInfo o) { + // Deal extend bridge + if (o.method != null && this.method != null + && o.method.isBridge() && !this.method.isBridge() + && o.method.getName().equals(this.method.getName())) { + return 1; + } + if (this.ordinal < o.ordinal) { return -1; } @@ -436,7 +524,6 @@ public int compareTo(FieldInfo o) { return 1; } } - boolean isSampeType = this.field != null && this.field.getType() == this.fieldClass; boolean oSameType = o.field != null && o.field.getType() == o.fieldClass; diff --git a/src/main/java/com/alibaba/fastjson/util/Function.java b/src/main/java/com/alibaba/fastjson/util/Function.java new file mode 100644 index 0000000000..0d43533873 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/Function.java @@ -0,0 +1,10 @@ +package com.alibaba.fastjson.util; + +public interface Function { + /** + * Computes a result + * + * @return computed result + */ + V apply(ARG arg); +} diff --git a/src/main/java/com/alibaba/fastjson/util/GenericArrayTypeImpl.java b/src/main/java/com/alibaba/fastjson/util/GenericArrayTypeImpl.java new file mode 100644 index 0000000000..45e53e3dbe --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/GenericArrayTypeImpl.java @@ -0,0 +1,45 @@ +package com.alibaba.fastjson.util; + +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Type; + +public class GenericArrayTypeImpl implements GenericArrayType { + private final Type genericComponentType; + + public GenericArrayTypeImpl(Type genericComponentType) { + assert genericComponentType != null; + this.genericComponentType = genericComponentType; + } + + @Override + public Type getGenericComponentType() { + return this.genericComponentType; + } + + @Override + public String toString() { + Type genericComponentType = this.getGenericComponentType(); + StringBuilder builder = new StringBuilder(); + if (genericComponentType instanceof Class) { + builder.append(((Class) genericComponentType).getName()); + } else { + builder.append(genericComponentType.toString()); + } + builder.append("[]"); + return builder.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof GenericArrayType) { + GenericArrayType that = (GenericArrayType) obj; + return this.genericComponentType.equals(that.getGenericComponentType()); + } + return false; + } + + @Override + public int hashCode() { + return this.genericComponentType.hashCode(); + } +} diff --git a/src/main/java/com/alibaba/fastjson/util/IOUtils.java b/src/main/java/com/alibaba/fastjson/util/IOUtils.java old mode 100755 new mode 100644 index 76df6cfda6..1269b2aef4 --- a/src/main/java/com/alibaba/fastjson/util/IOUtils.java +++ b/src/main/java/com/alibaba/fastjson/util/IOUtils.java @@ -37,20 +37,14 @@ */ public class IOUtils { - public final static String FASTJSON_PROPERTIES ="fastjson.properties"; - - public final static String FASTJSON_COMPATIBLEWITHJAVABEAN="fastjson.compatibleWithJavaBean"; - - public final static String FASTJSON_COMPATIBLEWITHFIELDNAME="fastjson.compatibleWithFieldName"; - - public final static Properties DEFAULT_PROPERTIES =new Properties(); - - public final static Charset UTF8 = Charset.forName("UTF-8"); - - public final static char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', - 'B', 'C', 'D', 'E', 'F' }; - - public final static boolean[] firstIdentifierFlags = new boolean[256]; + public final static String FASTJSON_PROPERTIES = "fastjson.properties"; + public final static String FASTJSON_COMPATIBLEWITHJAVABEAN = "fastjson.compatibleWithJavaBean"; + public final static String FASTJSON_COMPATIBLEWITHFIELDNAME = "fastjson.compatibleWithFieldName"; + public final static Properties DEFAULT_PROPERTIES = new Properties(); + public final static Charset UTF8 = Charset.forName("UTF-8"); + public final static char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + public final static boolean[] firstIdentifierFlags = new boolean[256]; + public final static boolean[] identifierFlags = new boolean[256]; static { for (char c = 0; c < firstIdentifierFlags.length; ++c) { if (c >= 'A' && c <= 'Z') { @@ -61,11 +55,7 @@ public class IOUtils { firstIdentifierFlags[c] = true; } } - } - public final static boolean[] identifierFlags = new boolean[256]; - - static { for (char c = 0; c < identifierFlags.length; ++c) { if (c >= 'A' && c <= 'Z') { identifierFlags[c] = true; @@ -77,9 +67,7 @@ public class IOUtils { identifierFlags[c] = true; } } - } - - static { + try { loadPropertiesFromFile(); } catch (Throwable e) { @@ -404,7 +392,8 @@ public static boolean isIdent(char ch) { * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within * the encoded string
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
- * + * + * @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11 * @param chars The source array. Length 0 will return an empty array. null will throw an exception. * @return The decoded array of bytes. May be of length 0. */ @@ -462,7 +451,10 @@ public static byte[] decodeBase64(char[] chars, int offset, int charsLen) { return bytes; } - + + /** + * @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11 + */ public static byte[] decodeBase64(String chars, int offset, int charsLen) { // Check special case if (charsLen == 0) { @@ -491,7 +483,10 @@ public static byte[] decodeBase64(String chars, int offset, int charsLen) { int d = 0; for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { // Assemble three bytes into an int from four "valid" characters. - int i = IA[chars.charAt(sIx++)] << 18 | IA[chars.charAt(sIx++)] << 12 | IA[chars.charAt(sIx++)] << 6 | IA[chars.charAt(sIx++)]; + int i = IA[chars.charAt(sIx++)] << 18 + | IA[chars.charAt(sIx++)] << 12 + | IA[chars.charAt(sIx++)] << 6 + | IA[chars.charAt(sIx++)]; // Add the bytes bytes[d++] = (byte) (i >> 16); @@ -525,7 +520,8 @@ public static byte[] decodeBase64(String chars, int offset, int charsLen) { * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within * the encoded string
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
- * + * + * @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11 * @param s The source string. Length 0 will return an empty array. null will throw an exception. * @return The decoded array of bytes. May be of length 0. */ @@ -608,20 +604,26 @@ public static int encodeUTF8(char[] chars, int offset, int len, byte[] bytes) { } else if (c >= '\uD800' && c < ('\uDFFF' + 1)) { //Character.isSurrogate(c) but 1.7 final int uc; int ip = offset - 1; - if (Character.isHighSurrogate(c)) { + if (c >= '\uD800' && c < ('\uDBFF' + 1)) { // Character.isHighSurrogate(c) if (sl - ip < 2) { uc = -1; } else { char d = chars[ip + 1]; - if (Character.isLowSurrogate(d)) { - uc = Character.toCodePoint(c, d); + // d >= '\uDC00' && d < ('\uDFFF' + 1) + if (d >= '\uDC00' && d < ('\uDFFF' + 1)) { // Character.isLowSurrogate(d) + uc = ((c << 10) + d) + (0x010000 - ('\uD800' << 10) - '\uDC00'); // Character.toCodePoint(c, d) } else { - throw new JSONException("encodeUTF8 error", new MalformedInputException(1)); +// throw new JSONException("encodeUTF8 error", new MalformedInputException(1)); + bytes[dp++] = (byte) '?'; + continue; } } } else { - if (Character.isLowSurrogate(c)) { - throw new JSONException("encodeUTF8 error", new MalformedInputException(1)); + // + if (c >= '\uDC00' && c < ('\uDFFF' + 1)) { // Character.isLowSurrogate(c) + bytes[dp++] = (byte) '?'; + continue; +// throw new JSONException("encodeUTF8 error", new MalformedInputException(1)); } else { uc = c; } @@ -693,7 +695,7 @@ public static int decodeUTF8(byte[] sa, int sp, int len, char[] da) { (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80 << 0)))); - boolean isSurrogate = c >= Character.MIN_SURROGATE && c < (Character.MAX_SURROGATE + 1); + boolean isSurrogate = c >= '\uD800' && c < ('\uDFFF' + 1); if (isSurrogate) { return -1; } else { @@ -720,11 +722,12 @@ public static int decodeUTF8(byte[] sa, int sp, int len, char[] da) { if (((b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 || (b4 & 0xc0) != 0x80) // isMalformed4 || // shortest form check - !Character.isSupplementaryCodePoint(uc)) { + !(uc >= 0x010000 && uc < 0X10FFFF + 1) // !Character.isSupplementaryCodePoint(uc) + ) { return -1; } else { - da[dp++] = (char) ((uc >>> 10) + (Character.MIN_HIGH_SURROGATE - (Character.MIN_SUPPLEMENTARY_CODE_POINT >>> 10))); // Character.highSurrogate(uc); - da[dp++] = (char) ((uc & 0x3ff) + Character.MIN_LOW_SURROGATE); // Character.lowSurrogate(uc); + da[dp++] = (char) ((uc >>> 10) + ('\uD800' - (0x010000 >>> 10))); // Character.highSurrogate(uc); + da[dp++] = (char) ((uc & 0x3ff) + '\uDC00'); // Character.lowSurrogate(uc); } continue; } diff --git a/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java b/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java old mode 100755 new mode 100644 index 94dfe1c595..087b6fc446 --- a/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java +++ b/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java @@ -15,7 +15,7 @@ */ package com.alibaba.fastjson.util; -import java.util.Collections; +import java.util.Arrays; /** * for concurrent IdentityHashMap @@ -106,4 +106,18 @@ public Entry(K key, V value, int hash, Entry next){ } } + public void clear() { + Arrays.fill(this.buckets, null); + } + + public int size() { + int count = 0; + for (Entry bucket : this.buckets) { + for (; bucket != null; bucket = bucket.next) { + count++; + } + } + + return count; + } } diff --git a/src/main/java/com/alibaba/fastjson/util/JavaBeanInfo.java b/src/main/java/com/alibaba/fastjson/util/JavaBeanInfo.java index 2dda5326a8..e28413c94f 100644 --- a/src/main/java/com/alibaba/fastjson/util/JavaBeanInfo.java +++ b/src/main/java/com/alibaba/fastjson/util/JavaBeanInfo.java @@ -1,16 +1,13 @@ package com.alibaba.fastjson.util; import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; +import java.lang.reflect.*; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.PropertyNamingStrategy; import com.alibaba.fastjson.annotation.JSONCreator; @@ -46,6 +43,9 @@ public class JavaBeanInfo { public Type[] creatorConstructorParameterTypes; public String[] creatorConstructorParameters; + public boolean kotlin; + public Constructor kotlinDefaultConstructor; + public JavaBeanInfo(Class clazz, // Class builderClass, // Constructor defaultConstructor, // @@ -121,42 +121,49 @@ public JavaBeanInfo(Class clazz, // if (creatorConstructor != null) { this.creatorConstructorParameterTypes = creatorConstructor.getParameterTypes(); - boolean match; - if (creatorConstructorParameterTypes.length != fields.length) { - match = false; - } else { - match = true; - for (int i = 0; i < creatorConstructorParameterTypes.length; i++) { - if (creatorConstructorParameterTypes[i] != fields[i].fieldClass) { - match = false; - break; - } - } - } - if (!match) { - boolean kotlin = TypeUtils.isKotlin(clazz); - if (kotlin) { - this.creatorConstructorParameters = TypeUtils.getKoltinConstructorParameters(clazz); - Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations(); - for (int i = 0; i < creatorConstructorParameters.length && i < paramAnnotationArrays.length; ++i) { - Annotation[] paramAnnotations = paramAnnotationArrays[i]; - JSONField fieldAnnotation = null; - for (Annotation paramAnnotation : paramAnnotations) { - if (paramAnnotation instanceof JSONField) { - fieldAnnotation = (JSONField) paramAnnotation; - break; - } + kotlin = TypeUtils.isKotlin(clazz); + if (kotlin) { + this.creatorConstructorParameters = TypeUtils.getKoltinConstructorParameters(clazz); + try { + this.kotlinDefaultConstructor = clazz.getConstructor(); + } catch (Throwable ex) { + // skip + } + + Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor); + for (int i = 0; i < creatorConstructorParameters.length && i < paramAnnotationArrays.length; ++i) { + Annotation[] paramAnnotations = paramAnnotationArrays[i]; + JSONField fieldAnnotation = null; + for (Annotation paramAnnotation : paramAnnotations) { + if (paramAnnotation instanceof JSONField) { + fieldAnnotation = (JSONField) paramAnnotation; + break; } - if (fieldAnnotation != null) { - String fieldAnnotationName = fieldAnnotation.name(); - if (fieldAnnotationName.length() > 0) { - creatorConstructorParameters[i] = fieldAnnotationName; - } + } + if (fieldAnnotation != null) { + String fieldAnnotationName = fieldAnnotation.name(); + if (fieldAnnotationName.length() > 0) { + creatorConstructorParameters[i] = fieldAnnotationName; } } + } + } else { + boolean match; + if (creatorConstructorParameterTypes.length != fields.length) { + match = false; } else { + match = true; + for (int i = 0; i < creatorConstructorParameterTypes.length; i++) { + if (creatorConstructorParameterTypes[i] != fields[i].fieldClass) { + match = false; + break; + } + } + } + + if (!match) { this.creatorConstructorParameters = ASMUtils.lookupParameterNames(creatorConstructor); } } @@ -188,15 +195,15 @@ static boolean add(List fieldList, FieldInfo field) { } if (item.fieldClass.isAssignableFrom(field.fieldClass)) { - fieldList.remove(i); - break; + fieldList.set(i, field); + return true; } int result = item.compareTo(field); if (result < 0) { - fieldList.remove(i); - break; + fieldList.set(i, field); + return true; } else { return false; } @@ -208,7 +215,50 @@ static boolean add(List fieldList, FieldInfo field) { } public static JavaBeanInfo build(Class clazz, Type type, PropertyNamingStrategy propertyNamingStrategy) { - return build(clazz, type, propertyNamingStrategy, false, TypeUtils.compatibleWithJavaBean); + return build(clazz, type, propertyNamingStrategy, false, TypeUtils.compatibleWithJavaBean, false); + } + + private static Map buildGenericInfo(Class clazz) { + Class childClass = clazz; + Class currentClass = clazz.getSuperclass(); + if (currentClass == null) { + return null; + } + + Map typeVarMap = null; + + //analyse the whole generic info from the class inheritance + for (; currentClass != null && currentClass != Object.class; childClass = currentClass, currentClass = currentClass.getSuperclass()) { + if (childClass.getGenericSuperclass() instanceof ParameterizedType) { + Type[] childGenericParentActualTypeArgs = ((ParameterizedType) childClass.getGenericSuperclass()).getActualTypeArguments(); + TypeVariable[] currentTypeParameters = currentClass.getTypeParameters(); + for (int i = 0; i < childGenericParentActualTypeArgs.length; i++) { + //if the child class's generic super class actual args is defined in the child class type parameters + if (typeVarMap == null) { + typeVarMap = new HashMap(); + } + + if (typeVarMap.containsKey(childGenericParentActualTypeArgs[i])) { + Type actualArg = typeVarMap.get(childGenericParentActualTypeArgs[i]); + typeVarMap.put(currentTypeParameters[i], actualArg); + } else { + typeVarMap.put(currentTypeParameters[i], childGenericParentActualTypeArgs[i]); + } + } + } + } + + return typeVarMap; + } + + + public static JavaBeanInfo build(Class clazz // + , Type type // + , PropertyNamingStrategy propertyNamingStrategy // + , boolean fieldBased // + , boolean compatibleWithJavaBean + ) { + return build(clazz, type, propertyNamingStrategy, fieldBased, compatibleWithJavaBean, false); } public static JavaBeanInfo build(Class clazz // @@ -216,6 +266,7 @@ public static JavaBeanInfo build(Class clazz // , PropertyNamingStrategy propertyNamingStrategy // , boolean fieldBased // , boolean compatibleWithJavaBean + , boolean jacksonCompatible ) { JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class); if (jsonType != null) { @@ -229,6 +280,7 @@ public static JavaBeanInfo build(Class clazz // Field[] declaredFields = clazz.getDeclaredFields(); Method[] methods = clazz.getMethods(); + Map genericInfo = buildGenericInfo(clazz); boolean kotlin = TypeUtils.isKotlin(clazz); Constructor[] constructors = clazz.getDeclaredConstructors(); @@ -254,20 +306,43 @@ public static JavaBeanInfo build(Class clazz // computeFields(clazz, type, propertyNamingStrategy, fieldList, fields); } + + if (defaultConstructor != null) { + TypeUtils.setAccessible(defaultConstructor); + } + return new JavaBeanInfo(clazz, builderClass, defaultConstructor, null, factoryMethod, buildMethod, jsonType, fieldList); } boolean isInterfaceOrAbstract = clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()); if ((defaultConstructor == null && builderClass == null) || isInterfaceOrAbstract) { - creatorConstructor = getCreatorConstructor(constructors); + + Type mixInType = JSON.getMixInAnnotations(clazz); + if (mixInType instanceof Class) { + Constructor[] mixInConstructors = ((Class) mixInType).getConstructors(); + Constructor mixInCreator = getCreatorConstructor(mixInConstructors); + if (mixInCreator != null) { + try { + creatorConstructor = clazz.getConstructor(mixInCreator.getParameterTypes()); + } catch (NoSuchMethodException e) { + // skip + } + } + } + + if (creatorConstructor == null) { + creatorConstructor = getCreatorConstructor(constructors); + } if (creatorConstructor != null && !isInterfaceOrAbstract) { // 基于标记 JSONCreator 注解的构造方法 TypeUtils.setAccessible(creatorConstructor); Class[] types = creatorConstructor.getParameterTypes(); + + String[] lookupParameterNames = null; if (types.length > 0) { - Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations(); - for (int i = 0; i < types.length; ++i) { + Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor); + for (int i = 0; i < types.length && i < paramAnnotationArrays.length; ++i) { Annotation[] paramAnnotations = paramAnnotationArrays[i]; JSONField fieldAnnotation = null; for (Annotation paramAnnotation : paramAnnotations) { @@ -276,28 +351,57 @@ public static JavaBeanInfo build(Class clazz // break; } } - if (fieldAnnotation == null) { - throw new JSONException("illegal json creator"); - } + Class fieldClass = types[i]; Type fieldType = creatorConstructor.getGenericParameterTypes()[i]; - Field field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields); - final int ordinal = fieldAnnotation.ordinal(); - final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); - final int parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); - FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field, + + String fieldName = null; + Field field = null; + int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; + if (fieldAnnotation != null) { + field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields); + ordinal = fieldAnnotation.ordinal(); + serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); + fieldName = fieldAnnotation.name(); + } + + if (fieldName == null || fieldName.length() == 0) { + if (lookupParameterNames == null) { + lookupParameterNames = ASMUtils.lookupParameterNames(creatorConstructor); + } + fieldName = lookupParameterNames[i]; + } + + if (field == null) { + if (lookupParameterNames == null) { + if (kotlin) { + lookupParameterNames = TypeUtils.getKoltinConstructorParameters(clazz); + } else { + lookupParameterNames = ASMUtils.lookupParameterNames(creatorConstructor); + } + } + + if (lookupParameterNames.length > i) { + String parameterName = lookupParameterNames[i]; + field = TypeUtils.getField(clazz, parameterName, declaredFields); + } + } + + FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures); add(fieldList, fieldInfo); } } //return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList); - } else if ((factoryMethod = getFactoryMethod(clazz, methods)) != null) { + } else if ((factoryMethod = getFactoryMethod(clazz, methods, jacksonCompatible)) != null) { TypeUtils.setAccessible(factoryMethod); + String[] lookupParameterNames = null; Class[] types = factoryMethod.getParameterTypes(); if (types.length > 0) { - Annotation[][] paramAnnotationArrays = factoryMethod.getParameterAnnotations(); + Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(factoryMethod); for (int i = 0; i < types.length; ++i) { Annotation[] paramAnnotations = paramAnnotationArrays[i]; JSONField fieldAnnotation = null; @@ -307,17 +411,32 @@ public static JavaBeanInfo build(Class clazz // break; } } - if (fieldAnnotation == null) { + if (fieldAnnotation == null && !(jacksonCompatible && TypeUtils.isJacksonCreator(factoryMethod))) { throw new JSONException("illegal json creator"); } + String fieldName = null; + int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; + + if (fieldAnnotation != null) { + fieldName = fieldAnnotation.name(); + ordinal = fieldAnnotation.ordinal(); + serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); + } + + if (fieldName == null || fieldName.length() == 0) { + if (lookupParameterNames == null) { + lookupParameterNames = ASMUtils.lookupParameterNames(factoryMethod); + } + fieldName = lookupParameterNames[i]; + } + Class fieldClass = types[i]; Type fieldType = factoryMethod.getGenericParameterTypes()[i]; - Field field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields); - final int ordinal = fieldAnnotation.ordinal(); - final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); - final int parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); - FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field, + + Field field = TypeUtils.getField(clazz, fieldName, declaredFields); + FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures); add(fieldList, fieldInfo); } @@ -330,7 +449,7 @@ public static JavaBeanInfo build(Class clazz // String[] paramNames = null; if (kotlin && constructors.length > 0) { paramNames = TypeUtils.getKoltinConstructorParameters(clazz); - creatorConstructor = TypeUtils.getKoltinConstructor(constructors); + creatorConstructor = TypeUtils.getKotlinConstructor(constructors, paramNames); TypeUtils.setAccessible(creatorConstructor); } else { @@ -343,6 +462,8 @@ public static JavaBeanInfo build(Class clazz // creatorConstructor.setAccessible(true); paramNames = ASMUtils.lookupParameterNames(constructor); break; + } else { + continue; } } @@ -355,6 +476,8 @@ public static JavaBeanInfo build(Class clazz // creatorConstructor.setAccessible(true); paramNames = new String[] {"principal", "credentials", "authorities"}; break; + } else { + continue; } } @@ -364,6 +487,8 @@ public static JavaBeanInfo build(Class clazz // creatorConstructor = constructor; paramNames = new String[] {"authority"}; break; + } else { + continue; } } @@ -396,7 +521,7 @@ public static JavaBeanInfo build(Class clazz // if (paramNames != null && types.length == paramNames.length) { - Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations(); + Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor); for (int i = 0; i < types.length; ++i) { Annotation[] paramAnnotations = paramAnnotationArrays[i]; String paramName = paramNames[i]; @@ -414,7 +539,7 @@ public static JavaBeanInfo build(Class clazz // Field field = TypeUtils.getField(clazz, paramName, declaredFields); if (field != null) { if (fieldAnnotation == null) { - fieldAnnotation = field.getAnnotation(JSONField.class); + fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class); } } final int ordinal, serialzeFeatures, parserFeatures; @@ -442,8 +567,7 @@ public static JavaBeanInfo build(Class clazz // add(fieldList, fieldInfo); } - if ((!kotlin) - && !clazz.getName().equals("javax.servlet.http.Cookie")) { + if ((!kotlin) && !clazz.getName().equals("javax.servlet.http.Cookie")) { return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList); } } else { @@ -459,12 +583,12 @@ public static JavaBeanInfo build(Class clazz // if (builderClass != null) { String withPrefix = null; - JSONPOJOBuilder builderAnno = builderClass.getAnnotation(JSONPOJOBuilder.class); + JSONPOJOBuilder builderAnno = TypeUtils.getAnnotation(builderClass, JSONPOJOBuilder.class); if (builderAnno != null) { withPrefix = builderAnno.withPrefix(); } - if (withPrefix == null || withPrefix.length() == 0) { + if (withPrefix == null) { withPrefix = "with"; } @@ -479,7 +603,7 @@ public static JavaBeanInfo build(Class clazz // int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; - JSONField annotation = method.getAnnotation(JSONField.class); + JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class); if (annotation == null) { annotation = TypeUtils.getSuperMethodAnnotation(clazz, method); @@ -497,7 +621,7 @@ public static JavaBeanInfo build(Class clazz // if (annotation.name().length() != 0) { String propertyName = annotation.name(); add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, - annotation, null, null)); + annotation, null, null, genericInfo)); continue; } } @@ -507,19 +631,23 @@ public static JavaBeanInfo build(Class clazz // if (methodName.startsWith("set") && methodName.length() > 3) { properNameBuilder = new StringBuilder(methodName.substring(3)); } else { - if (!methodName.startsWith(withPrefix)) { - continue; - } + if (withPrefix.length() == 0){ + properNameBuilder = new StringBuilder(methodName); + } else { + if (!methodName.startsWith(withPrefix)) { + continue; + } - if (methodName.length() <= withPrefix.length()) { - continue; + if (methodName.length() <= withPrefix.length()) { + continue; + } + + properNameBuilder = new StringBuilder(methodName.substring(withPrefix.length())); } - - properNameBuilder = new StringBuilder(methodName.substring(withPrefix.length())); } char c0 = properNameBuilder.charAt(0); - if (!Character.isUpperCase(c0)) { + if (withPrefix.length() != 0 && !Character.isUpperCase(c0)) { continue; } @@ -528,11 +656,11 @@ public static JavaBeanInfo build(Class clazz // String propertyName = properNameBuilder.toString(); add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, - annotation, null, null)); + annotation, null, null, genericInfo)); } if (builderClass != null) { - JSONPOJOBuilder builderAnnotation = builderClass.getAnnotation(JSONPOJOBuilder.class); + JSONPOJOBuilder builderAnnotation = TypeUtils.getAnnotation(builderClass, JSONPOJOBuilder.class); String buildMethodName = null; if (builderAnnotation != null) { @@ -593,13 +721,13 @@ public static JavaBeanInfo build(Class clazz // continue; } - JSONField annotation = method.getAnnotation(JSONField.class); + JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class); if (annotation != null && types.length == 2 && types[0] == String.class && types[1] == Object.class) { add(fieldList, new FieldInfo("", method, null, clazz, type, ordinal, - serialzeFeatures, parserFeatures, annotation, null, null)); + serialzeFeatures, parserFeatures, annotation, null, null, genericInfo)); continue; } @@ -627,37 +755,87 @@ public static JavaBeanInfo build(Class clazz // if (annotation.name().length() != 0) { String propertyName = annotation.name(); add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, - annotation, null, null)); + annotation, null, null, genericInfo)); continue; } } - if (annotation == null && !methodName.startsWith("set")) { // TODO "set"的判断放在 JSONField 注解后面,意思是允许非 setter 方法标记 JSONField 注解? + if (annotation == null && !methodName.startsWith("set") || builderClass != null) { // TODO "set"的判断放在 JSONField 注解后面,意思是允许非 setter 方法标记 JSONField 注解? continue; } char c3 = methodName.charAt(3); String propertyName; + Field field = null; + // 用于存储KotlinBean中所有的get方法, 方便后续判断 + List getMethodNameList = null; + + if (kotlin) { + getMethodNameList = new ArrayList(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().startsWith("get")) { + getMethodNameList.add(methods[i].getName()); + } + } + } + if (Character.isUpperCase(c3) // || c3 > 512 // for unicode method name ) { - if (TypeUtils.compatibleWithJavaBean) { - propertyName = TypeUtils.decapitalize(methodName.substring(3)); + // 这里本身的逻辑是通过setAbc这类方法名解析出成员变量名为abc或者Abc, 但是在kotlin中, isAbc, abc成员变量的set方法都是setAbc + // 因此如果是kotlin的话还需要进行不一样的判断, 判断的方式是通过get方法进行判断, isAbc的get方法名为isAbc(), abc的get方法名为getAbc() + if (kotlin) { + String getMethodName = "g" + methodName.substring(1); + propertyName = TypeUtils.getPropertyNameByMethodName(getMethodName); } else { - propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + if (TypeUtils.compatibleWithJavaBean) { + propertyName = TypeUtils.decapitalize(methodName.substring(3)); + } else { + propertyName = TypeUtils.getPropertyNameByMethodName(methodName); + } } + } else if (c3 == '_') { - propertyName = methodName.substring(4); + // 这里本身的逻辑是通过set_abc这类方法名解析出成员变量名为abc, 但是在kotlin中, is_abc和_abc成员变量的set方法都是set_abc + // 因此如果是kotlin的话还需要进行不一样的判断, 判断的方式是通过get方法进行判断, is_abc的get方法名为is_abc(), _abc的get方法名为get_abc() + if (kotlin) { + String getMethodName = "g" + methodName.substring(1); + if (getMethodNameList.contains(getMethodName)) { + propertyName = methodName.substring(3); + } else { + propertyName = "is" + methodName.substring(3); + } + field = TypeUtils.getField(clazz, propertyName, declaredFields); + } else { + propertyName = methodName.substring(4); + field = TypeUtils.getField(clazz, propertyName, declaredFields); + if (field == null) { + String temp = propertyName; + propertyName = methodName.substring(3); + field = TypeUtils.getField(clazz, propertyName, declaredFields); + if (field == null) { + propertyName = temp; //减少修改代码带来的影响 + } + } + } + } else if (c3 == 'f') { propertyName = methodName.substring(3); } else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) { propertyName = TypeUtils.decapitalize(methodName.substring(3)); } else { - continue; + propertyName = methodName.substring(3); + field = TypeUtils.getField(clazz, propertyName, declaredFields); + if (field == null) { + continue; + } + } + + if (field == null) { + field = TypeUtils.getField(clazz, propertyName, declaredFields); } - Field field = TypeUtils.getField(clazz, propertyName, declaredFields); if (field == null && types[0] == boolean.class) { String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1); field = TypeUtils.getField(clazz, isFieldName, declaredFields); @@ -665,7 +843,7 @@ public static JavaBeanInfo build(Class clazz // JSONField fieldAnnotation = null; if (field != null) { - fieldAnnotation = field.getAnnotation(JSONField.class); + fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class); if (fieldAnnotation != null) { if (!fieldAnnotation.deserialize()) { @@ -679,7 +857,7 @@ public static JavaBeanInfo build(Class clazz // if (fieldAnnotation.name().length() != 0) { propertyName = fieldAnnotation.name(); add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, - serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null)); + serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null, genericInfo)); continue; } } @@ -691,7 +869,7 @@ public static JavaBeanInfo build(Class clazz // } add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, - annotation, fieldAnnotation, null)); + annotation, fieldAnnotation, null, genericInfo)); } Field[] fields = clazz.getFields(); @@ -719,8 +897,9 @@ public static JavaBeanInfo build(Class clazz // || AtomicLong.class == method.getReturnType() // ) { String propertyName; + Field collectionField = null; - JSONField annotation = method.getAnnotation(JSONField.class); + JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class); if (annotation != null && annotation.deserialize()) { continue; } @@ -728,27 +907,44 @@ public static JavaBeanInfo build(Class clazz // if (annotation != null && annotation.name().length() > 0) { propertyName = annotation.name(); } else { - propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + propertyName = TypeUtils.getPropertyNameByMethodName(methodName); Field field = TypeUtils.getField(clazz, propertyName, declaredFields); if (field != null) { - JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + JSONField fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class); if (fieldAnnotation != null && !fieldAnnotation.deserialize()) { continue; } + + if (Collection.class.isAssignableFrom(method.getReturnType()) + || Map.class.isAssignableFrom(method.getReturnType())) { + collectionField = field; + } } } + if (propertyNamingStrategy != null) { + propertyName = propertyNamingStrategy.translate(propertyName); + } + FieldInfo fieldInfo = getField(fieldList, propertyName); if (fieldInfo != null) { continue; } - if (propertyNamingStrategy != null) { - propertyName = propertyNamingStrategy.translate(propertyName); - } + add(fieldList, new FieldInfo(propertyName, method, collectionField, clazz, type, 0, 0, 0, annotation, null, null, genericInfo)); + } + } + } + + if (fieldList.size() == 0) { + if (TypeUtils.isXmlField(clazz)) { + fieldBased = true; + } - add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, 0, 0, 0, annotation, null, null)); + if (fieldBased) { + for (Class currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) { + computeFields(clazz, type, propertyNamingStrategy, fieldList, declaredFields); } } } @@ -757,6 +953,8 @@ public static JavaBeanInfo build(Class clazz // } private static void computeFields(Class clazz, Type type, PropertyNamingStrategy propertyNamingStrategy, List fieldList, Field[] fields) { + Map genericInfo = buildGenericInfo(clazz); + for (Field field : fields) { // public static fields int modifiers = field.getModifiers(); if ((modifiers & Modifier.STATIC) != 0) { @@ -790,7 +988,7 @@ private static void computeFields(Class clazz, Type type, PropertyNamingStrat int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; String propertyName = field.getName(); - JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + JSONField fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class); if (fieldAnnotation != null) { if (!fieldAnnotation.deserialize()) { @@ -811,7 +1009,7 @@ private static void computeFields(Class clazz, Type type, PropertyNamingStrat } add(fieldList, new FieldInfo(propertyName, null, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, null, - fieldAnnotation, null)); + fieldAnnotation, null, genericInfo)); } } @@ -864,7 +1062,8 @@ public static Constructor getCreatorConstructor(Constructor[] constructors) { } for (Constructor constructor : constructors) { - Annotation[][] paramAnnotationArrays = constructor.getParameterAnnotations(); + Annotation[][] paramAnnotationArrays = TypeUtils.getParameterAnnotations(constructor); + if (paramAnnotationArrays.length == 0) { continue; } @@ -892,14 +1091,10 @@ public static Constructor getCreatorConstructor(Constructor[] constructors) { } } - if (creatorConstructor != null) { - return creatorConstructor; - } - return creatorConstructor; } - private static Method getFactoryMethod(Class clazz, Method[] methods) { + private static Method getFactoryMethod(Class clazz, Method[] methods, boolean jacksonCompatible) { Method factoryMethod = null; for (Method method : methods) { @@ -911,7 +1106,7 @@ private static Method getFactoryMethod(Class clazz, Method[] methods) { continue; } - JSONCreator annotation = method.getAnnotation(JSONCreator.class); + JSONCreator annotation = TypeUtils.getAnnotation(method, JSONCreator.class); if (annotation != null) { if (factoryMethod != null) { throw new JSONException("multi-JSONCreator"); @@ -921,9 +1116,21 @@ private static Method getFactoryMethod(Class clazz, Method[] methods) { // 不应该break,否则多个静态工厂方法上存在 JSONCreator 注解时,并不会触发上述异常抛出 } } + + if (factoryMethod == null && jacksonCompatible) { + for (Method method : methods) { + if (TypeUtils.isJacksonCreator(method)) { + factoryMethod = method; + break; + } + } + } return factoryMethod; } + /** + * @deprecated + */ public static Class getBuilderClass(JSONType type) { return getBuilderClass(null, type); } diff --git a/src/main/java/com/alibaba/fastjson/util/ModuleUtil.java b/src/main/java/com/alibaba/fastjson/util/ModuleUtil.java new file mode 100644 index 0000000000..2468be5662 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/ModuleUtil.java @@ -0,0 +1,41 @@ +package com.alibaba.fastjson.util; + +import java.util.concurrent.Callable; + +public class ModuleUtil { + private static boolean hasJavaSql = false; + + static { + try { + Class.forName("java.sql.Time"); + hasJavaSql = true; + } catch (Throwable e) { + hasJavaSql = false; + } + } + + public static T callWhenHasJavaSql(Callable callable) { + if (hasJavaSql) { + try { + return callable.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + return null; + } + + public static T callWhenHasJavaSql(Function callable, ARG arg) { + if (hasJavaSql) { + return callable.apply(arg); + } + return null; + } + + public static R callWhenHasJavaSql(BiFunction callable, T t, U u) { + if (hasJavaSql) { + return callable.apply(t, u); + } + return null; + } +} diff --git a/src/main/java/com/alibaba/fastjson/util/ParameterizedTypeImpl.java b/src/main/java/com/alibaba/fastjson/util/ParameterizedTypeImpl.java old mode 100755 new mode 100644 diff --git a/src/main/java/com/alibaba/fastjson/util/RyuDouble.java b/src/main/java/com/alibaba/fastjson/util/RyuDouble.java new file mode 100644 index 0000000000..758477c3a0 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/RyuDouble.java @@ -0,0 +1,580 @@ +// Copyright 2018 Ulf Adams +// +// 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. + +package com.alibaba.fastjson.util; + +import java.math.BigInteger; + +/** + * An implementation of Ryu for double. + */ +public final class RyuDouble { + private static final int[][] POW5_SPLIT = new int[326][4]; + private static final int[][] POW5_INV_SPLIT = new int[291][4]; + + static { + BigInteger mask = BigInteger.ONE.shiftLeft(31).subtract(BigInteger.ONE); + BigInteger invMask = BigInteger.ONE.shiftLeft(31).subtract(BigInteger.ONE); + for (int i = 0; i < 326; i++) { + BigInteger pow = BigInteger.valueOf(5).pow(i); + int pow5len = pow.bitLength(); + int expectedPow5Bits = i == 0 ? 1 : (int) ((i * 23219280L + 10000000L - 1) / 10000000L); + if (expectedPow5Bits != pow5len) { + throw new IllegalStateException(pow5len + " != " + expectedPow5Bits); + } + if (i < POW5_SPLIT.length) { + for (int j = 0; j < 4; j++) { + POW5_SPLIT[i][j] = pow + .shiftRight(pow5len - 121 + (3 - j) * 31) + .and(mask) + .intValue(); + } + } + + if (i < POW5_INV_SPLIT.length) { + // We want floor(log_2 5^q) here, which is pow5len - 1. + int j = pow5len + 121; + BigInteger inv = BigInteger.ONE + .shiftLeft(j) + .divide(pow) + .add(BigInteger.ONE); + for (int k = 0; k < 4; k++) { + if (k == 0) { + POW5_INV_SPLIT[i][k] = inv + .shiftRight((3 - k) * 31) + .intValue(); + } else { + POW5_INV_SPLIT[i][k] = inv + .shiftRight((3 - k) * 31) + .and(invMask) + .intValue(); + } + } + } + } + } + + public static String toString(double value) { + char[] result = new char[24]; + int len = toString(value, result, 0); + return new String(result, 0, len); + } + + public static int toString(double value, char[] result, int off) { + final long DOUBLE_MANTISSA_MASK = 4503599627370495L; // (1L << 52) - 1; + final int DOUBLE_EXPONENT_MASK = 2047; // (1 << 11) - 1; + final int DOUBLE_EXPONENT_BIAS = 1023; // (1 << (11 - 1)) - 1; + final long LOG10_5_NUMERATOR = 6989700L; // (long) (10000000L * Math.log10(5)); + final long LOG10_2_NUMERATOR = 3010299L; // (long) (10000000L * Math.log10(2)); + + // Step 1: Decode the floating point number, and unify normalized and subnormal cases. + // First, handle all the trivial cases. + int index = off; + if (Double.isNaN(value)) { + result[index++] = 'N'; + result[index++] = 'a'; + result[index++] = 'N'; + return index - off; + } + + if (value == Double.POSITIVE_INFINITY) { + result[index++] = 'I'; + result[index++] = 'n'; + result[index++] = 'f'; + result[index++] = 'i'; + result[index++] = 'n'; + result[index++] = 'i'; + result[index++] = 't'; + result[index++] = 'y'; + return index - off; + } + + if (value == Double.NEGATIVE_INFINITY) { + result[index++] = '-'; + result[index++] = 'I'; + result[index++] = 'n'; + result[index++] = 'f'; + result[index++] = 'i'; + result[index++] = 'n'; + result[index++] = 'i'; + result[index++] = 't'; + result[index++] = 'y'; + return index - off; + } + + long bits = Double.doubleToLongBits(value); + if (bits == 0) { + result[index++] = '0'; + result[index++] = '.'; + result[index++] = '0'; + return index - off; + } + if (bits == 0x8000000000000000L) { + result[index++] = '-'; + result[index++] = '0'; + result[index++] = '.'; + result[index++] = '0'; + return index - off; + } + + final int DOUBLE_MANTISSA_BITS = 52; + // Otherwise extract the mantissa and exponent bits and run the full algorithm. + int ieeeExponent = (int) ((bits >>> DOUBLE_MANTISSA_BITS) & DOUBLE_EXPONENT_MASK); + long ieeeMantissa = bits & DOUBLE_MANTISSA_MASK; + int e2; + long m2; + if (ieeeExponent == 0) { + // Denormal number - no implicit leading 1, and the exponent is 1, not 0. + e2 = 1 - DOUBLE_EXPONENT_BIAS - DOUBLE_MANTISSA_BITS; + m2 = ieeeMantissa; + } else { + // Add implicit leading 1. + e2 = ieeeExponent - DOUBLE_EXPONENT_BIAS - DOUBLE_MANTISSA_BITS; + m2 = ieeeMantissa | (1L << DOUBLE_MANTISSA_BITS); + } + + boolean sign = bits < 0; + + // Step 2: Determine the interval of legal decimal representations. + boolean even = (m2 & 1) == 0; + final long mv = 4 * m2; + final long mp = 4 * m2 + 2; + final int mmShift = ((m2 != (1L << DOUBLE_MANTISSA_BITS)) || (ieeeExponent <= 1)) ? 1 : 0; + final long mm = 4 * m2 - 1 - mmShift; + e2 -= 2; + + // Step 3: Convert to a decimal power base using 128-bit arithmetic. + // -1077 = 1 - 1023 - 53 - 2 <= e_2 - 2 <= 2046 - 1023 - 53 - 2 = 968 + long dv, dp, dm; + final int e10; + boolean dmIsTrailingZeros = false, dvIsTrailingZeros = false; + if (e2 >= 0) { + final int q = Math.max(0, (int) (e2 * LOG10_2_NUMERATOR / 10000000L) - 1); + // k = constant + floor(log_2(5^q)) + // q == 0 ? 1 : (int) ((q * 23219280L + 10000000L - 1) / 10000000L) + final int k = 122 + (q == 0 ? 1 : (int) ((q * 23219280L + 10000000L - 1) / 10000000L)) - 1; + final int i = -e2 + q + k; + + int actualShift = i - 3 * 31 - 21; + if (actualShift < 0) { + throw new IllegalArgumentException("" + actualShift); + } + + final int[] ints = POW5_INV_SPLIT[q]; + { + long mHigh = mv >>> 31; + long mLow = mv & 0x7fffffff; + long bits13 = mHigh * ints[0]; + long bits03 = mLow * ints[0]; + long bits12 = mHigh * ints[1]; + long bits02 = mLow * ints[1]; + long bits11 = mHigh * ints[2]; + long bits01 = mLow * ints[2]; + long bits10 = mHigh * ints[3]; + long bits00 = mLow * ints[3]; + + + dv = (((((( + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; + } + { + long mHigh = mp >>> 31; + long mLow = mp & 0x7fffffff; + long bits13 = mHigh * ints[0]; + long bits03 = mLow * ints[0]; + long bits12 = mHigh * ints[1]; + long bits02 = mLow * ints[1]; + long bits11 = mHigh * ints[2]; + long bits01 = mLow * ints[2]; + long bits10 = mHigh * ints[3]; + long bits00 = mLow * ints[3]; + + dp = (((((( + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; + } + { + long mHigh = mm >>> 31; + long mLow = mm & 0x7fffffff; + long bits13 = mHigh * ints[0]; + long bits03 = mLow * ints[0]; + long bits12 = mHigh * ints[1]; + long bits02 = mLow * ints[1]; + long bits11 = mHigh * ints[2]; + long bits01 = mLow * ints[2]; + long bits10 = mHigh * ints[3]; + long bits00 = mLow * ints[3]; + + dm = (((((( + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; + } + + e10 = q; + + if (q <= 21) { + if (mv % 5 == 0) { + int pow5Factor_mv; + { + long v = mv; + if ((v % 5) != 0) { + pow5Factor_mv = 0; + } else if ((v % 25) != 0) { + pow5Factor_mv = 1; + } else if ((v % 125) != 0) { + pow5Factor_mv = 2; + } else if ((v % 625) != 0) { + pow5Factor_mv = 3; + } else { + pow5Factor_mv = 4; + v /= 625; + while (v > 0) { + if (v % 5 != 0) { + break; + } + v /= 5; + pow5Factor_mv++; + } + } + } + dvIsTrailingZeros = pow5Factor_mv >= q; + } else if (even) { + int pow5Factor_mm; + { + long v = mm; + if ((v % 5) != 0) { + pow5Factor_mm = 0; + } else if ((v % 25) != 0) { + pow5Factor_mm = 1; + } else if ((v % 125) != 0) { + pow5Factor_mm = 2; + } else if ((v % 625) != 0) { + pow5Factor_mm = 3; + } else { + pow5Factor_mm = 4; + v /= 625; + while (v > 0) { + if (v % 5 != 0) { + break; + } + v /= 5; + pow5Factor_mm++; + } + } + } + + dmIsTrailingZeros = pow5Factor_mm >= q; // + } else { + int pow5Factor_mp; + { + long v = mp; + if ((v % 5) != 0) { + pow5Factor_mp = 0; + } else if ((v % 25) != 0) { + pow5Factor_mp = 1; + } else if ((v % 125) != 0) { + pow5Factor_mp = 2; + } else if ((v % 625) != 0) { + pow5Factor_mp = 3; + } else { + pow5Factor_mp = 4; + v /= 625; + while (v > 0) { + if (v % 5 != 0) { + break; + } + v /= 5; + pow5Factor_mp++; + } + } + } + + if (pow5Factor_mp >= q) { + dp--; + } + } + } + } else { + final int q = Math.max(0, (int) (-e2 * LOG10_5_NUMERATOR / 10000000L) - 1); + final int i = -e2 - q; + final int k = (i == 0 ? 1 : (int) ((i * 23219280L + 10000000L - 1) / 10000000L)) - 121; + final int j = q - k; + + int actualShift = j - 3 * 31 - 21; + if (actualShift < 0) { + throw new IllegalArgumentException("" + actualShift); + } + int[] ints = POW5_SPLIT[i]; + { + long mHigh = mv >>> 31; + long mLow = mv & 0x7fffffff; + long bits13 = mHigh * ints[0]; // 124 + long bits03 = mLow * ints[0]; // 93 + long bits12 = mHigh * ints[1]; // 93 + long bits02 = mLow * ints[1]; // 62 + long bits11 = mHigh * ints[2]; // 62 + long bits01 = mLow * ints[2]; // 31 + long bits10 = mHigh * ints[3]; // 31 + long bits00 = mLow * ints[3]; // 0 + + dv = (((((( + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; + } + { + long mHigh = mp >>> 31; + long mLow = mp & 0x7fffffff; + long bits13 = mHigh * ints[0]; // 124 + long bits03 = mLow * ints[0]; // 93 + long bits12 = mHigh * ints[1]; // 93 + long bits02 = mLow * ints[1]; // 62 + long bits11 = mHigh * ints[2]; // 62 + long bits01 = mLow * ints[2]; // 31 + long bits10 = mHigh * ints[3]; // 31 + long bits00 = mLow * ints[3]; // 0 + dp = (((((( + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; + } + { + long mHigh = mm >>> 31; + long mLow = mm & 0x7fffffff; + long bits13 = mHigh * ints[0]; // 124 + long bits03 = mLow * ints[0]; // 93 + long bits12 = mHigh * ints[1]; // 93 + long bits02 = mLow * ints[1]; // 62 + long bits11 = mHigh * ints[2]; // 62 + long bits01 = mLow * ints[2]; // 31 + long bits10 = mHigh * ints[3]; // 31 + long bits00 = mLow * ints[3]; // 0 + dm = (((((( + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; + } + + e10 = q + e2; + if (q <= 1) { + dvIsTrailingZeros = true; + if (even) { + dmIsTrailingZeros = mmShift == 1; + } else { + dp--; + } + } else if (q < 63) { + dvIsTrailingZeros = (mv & ((1L << (q - 1)) - 1)) == 0; + } + } + + // Step 4: Find the shortest decimal representation in the interval of legal representations. + // + // We do some extra work here in order to follow Float/Double.toString semantics. In particular, + // that requires printing in scientific format if and only if the exponent is between -3 and 7, + // and it requires printing at least two decimal digits. + // + // Above, we moved the decimal dot all the way to the right, so now we need to count digits to + // figure out the correct exponent for scientific notation. + final int vplength; // = decimalLength(dp); + if (dp >= 1000000000000000000L) { + vplength= 19; + } else if (dp >= 100000000000000000L) { + vplength= 18; + } else if (dp >= 10000000000000000L) { + vplength = 17; + } else if (dp >= 1000000000000000L) { + vplength = 16; + } else if (dp >= 100000000000000L) { + vplength = 15; + } else if (dp >= 10000000000000L) { + vplength = 14; + } else if (dp >= 1000000000000L) { + vplength = 13; + } else if (dp >= 100000000000L) { + vplength = 12; + } else if (dp >= 10000000000L) { + vplength = 11; + } else if (dp >= 1000000000L) { + vplength = 10; + } else if (dp >= 100000000L) { + vplength = 9; + } else if (dp >= 10000000L) { + vplength = 8; + } else if (dp >= 1000000L) { + vplength = 7; + } else if (dp >= 100000L) { + vplength = 6; + } else if (dp >= 10000L) { + vplength = 5; + } else if (dp >= 1000L) { + vplength = 4; + } else if (dp >= 100L) { + vplength = 3; + } else if (dp >= 10L) { + vplength = 2; + } else { + vplength = 1; + } + + int exp = e10 + vplength - 1; + + // Double.toString semantics requires using scientific notation if and only if outside this range. + boolean scientificNotation = !((exp >= -3) && (exp < 7)); + + int removed = 0; + + int lastRemovedDigit = 0; + long output; + if (dmIsTrailingZeros || dvIsTrailingZeros) { + while (dp / 10 > dm / 10) { + if ((dp < 100) && scientificNotation) { + // Double.toString semantics requires printing at least two digits. + break; + } + dmIsTrailingZeros &= dm % 10 == 0; + dvIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (int) (dv % 10); + dp /= 10; + dv /= 10; + dm /= 10; + removed++; + } + if (dmIsTrailingZeros && even) { + while (dm % 10 == 0) { + if ((dp < 100) && scientificNotation) { + // Double.toString semantics requires printing at least two digits. + break; + } + dvIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (int) (dv % 10); + dp /= 10; + dv /= 10; + dm /= 10; + removed++; + } + } + if (dvIsTrailingZeros && (lastRemovedDigit == 5) && (dv % 2 == 0)) { + // Round even if the exact numbers is .....50..0. + lastRemovedDigit = 4; + } + output = dv + + ((dv == dm && !(dmIsTrailingZeros && even)) || (lastRemovedDigit >= 5) ? 1 : 0); + } else { + while (dp / 10 > dm / 10) { + if ((dp < 100) && scientificNotation) { + // Double.toString semantics requires printing at least two digits. + break; + } + lastRemovedDigit = (int) (dv % 10); + dp /= 10; + dv /= 10; + dm /= 10; + removed++; + } + output = dv + ((dv == dm || (lastRemovedDigit >= 5)) ? 1 : 0); + } + int olength = vplength - removed; + + // Step 5: Print the decimal representation. + // We follow Double.toString semantics here. + if (sign) { + result[index++] = '-'; + } + + // Values in the interval [1E-3, 1E7) are special. + if (scientificNotation) { + // Print in the format x.xxxxxE-yy. + for (int i = 0; i < olength - 1; i++) { + int c = (int) (output % 10); + output /= 10; + result[index + olength - i] = (char) ('0' + c); + } + result[index] = (char) ('0' + output % 10); + result[index + 1] = '.'; + index += olength + 1; + if (olength == 1) { + result[index++] = '0'; + } + + // Print 'E', the exponent sign, and the exponent, which has at most three digits. + result[index++] = 'E'; + if (exp < 0) { + result[index++] = '-'; + exp = -exp; + } + if (exp >= 100) { + result[index++] = (char) ('0' + exp / 100); + exp %= 100; + result[index++] = (char) ('0' + exp / 10); + } else if (exp >= 10) { + result[index++] = (char) ('0' + exp / 10); + } + result[index++] = (char) ('0' + exp % 10); + return index - off; + } else { + // Otherwise follow the Java spec for values in the interval [1E-3, 1E7). + if (exp < 0) { + // Decimal dot is before any of the digits. + result[index++] = '0'; + result[index++] = '.'; + for (int i = -1; i > exp; i--) { + result[index++] = '0'; + } + int current = index; + for (int i = 0; i < olength; i++) { + result[current + olength - i - 1] = (char) ('0' + output % 10); + output /= 10; + index++; + } + } else if (exp + 1 >= olength) { + // Decimal dot is after any of the digits. + for (int i = 0; i < olength; i++) { + result[index + olength - i - 1] = (char) ('0' + output % 10); + output /= 10; + } + index += olength; + for (int i = olength; i < exp + 1; i++) { + result[index++] = '0'; + } + result[index++] = '.'; + result[index++] = '0'; + } else { + // Decimal dot is somewhere between the digits. + int current = index + 1; + for (int i = 0; i < olength; i++) { + if (olength - i - 1 == exp) { + result[current + olength - i - 1] = '.'; + current--; + } + result[current + olength - i - 1] = (char) ('0' + output % 10); + output /= 10; + } + index += olength + 1; + } + return index - off; + } + } + +} diff --git a/src/main/java/com/alibaba/fastjson/util/RyuFloat.java b/src/main/java/com/alibaba/fastjson/util/RyuFloat.java new file mode 100644 index 0000000000..e189f9f3e7 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/RyuFloat.java @@ -0,0 +1,423 @@ +// Copyright 2018 Ulf Adams +// +// 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. + +package com.alibaba.fastjson.util; + +/** + * An implementation of Ryu for float. + */ +public final class RyuFloat { + private static final int[][] POW5_SPLIT = { + {536870912, 0}, + {671088640, 0}, + {838860800, 0}, + {1048576000, 0}, + {655360000, 0}, + {819200000, 0}, + {1024000000, 0}, + {640000000, 0}, + {800000000, 0}, + {1000000000, 0}, + {625000000, 0}, + {781250000, 0}, + {976562500, 0}, + {610351562, 1073741824}, + {762939453, 268435456}, + {953674316, 872415232}, + {596046447, 1619001344}, + {745058059, 1486880768}, + {931322574, 1321730048}, + {582076609, 289210368}, + {727595761, 898383872}, + {909494701, 1659850752}, + {568434188, 1305842176}, + {710542735, 1632302720}, + {888178419, 1503507488}, + {555111512, 671256724}, + {693889390, 839070905}, + {867361737, 2122580455}, + {542101086, 521306416}, + {677626357, 1725374844}, + {847032947, 546105819}, + {1058791184, 145761362}, + {661744490, 91100851}, + {827180612, 1187617888}, + {1033975765, 1484522360}, + {646234853, 1196261931}, + {807793566, 2032198326}, + {1009741958, 1466506084}, + {631088724, 379695390}, + {788860905, 474619238}, + {986076131, 1130144959}, + {616297582, 437905143}, + {770371977, 1621123253}, + {962964972, 415791331}, + {601853107, 1333611405}, + {752316384, 1130143345}, + {940395480, 1412679181}, + }; + + private static final int[][] POW5_INV_SPLIT = { + {268435456, 1}, + {214748364, 1717986919}, + {171798691, 1803886265}, + {137438953, 1013612282}, + {219902325, 1192282922}, + {175921860, 953826338}, + {140737488, 763061070}, + {225179981, 791400982}, + {180143985, 203624056}, + {144115188, 162899245}, + {230584300, 1978625710}, + {184467440, 1582900568}, + {147573952, 1266320455}, + {236118324, 308125809}, + {188894659, 675997377}, + {151115727, 970294631}, + {241785163, 1981968139}, + {193428131, 297084323}, + {154742504, 1955654377}, + {247588007, 1840556814}, + {198070406, 613451992}, + {158456325, 61264864}, + {253530120, 98023782}, + {202824096, 78419026}, + {162259276, 1780722139}, + {259614842, 1990161963}, + {207691874, 733136111}, + {166153499, 1016005619}, + {265845599, 337118801}, + {212676479, 699191770}, + {170141183, 988850146}, + }; + + public static String toString(float value) { + char[] result = new char[15]; + int len = toString(value, result, 0); + return new String(result, 0, len); + } + + public static int toString(float value, char[] result, int off) { + final int FLOAT_MANTISSA_MASK = 8388607; // (1 << 23) - 1; + final int FLOAT_EXPONENT_MASK = 255; // (1 << 8) - 1; + final int FLOAT_EXPONENT_BIAS = 127; // (1 << (8 - 1)) - 1; + final long LOG10_2_NUMERATOR = 3010299; // (long) (10000000L * Math.log10(2)); + final long LOG10_5_DENOMINATOR = 10000000L; + final long LOG10_5_NUMERATOR = 6989700L; // (long) (LOG10_5_DENOMINATOR * Math.log10(5)); + + + // Step 1: Decode the floating point number, and unify normalized and subnormal cases. + // First, handle all the trivial cases. + int index = off; + if (Float.isNaN(value)) { + result[index++] = 'N'; + result[index++] = 'a'; + result[index++] = 'N'; + return index - off; + } + + if (value == Float.POSITIVE_INFINITY) { + result[index++] = 'I'; + result[index++] = 'n'; + result[index++] = 'f'; + result[index++] = 'i'; + result[index++] = 'n'; + result[index++] = 'i'; + result[index++] = 't'; + result[index++] = 'y'; + return index - off; + } + + if (value == Float.NEGATIVE_INFINITY) { + result[index++] = '-'; + result[index++] = 'I'; + result[index++] = 'n'; + result[index++] = 'f'; + result[index++] = 'i'; + result[index++] = 'n'; + result[index++] = 'i'; + result[index++] = 't'; + result[index++] = 'y'; + return index - off; + } + + int bits = Float.floatToIntBits(value); + if (bits == 0) { + result[index++] = '0'; + result[index++] = '.'; + result[index++] = '0'; + return index - off; + } + if (bits == 0x80000000) { + result[index++] = '-'; + result[index++] = '0'; + result[index++] = '.'; + result[index++] = '0'; + return index - off; + } + + // Otherwise extract the mantissa and exponent bits and run the full algorithm. + int ieeeExponent = (bits >> 23) & FLOAT_EXPONENT_MASK; + int ieeeMantissa = bits & FLOAT_MANTISSA_MASK; + // By default, the correct mantissa starts with a 1, except for denormal numbers. + int e2; + int m2; + if (ieeeExponent == 0) { + e2 = 1 - FLOAT_EXPONENT_BIAS - 23; + m2 = ieeeMantissa; + } else { + e2 = ieeeExponent - FLOAT_EXPONENT_BIAS - 23; + m2 = ieeeMantissa | (1 << 23); + } + + boolean sign = bits < 0; + + // Step 2: Determine the interval of legal decimal representations. + boolean even = (m2 & 1) == 0; + int mv = 4 * m2; + int mp = 4 * m2 + 2; + int mm = 4 * m2 - ((m2 != (1L << 23)) || (ieeeExponent <= 1) ? 2 : 1); + e2 -= 2; + + // Step 3: Convert to a decimal power base using 128-bit arithmetic. + // -151 = 1 - 127 - 23 - 2 <= e_2 - 2 <= 254 - 127 - 23 - 2 = 102 + int dp, dv, dm; + int e10; + boolean dpIsTrailingZeros, dvIsTrailingZeros, dmIsTrailingZeros; + int lastRemovedDigit = 0; + if (e2 >= 0) { + // Compute m * 2^e_2 / 10^q = m * 2^(e_2 - q) / 5^q + int q = (int) (e2 * LOG10_2_NUMERATOR / 10000000L); + int k = 59 + (q == 0 ? 1 : (int) ((q * 23219280L + 10000000L - 1) / 10000000L)) - 1; + int i = -e2 + q + k; + long pis0 = (long) POW5_INV_SPLIT[q][0]; + long pis1 = (long) POW5_INV_SPLIT[q][1]; + dv = (int) ((mv * pis0 + ((mv * pis1) >> 31)) >> (i - 31)); + dp = (int) ((mp * pis0 + ((mp * pis1) >> 31)) >> (i - 31)); + dm = (int) ((mm * pis0 + ((mm * pis1) >> 31)) >> (i - 31)); + if (q != 0 && ((dp - 1) / 10 <= dm / 10)) { + // We need to know one removed digit even if we are not going to loop below. We could use + // q = X - 1 above, except that would require 33 bits for the result, and we've found that + // 32-bit arithmetic is faster even on 64-bit machines. + int e = q - 1; + int l = 59 + (e == 0 ? 1 : (int) ((e * 23219280L + 10000000L - 1) / 10000000L)) - 1; + int qx = q - 1, ii = -e2 + q - 1 + l; + long mulPow5InvDivPow2 = (mv * (long) POW5_INV_SPLIT[qx][0] + ((mv * (long) POW5_INV_SPLIT[qx][1]) >> 31)) >> (ii - 31); + lastRemovedDigit = (int) (mulPow5InvDivPow2 % 10); + } + e10 = q; + + int pow5Factor_mp = 0; + { + int v = mp; + while (v > 0) { + if (v % 5 != 0) { + break; + } + v /= 5; + pow5Factor_mp++; + } + } + + int pow5Factor_mv = 0; + { + int v = mv; + while (v > 0) { + if (v % 5 != 0) { + break; + } + v /= 5; + pow5Factor_mv++; + } + } + + int pow5Factor_mm = 0; + { + int v = mm; + while (v > 0) { + if (v % 5 != 0) { + break; + } + v /= 5; + pow5Factor_mm++; + } + } + + dpIsTrailingZeros = pow5Factor_mp >= q; + dvIsTrailingZeros = pow5Factor_mv >= q; + dmIsTrailingZeros = pow5Factor_mm >= q; + } else { + // Compute m * 5^(-e_2) / 10^q = m * 5^(-e_2 - q) / 2^q + int q = (int) (-e2 * LOG10_5_NUMERATOR / LOG10_5_DENOMINATOR); + int i = -e2 - q; + int k = (i == 0 ? 1 : (int) ((i * 23219280L + 10000000L - 1) / 10000000L)) - 61; + int j = q - k; + + long ps0 = POW5_SPLIT[i][0]; + long ps1 = POW5_SPLIT[i][1]; + int j31 = j - 31; + dv = (int) ((mv * ps0 + ((mv * ps1) >> 31)) >> j31); + dp = (int) ((mp * ps0 + ((mp * ps1) >> 31)) >> j31); + dm = (int) ((mm * ps0 + ((mm * ps1) >> 31)) >> j31); + + if (q != 0 && ((dp - 1) / 10 <= dm / 10)) { + int e = i + 1; + j = q - 1 - ((e == 0 ? 1 : (int) ((e * 23219280L + 10000000L - 1) / 10000000L)) - 61); + int ix = i + 1; + long mulPow5divPow2 = (mv * (long) POW5_SPLIT[ix][0] + ((mv * (long) POW5_SPLIT[ix][1]) >> 31)) >> (j - 31); + lastRemovedDigit = (int) (mulPow5divPow2 % 10); + } + e10 = q + e2; // Note: e2 and e10 are both negative here. + + dpIsTrailingZeros = 1 >= q; + dvIsTrailingZeros = (q < 23) && (mv & ((1 << (q - 1)) - 1)) == 0; + dmIsTrailingZeros = (mm % 2 == 1 ? 0 : 1) >= q; + } + + // Step 4: Find the shortest decimal representation in the interval of legal representations. + // + // We do some extra work here in order to follow Float/Double.toString semantics. In particular, + // that requires printing in scientific format if and only if the exponent is between -3 and 7, + // and it requires printing at least two decimal digits. + // + // Above, we moved the decimal dot all the way to the right, so now we need to count digits to + // figure out the correct exponent for scientific notation. + + int dplength = 10; + int factor = 1000000000; + for (; dplength > 0; dplength--) { + if (dp >= factor) { + break; + } + factor /= 10; + } + int exp = e10 + dplength - 1; + + // Float.toString semantics requires using scientific notation if and only if outside this range. + boolean scientificNotation = !((exp >= -3) && (exp < 7)); + + int removed = 0; + if (dpIsTrailingZeros && !even) { + dp--; + } + + while (dp / 10 > dm / 10) { + if ((dp < 100) && scientificNotation) { + // We print at least two digits, so we might as well stop now. + break; + } + dmIsTrailingZeros &= dm % 10 == 0; + dp /= 10; + lastRemovedDigit = dv % 10; + dv /= 10; + dm /= 10; + removed++; + } + if (dmIsTrailingZeros && even) { + while (dm % 10 == 0) { + if ((dp < 100) && scientificNotation) { + // We print at least two digits, so we might as well stop now. + break; + } + dp /= 10; + lastRemovedDigit = dv % 10; + dv /= 10; + dm /= 10; + removed++; + } + } + + if (dvIsTrailingZeros && (lastRemovedDigit == 5) && (dv % 2 == 0)) { + // Round down not up if the number ends in X50000 and the number is even. + lastRemovedDigit = 4; + } + int output = dv + + ((dv == dm && !(dmIsTrailingZeros && even)) || (lastRemovedDigit >= 5) ? 1 : 0); + int olength = dplength - removed; + + // Step 5: Print the decimal representation. + // We follow Float.toString semantics here. + if (sign) { + result[index++] = '-'; + } + + if (scientificNotation) { + // Print in the format x.xxxxxE-yy. + for (int i = 0; i < olength - 1; i++) { + int c = output % 10; + output /= 10; + result[index + olength - i] = (char) ('0' + c); + } + result[index] = (char) ('0' + output % 10); + result[index + 1] = '.'; + index += olength + 1; + if (olength == 1) { + result[index++] = '0'; + } + + // Print 'E', the exponent sign, and the exponent, which has at most two digits. + result[index++] = 'E'; + if (exp < 0) { + result[index++] = '-'; + exp = -exp; + } + if (exp >= 10) { + result[index++] = (char) ('0' + exp / 10); + } + result[index++] = (char) ('0' + exp % 10); + } else { + // Otherwise follow the Java spec for values in the interval [1E-3, 1E7). + if (exp < 0) { + // Decimal dot is before any of the digits. + result[index++] = '0'; + result[index++] = '.'; + for (int i = -1; i > exp; i--) { + result[index++] = '0'; + } + int current = index; + for (int i = 0; i < olength; i++) { + result[current + olength - i - 1] = (char) ('0' + output % 10); + output /= 10; + index++; + } + } else if (exp + 1 >= olength) { + // Decimal dot is after any of the digits. + for (int i = 0; i < olength; i++) { + result[index + olength - i - 1] = (char) ('0' + output % 10); + output /= 10; + } + index += olength; + for (int i = olength; i < exp + 1; i++) { + result[index++] = '0'; + } + result[index++] = '.'; + result[index++] = '0'; + } else { + // Decimal dot is somewhere between the digits. + int current = index + 1; + for (int i = 0; i < olength; i++) { + if (olength - i - 1 == exp) { + result[current + olength - i - 1] = '.'; + current--; + } + result[current + olength - i - 1] = (char) ('0' + output % 10); + output /= 10; + } + index += olength + 1; + } + } + return index - off; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java b/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java old mode 100755 new mode 100644 index b5b77d5b9e..df5234ab15 --- a/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java +++ b/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java @@ -39,7 +39,7 @@ public static Set load(Class clazz, ClassLoader classLoader) { load(url, serviceNames); loadedUrls.add(url.toString()); } - } catch (IOException ex) { + } catch (Throwable ex) { // skip } diff --git a/src/main/java/com/alibaba/fastjson/util/TypeUtils.java b/src/main/java/com/alibaba/fastjson/util/TypeUtils.java old mode 100755 new mode 100644 index 64dafef628..0fb8964193 --- a/src/main/java/com/alibaba/fastjson/util/TypeUtils.java +++ b/src/main/java/com/alibaba/fastjson/util/TypeUtils.java @@ -15,67 +15,49 @@ */ package com.alibaba.fastjson.util; -import java.lang.annotation.Annotation; -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Proxy; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.security.AccessControlException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.PropertyNamingStrategy; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.EnumDeserializer; import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import com.alibaba.fastjson.serializer.CalendarCodec; import com.alibaba.fastjson.serializer.SerializeBeanInfo; import com.alibaba.fastjson.serializer.SerializerFeature; +import java.io.InputStream; +import java.io.Reader; +import java.lang.annotation.Annotation; +import java.lang.reflect.*; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Clob; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * @author wenshao[szujobs@hotmail.com] */ -public class TypeUtils{ +public class TypeUtils { + private static final Pattern NUMBER_WITH_TRAILING_ZEROS_PATTERN = Pattern.compile("\\.0*$"); public static boolean compatibleWithJavaBean = false; - /** 根据field name的大小写输出输入数据 */ + /** + * 根据field name的大小写输出输入数据 + */ public static boolean compatibleWithFieldName = false; private static boolean setAccessibleEnable = true; private static boolean oracleTimestampMethodInited = false; @@ -102,64 +84,191 @@ public class TypeUtils{ private static volatile Method kotlin_kfunction_getParameters; private static volatile Method kotlin_kparameter_getName; private static volatile boolean kotlin_error; - private static volatile Map kotlinIgnores; + private static volatile Map kotlinIgnores; private static volatile boolean kotlinIgnores_error; - private static ConcurrentMap> mappings = new ConcurrentHashMap>(16, 0.75f, 1); + private static ConcurrentMap> mappings = new ConcurrentHashMap>(256, 0.75f, 1); private static Class pathClass; private static boolean pathClass_error = false; - static{ - try{ + private static Class class_JacksonCreator = null; + private static boolean class_JacksonCreator_error = false; + + private static volatile Class class_XmlAccessType = null; + private static volatile Class class_XmlAccessorType = null; + private static volatile boolean classXmlAccessorType_error = false; + private static volatile Method method_XmlAccessorType_value = null; + private static volatile Field field_XmlAccessType_FIELD = null; + private static volatile Object field_XmlAccessType_FIELD_VALUE = null; + + private static Class class_deque = null; + + static { + try { TypeUtils.compatibleWithJavaBean = "true".equals(IOUtils.getStringProperty(IOUtils.FASTJSON_COMPATIBLEWITHJAVABEAN)); TypeUtils.compatibleWithFieldName = "true".equals(IOUtils.getStringProperty(IOUtils.FASTJSON_COMPATIBLEWITHFIELDNAME)); - } catch(Throwable e){ + } catch (Throwable e) { + // skip + } + + try { + class_deque = Class.forName("java.util.Deque"); + } catch (Throwable e) { // skip } } - static{ - addBaseClassMappings(); + public static boolean isXmlField(Class clazz) { + if (class_XmlAccessorType == null && !classXmlAccessorType_error) { + try { + class_XmlAccessorType = Class.forName("javax.xml.bind.annotation.XmlAccessorType"); + } catch (Throwable ex) { + classXmlAccessorType_error = true; + } + } + + if (class_XmlAccessorType == null) { + return false; + } + + Annotation annotation = TypeUtils.getAnnotation(clazz, class_XmlAccessorType); + if (annotation == null) { + return false; + } + + if (method_XmlAccessorType_value == null && !classXmlAccessorType_error) { + try { + method_XmlAccessorType_value = class_XmlAccessorType.getMethod("value"); + } catch (Throwable ex) { + classXmlAccessorType_error = true; + } + } + + if (method_XmlAccessorType_value == null) { + return false; + } + + Object value = null; + if (!classXmlAccessorType_error) { + try { + value = method_XmlAccessorType_value.invoke(annotation); + } catch (Throwable ex) { + classXmlAccessorType_error = true; + } + } + if (value == null) { + return false; + } + + if (class_XmlAccessType == null && !classXmlAccessorType_error) { + try { + class_XmlAccessType = Class.forName("javax.xml.bind.annotation.XmlAccessType"); + field_XmlAccessType_FIELD = class_XmlAccessType.getField("FIELD"); + field_XmlAccessType_FIELD_VALUE = field_XmlAccessType_FIELD.get(null); + } catch (Throwable ex) { + classXmlAccessorType_error = true; + } + } + + return value == field_XmlAccessType_FIELD_VALUE; + } + + public static Annotation getXmlAccessorType(Class clazz) { + if (class_XmlAccessorType == null && !classXmlAccessorType_error) { + + try { + class_XmlAccessorType = Class.forName("javax.xml.bind.annotation.XmlAccessorType"); + } catch (Throwable ex) { + classXmlAccessorType_error = true; + } + } + + if (class_XmlAccessorType == null) { + return null; + } + + return TypeUtils.getAnnotation(clazz, class_XmlAccessorType); } - public static String castToString(Object value){ - if(value == null){ +// +// public static boolean isXmlAccessType(Class clazz) { +// if (class_XmlAccessType == null && !class_XmlAccessType_error) { +// +// try{ +// class_XmlAccessType = Class.forName("javax.xml.bind.annotation.XmlAccessType"); +// } catch(Throwable ex){ +// class_XmlAccessType_error = true; +// } +// } +// +// if (class_XmlAccessType == null) { +// return false; +// } +// +// return class_XmlAccessType.isAssignableFrom(clazz); +// } + + private static Function isClobFunction = new Function() { + public Boolean apply(Class clazz) { + return Clob.class.isAssignableFrom(clazz); + } + }; + + public static boolean isClob(final Class clazz) { + Boolean isClob = ModuleUtil.callWhenHasJavaSql(isClobFunction, clazz); + + return isClob != null ? isClob : false; + } + + public static String castToString(Object value) { + if (value == null) { return null; } return value.toString(); } - public static Byte castToByte(Object value){ - if(value == null){ + public static Byte castToByte(Object value) { + if (value == null) { return null; } - if(value instanceof Number){ + + if (value instanceof BigDecimal) { + return byteValue((BigDecimal) value); + } + + if (value instanceof Number) { return ((Number) value).byteValue(); } - if(value instanceof String){ + + if (value instanceof String) { String strVal = (String) value; - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } return Byte.parseByte(strVal); } + + if (value instanceof Boolean) { + return (Boolean) value ? (byte) 1 : (byte) 0; + } + throw new JSONException("can not cast to byte, value : " + value); } - public static Character castToChar(Object value){ - if(value == null){ + public static Character castToChar(Object value) { + if (value == null) { return null; } - if(value instanceof Character){ + if (value instanceof Character) { return (Character) value; } - if(value instanceof String){ + if (value instanceof String) { String strVal = (String) value; - if(strVal.length() == 0){ + if (strVal.length() == 0) { return null; } - if(strVal.length() != 1){ + if (strVal.length() != 1) { throw new JSONException("can not cast to char, value : " + value); } return strVal.charAt(0); @@ -167,390 +276,733 @@ public static Character castToChar(Object value){ throw new JSONException("can not cast to char, value : " + value); } - public static Short castToShort(Object value){ - if(value == null){ + public static Short castToShort(Object value) { + if (value == null) { return null; } - if(value instanceof Number){ + + if (value instanceof BigDecimal) { + return shortValue((BigDecimal) value); + } + + if (value instanceof Number) { return ((Number) value).shortValue(); } - if(value instanceof String){ + + if (value instanceof String) { String strVal = (String) value; - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } return Short.parseShort(strVal); } + + if (value instanceof Boolean) { + return ((Boolean) value).booleanValue() ? (short) 1 : (short) 0; + } + throw new JSONException("can not cast to short, value : " + value); } - public static BigDecimal castToBigDecimal(Object value){ - if(value == null){ + public static BigDecimal castToBigDecimal(Object value) { + if (value == null) { return null; } - if(value instanceof BigDecimal){ + + if (value instanceof Float) { + if (Float.isNaN((Float) value) || Float.isInfinite((Float) value)) { + return null; + } + } else if (value instanceof Double) { + if (Double.isNaN((Double) value) || Double.isInfinite((Double) value)) { + return null; + } + } else if (value instanceof BigDecimal) { return (BigDecimal) value; - } - if(value instanceof BigInteger){ + } else if (value instanceof BigInteger) { return new BigDecimal((BigInteger) value); + } else if (value instanceof Map && ((Map) value).size() == 0) { + return null; } + String strVal = value.toString(); - if(strVal.length() == 0){ + + if (strVal.length() == 0 + || strVal.equalsIgnoreCase("null")) { return null; } - if(value instanceof Map && ((Map) value).size() == 0){ - return null; + + if (strVal.length() > 65535) { + throw new JSONException("decimal overflow"); } return new BigDecimal(strVal); } - public static BigInteger castToBigInteger(Object value){ - if(value == null){ + public static BigInteger castToBigInteger(Object value) { + if (value == null) { return null; } - if(value instanceof BigInteger){ + + if (value instanceof Float) { + Float floatValue = (Float) value; + if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) { + return null; + } + return BigInteger.valueOf(floatValue.longValue()); + } else if (value instanceof Double) { + Double doubleValue = (Double) value; + if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) { + return null; + } + return BigInteger.valueOf(doubleValue.longValue()); + } else if (value instanceof BigInteger) { return (BigInteger) value; + } else if (value instanceof BigDecimal) { + BigDecimal decimal = (BigDecimal) value; + int scale = decimal.scale(); + if (scale > -1000 && scale < 1000) { + return ((BigDecimal) value).toBigInteger(); + } } - if(value instanceof Float || value instanceof Double){ - return BigInteger.valueOf(((Number) value).longValue()); - } + String strVal = value.toString(); - if(strVal.length() == 0 // - || "null".equals(strVal) // - || "NULL".equals(strVal)){ + + if (strVal.length() == 0 + || strVal.equalsIgnoreCase("null")) { return null; } + + if (strVal.length() > 65535) { + throw new JSONException("decimal overflow"); + } return new BigInteger(strVal); } - public static Float castToFloat(Object value){ - if(value == null){ + public static Float castToFloat(Object value) { + if (value == null) { return null; } - if(value instanceof Number){ + if (value instanceof Number) { return ((Number) value).floatValue(); } - if(value instanceof String){ + if (value instanceof String) { String strVal = value.toString(); - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } - if(strVal.indexOf(',') != 0){ + if (strVal.indexOf(',') != -1) { strVal = strVal.replaceAll(",", ""); } return Float.parseFloat(strVal); } + + if (value instanceof Boolean) { + return (Boolean) value ? 1F : 0F; + } + throw new JSONException("can not cast to float, value : " + value); } - public static Double castToDouble(Object value){ - if(value == null){ + public static Double castToDouble(Object value) { + if (value == null) { return null; } - if(value instanceof Number){ + if (value instanceof Number) { return ((Number) value).doubleValue(); } - if(value instanceof String){ + if (value instanceof String) { String strVal = value.toString(); - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } - if(strVal.indexOf(',') != 0){ + if (strVal.indexOf(',') != -1) { strVal = strVal.replaceAll(",", ""); } return Double.parseDouble(strVal); } + + if (value instanceof Boolean) { + return (Boolean) value ? 1D : 0D; + } + throw new JSONException("can not cast to double, value : " + value); } - public static Date castToDate(Object value){ - if(value == null){ + public static Date castToDate(Object value) { + return castToDate(value, null); + } + + public static Date castToDate(Object value, String format) { + if (value == null) { return null; } - if(value instanceof Date){ // 使用频率最高的,应优先处理 + + if (value instanceof Date) { // 使用频率最高的,应优先处理 return (Date) value; } - if(value instanceof Calendar){ + + if (value instanceof Calendar) { return ((Calendar) value).getTime(); } + long longValue = -1; - if(value instanceof Number){ + + if (value instanceof BigDecimal) { + longValue = longValue((BigDecimal) value); + return new Date(longValue); + } + + if (value instanceof Number) { longValue = ((Number) value).longValue(); + if ("unixtime".equals(format)) { + longValue *= 1000; + } return new Date(longValue); } - if(value instanceof String){ + + if (value instanceof String) { String strVal = (String) value; JSONScanner dateLexer = new JSONScanner(strVal); - try{ - if(dateLexer.scanISO8601DateIfMatch(false)){ + try { + if (dateLexer.scanISO8601DateIfMatch(false)) { Calendar calendar = dateLexer.getCalendar(); return calendar.getTime(); } - } finally{ + } finally { dateLexer.close(); } - if(strVal.startsWith("/Date(") && strVal.endsWith(")/")){ - String dotnetDateStr = strVal.substring(6, strVal.length() - 2); - strVal = dotnetDateStr; - } - if(strVal.indexOf('-') != -1){ - String format; - - if(strVal.length() == JSON.DEFFAULT_DATE_FORMAT.length() - || (strVal.length() == 22 && JSON.DEFFAULT_DATE_FORMAT.equals("yyyyMMddHHmmssSSSZ"))){ - format = JSON.DEFFAULT_DATE_FORMAT; - } else if(strVal.length() == 10){ - format = "yyyy-MM-dd"; - } else if(strVal.length() == "yyyy-MM-dd HH:mm:ss".length()){ - format = "yyyy-MM-dd HH:mm:ss"; - } else if(strVal.length() == 29 - && strVal.charAt(26) == ':' - && strVal.charAt(28) == '0'){ - format = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; - } else{ - format = "yyyy-MM-dd HH:mm:ss.SSS"; + + if (strVal.startsWith("/Date(") && strVal.endsWith(")/")) { + strVal = strVal.substring(6, strVal.length() - 2); + } + + if (strVal.indexOf('-') > 0 || strVal.indexOf('+') > 0 || format != null) { + if (format == null) { + final int len = strVal.length(); + if (len == JSON.DEFFAULT_DATE_FORMAT.length() + || (len == 22 && JSON.DEFFAULT_DATE_FORMAT.equals("yyyyMMddHHmmssSSSZ"))) { + format = JSON.DEFFAULT_DATE_FORMAT; + } else if (len == 10) { + format = "yyyy-MM-dd"; + } else if (len == "yyyy-MM-dd HH:mm:ss".length()) { + format = "yyyy-MM-dd HH:mm:ss"; + } else if (len == 29 + && strVal.charAt(26) == ':' + && strVal.charAt(28) == '0') { + format = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; + } else if (len == 23 && strVal.charAt(19) == ',') { + format = "yyyy-MM-dd HH:mm:ss,SSS"; + } else { + format = "yyyy-MM-dd HH:mm:ss.SSS"; + } } + SimpleDateFormat dateFormat = new SimpleDateFormat(format, JSON.defaultLocale); dateFormat.setTimeZone(JSON.defaultTimeZone); - try{ - return (Date) dateFormat.parse(strVal); - } catch(ParseException e){ + try { + return dateFormat.parse(strVal); + } catch (ParseException e) { throw new JSONException("can not cast to Date, value : " + strVal); } } - if(strVal.length() == 0){ + if (strVal.length() == 0) { return null; } longValue = Long.parseLong(strVal); } - if(longValue < 0){ + + if (longValue == -1) { Class clazz = value.getClass(); - if("oracle.sql.TIMESTAMP".equals(clazz.getName())){ - if(oracleTimestampMethod == null && !oracleTimestampMethodInited){ - try{ + if ("oracle.sql.TIMESTAMP".equals(clazz.getName())) { + if (oracleTimestampMethod == null && !oracleTimestampMethodInited) { + try { oracleTimestampMethod = clazz.getMethod("toJdbc"); - } catch(NoSuchMethodException e){ + } catch (NoSuchMethodException e) { // skip - } finally{ + } finally { oracleTimestampMethodInited = true; } } Object result; - try{ + try { result = oracleTimestampMethod.invoke(value); - } catch(Exception e){ + } catch (Exception e) { throw new JSONException("can not cast oracle.sql.TIMESTAMP to Date", e); } return (Date) result; } - if("oracle.sql.DATE".equals(clazz.getName())){ - if(oracleDateMethod == null && !oracleDateMethodInited){ - try{ + if ("oracle.sql.DATE".equals(clazz.getName())) { + if (oracleDateMethod == null && !oracleDateMethodInited) { + try { oracleDateMethod = clazz.getMethod("toJdbc"); - } catch(NoSuchMethodException e){ + } catch (NoSuchMethodException e) { // skip - } finally{ + } finally { oracleDateMethodInited = true; } } Object result; - try{ + try { result = oracleDateMethod.invoke(value); - } catch(Exception e){ + } catch (Exception e) { throw new JSONException("can not cast oracle.sql.DATE to Date", e); } return (Date) result; } + throw new JSONException("can not cast to Date, value : " + value); } + return new Date(longValue); } - public static java.sql.Date castToSqlDate(Object value){ - if(value == null){ - return null; - } - if(value instanceof java.sql.Date){ - return (java.sql.Date) value; - } - if(value instanceof java.util.Date){ - return new java.sql.Date(((java.util.Date) value).getTime()); - } - if(value instanceof Calendar){ - return new java.sql.Date(((Calendar) value).getTimeInMillis()); - } - long longValue = 0; - if(value instanceof Number){ - longValue = ((Number) value).longValue(); - } - if(value instanceof String){ - String strVal = (String) value; - if(strVal.length() == 0 // - || "null".equals(strVal) // - || "NULL".equals(strVal)){ + private static Function castToSqlDateFunction = new Function() { + public Object apply(Object value) { + if (value == null) { return null; } - if(isNumber(strVal)){ - longValue = Long.parseLong(strVal); - } else{ - JSONScanner scanner = new JSONScanner(strVal); - if(scanner.scanISO8601DateIfMatch(false)){ - longValue = scanner.getCalendar().getTime().getTime(); - } else{ - throw new JSONException("can not cast to Timestamp, value : " + strVal); + if (value instanceof java.sql.Date) { + return (java.sql.Date) value; + } + if (value instanceof Date) { + return new java.sql.Date(((Date) value).getTime()); + } + if (value instanceof Calendar) { + return new java.sql.Date(((Calendar) value).getTimeInMillis()); + } + + long longValue = 0; + if (value instanceof BigDecimal) { + longValue = longValue((BigDecimal) value); + } else if (value instanceof Number) { + longValue = ((Number) value).longValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + if (strVal.length() == 0 // + || "null".equals(strVal) // + || "NULL".equals(strVal)) { + return null; + } + if (isNumber(strVal)) { + longValue = Long.parseLong(strVal); + } else { + JSONScanner scanner = new JSONScanner(strVal); + if (scanner.scanISO8601DateIfMatch(false)) { + longValue = scanner.getCalendar().getTime().getTime(); + } else { + throw new JSONException("can not cast to Timestamp, value : " + strVal); + } } } + if (longValue <= 0) { + throw new JSONException("can not cast to Date, value : " + value); // TODO 忽略 1970-01-01 之前的时间处理? + } + return new java.sql.Date(longValue); } - if(longValue <= 0){ - throw new JSONException("can not cast to Date, value : " + value); // TODO 忽略 1970-01-01 之前的时间处理? - } - return new java.sql.Date(longValue); + }; + + public static Object castToSqlDate(final Object value) { + return ModuleUtil.callWhenHasJavaSql(castToSqlDateFunction, value); } - public static java.sql.Timestamp castToTimestamp(Object value){ - if(value == null){ - return null; - } - if(value instanceof Calendar){ - return new java.sql.Timestamp(((Calendar) value).getTimeInMillis()); - } - if(value instanceof java.sql.Timestamp){ - return (java.sql.Timestamp) value; + public static long longExtractValue(Number number) { + if (number instanceof BigDecimal) { + return ((BigDecimal) number).longValueExact(); } - if(value instanceof java.util.Date){ - return new java.sql.Timestamp(((java.util.Date) value).getTime()); - } - long longValue = 0; - if(value instanceof Number){ - longValue = ((Number) value).longValue(); + + return number.longValue(); + } + + private static Function castToSqlTimeFunction = new Function() { + public Object apply(Object value) { + if (value == null) { + return null; + } + if (value instanceof java.sql.Time) { + return (java.sql.Time) value; + } + if (value instanceof java.util.Date) { + return new java.sql.Time(((java.util.Date) value).getTime()); + } + if (value instanceof Calendar) { + return new java.sql.Time(((Calendar) value).getTimeInMillis()); + } + + long longValue = 0; + if (value instanceof BigDecimal) { + longValue = longValue((BigDecimal) value); + } else if (value instanceof Number) { + longValue = ((Number) value).longValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + if (strVal.length() == 0 // + || "null".equalsIgnoreCase(strVal)) { + return null; + } + + if (isNumber(strVal)) { + longValue = Long.parseLong(strVal); + } else { + if (strVal.length() == 8 && strVal.charAt(2) == ':' && strVal.charAt(5) == ':') { + return java.sql.Time.valueOf(strVal); + } + + JSONScanner scanner = new JSONScanner(strVal); + if (scanner.scanISO8601DateIfMatch(false)) { + longValue = scanner.getCalendar().getTime().getTime(); + } else { + throw new JSONException("can not cast to Timestamp, value : " + strVal); + } + + } + } + if (longValue <= 0) { + throw new JSONException("can not cast to Date, value : " + value); // TODO 忽略 1970-01-01 之前的时间处理? + } + return new java.sql.Time(longValue); } - if(value instanceof String){ - String strVal = (String) value; - if(strVal.length() == 0 // - || "null".equals(strVal) // - || "NULL".equals(strVal)){ + }; + + public static Object castToSqlTime(final Object value) { + return ModuleUtil.callWhenHasJavaSql(castToSqlTimeFunction, value); + } + + public static Function castToTimestampFunction = new Function() { + public Object apply(Object value) { + if (value == null) { return null; } - if(strVal.endsWith(".000000000")){ - strVal = strVal.substring(0, strVal.length() - 10); - } else if(strVal.endsWith(".000000")){ - strVal = strVal.substring(0, strVal.length() - 7); + if (value instanceof Calendar) { + return new java.sql.Timestamp(((Calendar) value).getTimeInMillis()); + } + if (value instanceof java.sql.Timestamp) { + return (java.sql.Timestamp) value; + } + if (value instanceof java.util.Date) { + return new java.sql.Timestamp(((java.util.Date) value).getTime()); + } + long longValue = 0; + if (value instanceof BigDecimal) { + longValue = longValue((BigDecimal) value); + } else if (value instanceof Number) { + longValue = ((Number) value).longValue(); } - if(isNumber(strVal)){ - longValue = Long.parseLong(strVal); - } else{ - JSONScanner scanner = new JSONScanner(strVal); - if(scanner.scanISO8601DateIfMatch(false)){ - longValue = scanner.getCalendar().getTime().getTime(); - } else{ - throw new JSONException("can not cast to Timestamp, value : " + strVal); + if (value instanceof String) { + String strVal = (String) value; + if (strVal.length() == 0 // + || "null".equals(strVal) // + || "NULL".equals(strVal)) { + return null; + } + if (strVal.endsWith(".000000000")) { + strVal = strVal.substring(0, strVal.length() - 10); + } else if (strVal.endsWith(".000000")) { + strVal = strVal.substring(0, strVal.length() - 7); + } + + if (strVal.length() == 29 + && strVal.charAt(4) == '-' + && strVal.charAt(7) == '-' + && strVal.charAt(10) == ' ' + && strVal.charAt(13) == ':' + && strVal.charAt(16) == ':' + && strVal.charAt(19) == '.') { + int year = num( + strVal.charAt(0), + strVal.charAt(1), + strVal.charAt(2), + strVal.charAt(3)); + int month = num( + strVal.charAt(5), + strVal.charAt(6)); + int day = num( + strVal.charAt(8), + strVal.charAt(9)); + int hour = num( + strVal.charAt(11), + strVal.charAt(12)); + int minute = num( + strVal.charAt(14), + strVal.charAt(15)); + int second = num( + strVal.charAt(17), + strVal.charAt(18)); + int nanos = num( + strVal.charAt(20), + strVal.charAt(21), + strVal.charAt(22), + strVal.charAt(23), + strVal.charAt(24), + strVal.charAt(25), + strVal.charAt(26), + strVal.charAt(27), + strVal.charAt(28)); + return new java.sql.Timestamp(year - 1900, month - 1, day, hour, minute, second, nanos); + } + + if (isNumber(strVal)) { + longValue = Long.parseLong(strVal); + } else { + JSONScanner scanner = new JSONScanner(strVal); + if (scanner.scanISO8601DateIfMatch(false)) { + longValue = scanner.getCalendar().getTime().getTime(); + } else { + throw new JSONException("can not cast to Timestamp, value : " + strVal); + } } } + + return new java.sql.Timestamp(longValue); } - if(longValue <= 0){ - throw new JSONException("can not cast to Timestamp, value : " + value); + }; + + public static Object castToTimestamp(final Object value) { + return ModuleUtil.callWhenHasJavaSql(castToTimestampFunction, value); + } + + static int num(char c0, char c1) { + if (c0 >= '0' + && c0 <= '9' + && c1 >= '0' + && c1 <= '9' + ) { + return (c0 - '0') * 10 + + (c1 - '0'); + } + + return -1; + } + + static int num(char c0, char c1, char c2, char c3) { + if (c0 >= '0' + && c0 <= '9' + && c1 >= '0' + && c1 <= '9' + && c2 >= '0' + && c2 <= '9' + && c3 >= '0' + && c3 <= '9' + ) { + return (c0 - '0') * 1000 + + (c1 - '0') * 100 + + (c2 - '0') * 10 + + (c3 - '0'); + } + + return -1; + } + + static int num(char c0, char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8) { + if (c0 >= '0' + && c0 <= '9' + && c1 >= '0' + && c1 <= '9' + && c2 >= '0' + && c2 <= '9' + && c3 >= '0' + && c3 <= '9' + && c4 >= '0' + && c4 <= '9' + && c5 >= '0' + && c5 <= '9' + && c6 >= '0' + && c6 <= '9' + && c7 >= '0' + && c7 <= '9' + && c8 >= '0' + && c8 <= '9' + ) { + return (c0 - '0') * 100000000 + + (c1 - '0') * 10000000 + + (c2 - '0') * 1000000 + + (c3 - '0') * 100000 + + (c4 - '0') * 10000 + + (c5 - '0') * 1000 + + (c6 - '0') * 100 + + (c7 - '0') * 10 + + (c8 - '0'); } - return new java.sql.Timestamp(longValue); + + return -1; } - public static boolean isNumber(String str){ - for(int i = 0; i < str.length(); ++i){ + public static boolean isNumber(String str) { + for (int i = 0; i < str.length(); ++i) { char ch = str.charAt(i); - if(ch == '+' || ch == '-'){ - if(i != 0){ + if (ch == '+' || ch == '-') { + if (i != 0) { return false; - } else{ - continue; } - } else if(ch < '0' || ch > '9'){ + } else if (ch < '0' || ch > '9') { return false; } } return true; } - public static Long castToLong(Object value){ - if(value == null){ + public static Long castToLong(Object value) { + if (value == null) { return null; } - if(value instanceof Number){ + + if (value instanceof BigDecimal) { + return longValue((BigDecimal) value); + } + + if (value instanceof Number) { return ((Number) value).longValue(); } - if(value instanceof String){ + + if (value instanceof String) { String strVal = (String) value; - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } - if(strVal.indexOf(',') != 0){ + if (strVal.indexOf(',') != -1) { strVal = strVal.replaceAll(",", ""); } - try{ + try { return Long.parseLong(strVal); - } catch(NumberFormatException ex){ + } catch (NumberFormatException ex) { // } JSONScanner dateParser = new JSONScanner(strVal); Calendar calendar = null; - if(dateParser.scanISO8601DateIfMatch(false)){ + if (dateParser.scanISO8601DateIfMatch(false)) { calendar = dateParser.getCalendar(); } dateParser.close(); - if(calendar != null){ + if (calendar != null) { return calendar.getTimeInMillis(); } } - if(value instanceof Map){ + + if (value instanceof Map) { Map map = (Map) value; - if(map.size() == 2 + if (map.size() == 2 && map.containsKey("andIncrement") - && map.containsKey("andDecrement")){ + && map.containsKey("andDecrement")) { Iterator iter = map.values().iterator(); iter.next(); Object value2 = iter.next(); return castToLong(value2); } } + + if (value instanceof Boolean) { + return (Boolean) value ? 1L : 0L; + } + throw new JSONException("can not cast to long, value : " + value); } - public static Integer castToInt(Object value){ - if(value == null){ + public static byte byteValue(BigDecimal decimal) { + if (decimal == null) { + return 0; + } + + int scale = decimal.scale(); + if (scale >= -100 && scale <= 100) { + return decimal.byteValue(); + } + + return decimal.byteValueExact(); + } + + public static short shortValue(BigDecimal decimal) { + if (decimal == null) { + return 0; + } + + int scale = decimal.scale(); + if (scale >= -100 && scale <= 100) { + return decimal.shortValue(); + } + + return decimal.shortValueExact(); + } + + public static int intValue(BigDecimal decimal) { + if (decimal == null) { + return 0; + } + + int scale = decimal.scale(); + if (scale >= -100 && scale <= 100) { + return decimal.intValue(); + } + + return decimal.intValueExact(); + } + + public static long longValue(BigDecimal decimal) { + if (decimal == null) { + return 0; + } + + int scale = decimal.scale(); + if (scale >= -100 && scale <= 100) { + return decimal.longValue(); + } + + return decimal.longValueExact(); + } + + public static Integer castToInt(Object value) { + if (value == null) { return null; } - if(value instanceof Integer){ + + if (value instanceof Integer) { return (Integer) value; } - if(value instanceof Number){ + + if (value instanceof BigDecimal) { + return intValue((BigDecimal) value); + } + + if (value instanceof Number) { return ((Number) value).intValue(); } - if(value instanceof String){ + + if (value instanceof String) { String strVal = (String) value; - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } - if(strVal.indexOf(',') != 0){ + if (strVal.indexOf(',') != -1) { strVal = strVal.replaceAll(",", ""); } + + Matcher matcher = NUMBER_WITH_TRAILING_ZEROS_PATTERN.matcher(strVal); + if (matcher.find()) { + strVal = matcher.replaceAll(""); + } return Integer.parseInt(strVal); } - if(value instanceof Boolean){ - return ((Boolean) value).booleanValue() ? 1 : 0; + + if (value instanceof Boolean) { + return (Boolean) value ? 1 : 0; } - if(value instanceof Map){ + if (value instanceof Map) { Map map = (Map) value; - if(map.size() == 2 + if (map.size() == 2 && map.containsKey("andIncrement") - && map.containsKey("andDecrement")){ + && map.containsKey("andDecrement")) { Iterator iter = map.values().iterator(); iter.next(); Object value2 = iter.next(); @@ -560,284 +1012,400 @@ public static Integer castToInt(Object value){ throw new JSONException("can not cast to int, value : " + value); } - public static byte[] castToBytes(Object value){ - if(value instanceof byte[]){ + public static byte[] castToBytes(Object value) { + if (value instanceof byte[]) { return (byte[]) value; } - if(value instanceof String){ + if (value instanceof String) { return IOUtils.decodeBase64((String) value); } - throw new JSONException("can not cast to int, value : " + value); + throw new JSONException("can not cast to byte[], value : " + value); } - public static Boolean castToBoolean(Object value){ - if(value == null){ + public static Boolean castToBoolean(Object value) { + if (value == null) { return null; } - if(value instanceof Boolean){ + if (value instanceof Boolean) { return (Boolean) value; } - if(value instanceof Number){ + + if (value instanceof BigDecimal) { + return intValue((BigDecimal) value) == 1; + } + + if (value instanceof Number) { return ((Number) value).intValue() == 1; } - if(value instanceof String){ + + if (value instanceof String) { String strVal = (String) value; - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } - if("true".equalsIgnoreCase(strVal) // - || "1".equals(strVal)){ + if ("true".equalsIgnoreCase(strVal) // + || "1".equals(strVal)) { return Boolean.TRUE; } - if("false".equalsIgnoreCase(strVal) // - || "0".equals(strVal)){ + if ("false".equalsIgnoreCase(strVal) // + || "0".equals(strVal)) { return Boolean.FALSE; } - if("Y".equalsIgnoreCase(strVal) // - || "T".equals(strVal)){ + if ("Y".equalsIgnoreCase(strVal) // + || "T".equals(strVal)) { return Boolean.TRUE; } - if("F".equalsIgnoreCase(strVal) // - || "N".equals(strVal)){ + if ("F".equalsIgnoreCase(strVal) // + || "N".equals(strVal)) { return Boolean.FALSE; } } throw new JSONException("can not cast to boolean, value : " + value); } - public static T castToJavaBean(Object obj, Class clazz){ + public static T castToJavaBean(Object obj, Class clazz) { return cast(obj, clazz, ParserConfig.getGlobalInstance()); } + private static BiFunction castFunction = new BiFunction() { + public Object apply(Object obj, Class clazz) { + if (clazz == java.sql.Date.class) { + return castToSqlDate(obj); + } + + if (clazz == java.sql.Time.class) { + return castToSqlTime(obj); + } + + if (clazz == java.sql.Timestamp.class) { + return castToTimestamp(obj); + } + return null; + } + }; + @SuppressWarnings({"unchecked", "rawtypes"}) - public static T cast(Object obj, Class clazz, ParserConfig config){ - if(obj == null){ - if(clazz == int.class){ + public static T cast(final Object obj, final Class clazz, ParserConfig config) { + if (obj == null) { + if (clazz == int.class) { return (T) Integer.valueOf(0); - } else if(clazz == long.class){ + } else if (clazz == long.class) { return (T) Long.valueOf(0); - } else if(clazz == short.class){ + } else if (clazz == short.class) { return (T) Short.valueOf((short) 0); - } else if(clazz == byte.class){ + } else if (clazz == byte.class) { return (T) Byte.valueOf((byte) 0); - } else if(clazz == float.class){ + } else if (clazz == float.class) { return (T) Float.valueOf(0); - } else if(clazz == double.class){ + } else if (clazz == double.class) { return (T) Double.valueOf(0); - } else if(clazz == boolean.class){ + } else if (clazz == boolean.class) { return (T) Boolean.FALSE; } return null; } - if(clazz == null){ + + if (clazz == null) { throw new IllegalArgumentException("clazz is null"); } - if(clazz == obj.getClass()){ + + if (clazz == obj.getClass()) { return (T) obj; } - if(obj instanceof Map){ - if(clazz == Map.class){ + + if (obj instanceof Map) { + if (clazz == Map.class) { return (T) obj; } + Map map = (Map) obj; - if(clazz == Object.class && !map.containsKey(JSON.DEFAULT_TYPE_KEY)){ + if (clazz == Object.class && !map.containsKey(JSON.DEFAULT_TYPE_KEY)) { return (T) obj; } - return castToJavaBean((Map) obj, clazz, config); + return castToJavaBean((Map) obj, clazz, config); } - if(clazz.isArray()){ - if(obj instanceof Collection){ + + if (clazz.isArray()) { + if (obj instanceof Collection) { Collection collection = (Collection) obj; int index = 0; Object array = Array.newInstance(clazz.getComponentType(), collection.size()); - for(Object item : collection){ + for (Object item : collection) { Object value = cast(item, clazz.getComponentType(), config); Array.set(array, index, value); index++; } return (T) array; } - if(clazz == byte[].class){ + if (clazz == byte[].class) { return (T) castToBytes(obj); } } - if(clazz.isAssignableFrom(obj.getClass())){ + + if (clazz.isAssignableFrom(obj.getClass())) { return (T) obj; } - if(clazz == boolean.class || clazz == Boolean.class){ + + if (clazz == boolean.class || clazz == Boolean.class) { return (T) castToBoolean(obj); } - if(clazz == byte.class || clazz == Byte.class){ + + if (clazz == byte.class || clazz == Byte.class) { return (T) castToByte(obj); } - if(clazz == char.class || clazz == Character.class){ + + if (clazz == char.class || clazz == Character.class) { return (T) castToChar(obj); } - if(clazz == short.class || clazz == Short.class){ + + if (clazz == short.class || clazz == Short.class) { return (T) castToShort(obj); } - if(clazz == int.class || clazz == Integer.class){ + + if (clazz == int.class || clazz == Integer.class) { return (T) castToInt(obj); } - if(clazz == long.class || clazz == Long.class){ + + if (clazz == long.class || clazz == Long.class) { return (T) castToLong(obj); } - if(clazz == float.class || clazz == Float.class){ + + if (clazz == float.class || clazz == Float.class) { return (T) castToFloat(obj); } - if(clazz == double.class || clazz == Double.class){ + + if (clazz == double.class || clazz == Double.class) { return (T) castToDouble(obj); } - if(clazz == String.class){ + + if (clazz == String.class) { return (T) castToString(obj); } - if(clazz == BigDecimal.class){ + + if (clazz == BigDecimal.class) { return (T) castToBigDecimal(obj); } - if(clazz == BigInteger.class){ + + if (clazz == BigInteger.class) { return (T) castToBigInteger(obj); } - if(clazz == Date.class){ + + if (clazz == Date.class) { return (T) castToDate(obj); } - if(clazz == java.sql.Date.class){ - return (T) castToSqlDate(obj); - } - if(clazz == java.sql.Timestamp.class){ - return (T) castToTimestamp(obj); + + T retObj = (T) ModuleUtil.callWhenHasJavaSql(castFunction, obj, clazz); + + if (retObj != null) { + return retObj; } - if(clazz.isEnum()){ - return (T) castToEnum(obj, clazz, config); + + if (clazz.isEnum()) { + return castToEnum(obj, clazz, config); } - if(Calendar.class.isAssignableFrom(clazz)){ + + if (Calendar.class.isAssignableFrom(clazz)) { Date date = castToDate(obj); Calendar calendar; - if(clazz == Calendar.class){ + if (clazz == Calendar.class) { calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale); - } else{ - try{ + } else { + try { calendar = (Calendar) clazz.newInstance(); - } catch(Exception e){ + } catch (Exception e) { throw new JSONException("can not cast to : " + clazz.getName(), e); } } calendar.setTime(date); return (T) calendar; } - if(clazz.getName().equals("javax.xml.datatype.XMLGregorianCalendar")){ + + String className = clazz.getName(); + if (className.equals("javax.xml.datatype.XMLGregorianCalendar")) { Date date = castToDate(obj); Calendar calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale); calendar.setTime(date); return (T) CalendarCodec.instance.createXMLGregorianCalendar(calendar); } - if(obj instanceof String){ + + if (obj instanceof String) { String strVal = (String) obj; - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } - if(clazz == java.util.Currency.class){ + + if (clazz == java.util.Currency.class) { return (T) java.util.Currency.getInstance(strVal); } - if(clazz == java.util.Locale.class){ + + if (clazz == java.util.Locale.class) { return (T) toLocale(strVal); } + + if (className.startsWith("java.time.")) { + String json = JSON.toJSONString(strVal); + return JSON.parseObject(json, clazz); + } + } + + final ObjectDeserializer objectDeserializer = config.get(clazz); + if (objectDeserializer != null) { + String str = JSON.toJSONString(obj); + return JSON.parseObject(str, clazz); } throw new JSONException("can not cast to : " + clazz.getName()); } - public static Locale toLocale(String strVal){ + public static Locale toLocale(String strVal) { String[] items = strVal.split("_"); - if(items.length == 1){ + if (items.length == 1) { return new Locale(items[0]); } - if(items.length == 2){ + if (items.length == 2) { return new Locale(items[0], items[1]); } return new Locale(items[0], items[1], items[2]); } @SuppressWarnings({"unchecked", "rawtypes"}) - public static T castToEnum(Object obj, Class clazz, ParserConfig mapping){ - try{ - if(obj instanceof String){ + public static T castToEnum(Object obj, Class clazz, ParserConfig mapping) { + try { + if (obj instanceof String) { String name = (String) obj; - if(name.length() == 0){ + if (name.length() == 0) { return null; } + + if (mapping == null) { + mapping = ParserConfig.getGlobalInstance(); + } + + ObjectDeserializer deserializer = mapping.getDeserializer(clazz); + if (deserializer instanceof EnumDeserializer) { + EnumDeserializer enumDeserializer = (EnumDeserializer) deserializer; + return (T) enumDeserializer.getEnumByHashCode(TypeUtils.fnv1a_64(name)); + } + return (T) Enum.valueOf((Class) clazz, name); } - if(obj instanceof Number){ + + if (obj instanceof BigDecimal) { + int ordinal = intValue((BigDecimal) obj); + Object[] values = clazz.getEnumConstants(); + if (ordinal < values.length) { + return (T) values[ordinal]; + } + } + + if (obj instanceof Number) { int ordinal = ((Number) obj).intValue(); Object[] values = clazz.getEnumConstants(); - if(ordinal < values.length){ + if (ordinal < values.length) { return (T) values[ordinal]; } } - } catch(Exception ex){ + } catch (Exception ex) { throw new JSONException("can not cast to : " + clazz.getName(), ex); } throw new JSONException("can not cast to : " + clazz.getName()); } @SuppressWarnings("unchecked") - public static T cast(Object obj, Type type, ParserConfig mapping){ - if(obj == null){ + public static T cast(Object obj, Type type, ParserConfig mapping) { + if (obj == null) { return null; } - if(type instanceof Class){ - return (T) cast(obj, (Class) type, mapping); + if (type instanceof Class) { + return cast(obj, (Class) type, mapping); } - if(type instanceof ParameterizedType){ + if (type instanceof ParameterizedType) { return (T) cast(obj, (ParameterizedType) type, mapping); } - if(obj instanceof String){ + if (obj instanceof String) { String strVal = (String) obj; - if(strVal.length() == 0 // + if (strVal.length() == 0 // || "null".equals(strVal) // - || "NULL".equals(strVal)){ + || "NULL".equals(strVal)) { return null; } } - if(type instanceof TypeVariable){ + if (type instanceof TypeVariable) { return (T) obj; } throw new JSONException("can not cast to : " + type); } @SuppressWarnings({"rawtypes", "unchecked"}) - public static T cast(Object obj, ParameterizedType type, ParserConfig mapping){ + public static T cast(Object obj, ParameterizedType type, ParserConfig mapping) { Type rawTye = type.getRawType(); - if(rawTye == Set.class || rawTye == HashSet.class // + + if (rawTye == List.class || rawTye == ArrayList.class) { + Type itemType = type.getActualTypeArguments()[0]; + if (obj instanceof List) { + List listObj = (List) obj; + List arrayList = new ArrayList(listObj.size()); + + for (Object item : listObj) { + Object itemValue; + if (itemType instanceof Class) { + if (item != null && item.getClass() == JSONObject.class) { + itemValue = ((JSONObject) item).toJavaObject((Class) itemType, mapping, 0); + } else { + itemValue = cast(item, (Class) itemType, mapping); + } + } else { + itemValue = cast(item, itemType, mapping); + } + + arrayList.add(itemValue); + } + return (T) arrayList; + } + } + + if (rawTye == Set.class || rawTye == HashSet.class // || rawTye == TreeSet.class // + || rawTye == Collection.class // || rawTye == List.class // - || rawTye == ArrayList.class){ + || rawTye == ArrayList.class) { Type itemType = type.getActualTypeArguments()[0]; - if(obj instanceof Iterable){ + if (obj instanceof Iterable) { Collection collection; - if(rawTye == Set.class || rawTye == HashSet.class){ + if (rawTye == Set.class || rawTye == HashSet.class) { collection = new HashSet(); - } else if(rawTye == TreeSet.class){ + } else if (rawTye == TreeSet.class) { collection = new TreeSet(); - } else{ + } else { collection = new ArrayList(); } - for(Iterator it = ((Iterable) obj).iterator(); it.hasNext(); ){ - Object item = it.next(); - collection.add(cast(item, itemType, mapping)); + for (Object item : (Iterable) obj) { + Object itemValue; + if (itemType instanceof Class) { + if (item != null && item.getClass() == JSONObject.class) { + itemValue = ((JSONObject) item).toJavaObject((Class) itemType, mapping, 0); + } else { + itemValue = cast(item, (Class) itemType, mapping); + } + } else { + itemValue = cast(item, itemType, mapping); + } + + collection.add(itemValue); } return (T) collection; } } - if(rawTye == Map.class || rawTye == HashMap.class){ + + if (rawTye == Map.class || rawTye == HashMap.class) { Type keyType = type.getActualTypeArguments()[0]; Type valueType = type.getActualTypeArguments()[1]; - if(obj instanceof Map){ + if (obj instanceof Map) { Map map = new HashMap(); - for(Map.Entry entry : ((Map) obj).entrySet()){ + for (Map.Entry entry : ((Map) obj).entrySet()) { Object key = cast(entry.getKey(), keyType, mapping); Object value = cast(entry.getValue(), valueType, mapping); map.put(key, value); @@ -845,40 +1413,63 @@ public static T cast(Object obj, ParameterizedType type, ParserConfig mappin return (T) map; } } - if(obj instanceof String){ + if (obj instanceof String) { String strVal = (String) obj; - if(strVal.length() == 0){ + if (strVal.length() == 0) { return null; } } - if(type.getActualTypeArguments().length == 1){ + + Type[] actualTypeArguments = type.getActualTypeArguments(); + if (actualTypeArguments.length == 1) { Type argType = type.getActualTypeArguments()[0]; - if(argType instanceof WildcardType){ + if (argType instanceof WildcardType) { return (T) cast(obj, rawTye, mapping); } } if (rawTye == Map.Entry.class && obj instanceof Map && ((Map) obj).size() == 1) { Map.Entry entry = (Map.Entry) ((Map) obj).entrySet().iterator().next(); + Object entryValue = entry.getValue(); + if (actualTypeArguments.length == 2 && entryValue instanceof Map) { + Type valueType = actualTypeArguments[1]; + entry.setValue( + cast(entryValue, valueType, mapping) + ); + } return (T) entry; } + if (rawTye instanceof Class) { + if (mapping == null) { + mapping = ParserConfig.global; + } + ObjectDeserializer deserializer = mapping.getDeserializer(rawTye); + if (deserializer != null) { + String str = JSON.toJSONString(obj); + DefaultJSONParser parser = new DefaultJSONParser(str, mapping); + return (T) deserializer.deserialze(parser, type, null); + } + } + throw new JSONException("can not cast to : " + type); } @SuppressWarnings({"unchecked"}) - public static T castToJavaBean(Map map, Class clazz, ParserConfig config){ - try{ - if(clazz == StackTraceElement.class){ + public static T castToJavaBean(Map map, Class clazz, ParserConfig config) { + try { + if (clazz == StackTraceElement.class) { String declaringClass = (String) map.get("className"); String methodName = (String) map.get("methodName"); String fileName = (String) map.get("fileName"); int lineNumber; { Number value = (Number) map.get("lineNumber"); - if(value == null){ + if (value == null) { lineNumber = 0; - } else{ + } else if (value instanceof BigDecimal) { + lineNumber = ((BigDecimal) value).intValueExact(); + } else { lineNumber = value.intValue(); } } @@ -887,50 +1478,50 @@ public static T castToJavaBean(Map map, Class clazz, Parse { Object iClassObject = map.get(JSON.DEFAULT_TYPE_KEY); - if(iClassObject instanceof String){ + if (iClassObject instanceof String) { String className = (String) iClassObject; Class loadClazz; - if(config == null){ + if (config == null) { config = ParserConfig.global; } loadClazz = config.checkAutoType(className, null); - if(loadClazz == null){ + if (loadClazz == null) { throw new ClassNotFoundException(className + " not found"); } - if(!loadClazz.equals(clazz)){ + if (!loadClazz.equals(clazz)) { return (T) castToJavaBean(map, loadClazz, config); } } } - if(clazz.isInterface()){ + if (clazz.isInterface()) { JSONObject object; - if(map instanceof JSONObject){ + if (map instanceof JSONObject) { object = (JSONObject) map; - } else{ + } else { object = new JSONObject(map); } - if(config == null){ + if (config == null) { config = ParserConfig.getGlobalInstance(); } - ObjectDeserializer deserializer = config.getDeserializers().get(clazz); - if(deserializer != null){ + ObjectDeserializer deserializer = config.get(clazz); + if (deserializer != null) { String json = JSON.toJSONString(object); - return (T) JSON.parseObject(json, clazz); + return JSON.parseObject(json, clazz); } return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{clazz}, object); } - if(clazz == Locale.class){ + if (clazz == Locale.class) { Object arg0 = map.get("language"); Object arg1 = map.get("country"); - if(arg0 instanceof String){ + if (arg0 instanceof String) { String language = (String) arg0; - if(arg1 instanceof String){ + if (arg1 instanceof String) { String country = (String) arg1; return (T) new Locale(language, country); - } else if(arg1 == null){ + } else if (arg1 == null) { return (T) new Locale(language); } } @@ -940,37 +1531,68 @@ public static T castToJavaBean(Map map, Class clazz, Parse return (T) map.toString(); } + if (clazz == JSON.class && map instanceof JSONObject) { + return (T) map; + } + if (clazz == LinkedHashMap.class && map instanceof JSONObject) { JSONObject jsonObject = (JSONObject) map; - Map innerMap = jsonObject.getInnerMap(); + Map innerMap = jsonObject.getInnerMap(); if (innerMap instanceof LinkedHashMap) { return (T) innerMap; - } else { - LinkedHashMap linkedHashMap = new LinkedHashMap(); - linkedHashMap.putAll(innerMap); } } + if (clazz.isInstance(map)) { + return (T) map; + } + + if (clazz == JSONObject.class) { + return (T) new JSONObject(map); + } + if (config == null) { config = ParserConfig.getGlobalInstance(); } JavaBeanDeserializer javaBeanDeser = null; - ObjectDeserializer deserizer = config.getDeserializer(clazz); - if (deserizer instanceof JavaBeanDeserializer) { - javaBeanDeser = (JavaBeanDeserializer) deserizer; + ObjectDeserializer deserializer = config.getDeserializer(clazz); + if (deserializer instanceof JavaBeanDeserializer) { + javaBeanDeser = (JavaBeanDeserializer) deserializer; } - if(javaBeanDeser == null){ + if (javaBeanDeser == null) { throw new JSONException("can not get javaBeanDeserializer. " + clazz.getName()); } return (T) javaBeanDeser.createInstance(map, config); - } catch(Exception e){ + } catch (Exception e) { throw new JSONException(e.getMessage(), e); } } - private static void addBaseClassMappings(){ + private static Function>, Void> addBaseClassMappingsFunction = + new Function>, Void>() { + public Void apply(Map> mappings) { + Class[] classes = new Class[]{ + java.sql.Time.class, + java.sql.Date.class, + java.sql.Timestamp.class + }; + for (Class clazz : classes) { + if (clazz == null) { + continue; + } + mappings.put(clazz.getName(), clazz); + } + return null; + } + }; + + static { + addBaseClassMappings(); + } + + private static void addBaseClassMappings() { mappings.put("byte", byte.class); mappings.put("short", short.class); mappings.put("int", int.class); @@ -1029,6 +1651,7 @@ private static void addBaseClassMappings(){ java.lang.VerifyError.class, java.lang.StackTraceElement.class, java.util.HashMap.class, + java.util.LinkedHashMap.class, java.util.Hashtable.class, java.util.TreeMap.class, java.util.IdentityHashMap.class, @@ -1037,206 +1660,198 @@ private static void addBaseClassMappings(){ java.util.HashSet.class, java.util.LinkedHashSet.class, java.util.TreeSet.class, + java.util.ArrayList.class, java.util.concurrent.TimeUnit.class, java.util.concurrent.ConcurrentHashMap.class, - loadClass("java.util.concurrent.ConcurrentSkipListMap"), - loadClass("java.util.concurrent.ConcurrentSkipListSet"), java.util.concurrent.atomic.AtomicInteger.class, java.util.concurrent.atomic.AtomicLong.class, java.util.Collections.EMPTY_MAP.getClass(), + java.lang.Boolean.class, + java.lang.Character.class, + java.lang.Byte.class, + java.lang.Short.class, + java.lang.Integer.class, + java.lang.Long.class, + java.lang.Float.class, + java.lang.Double.class, + java.lang.Number.class, + java.lang.String.class, + java.math.BigDecimal.class, + java.math.BigInteger.class, java.util.BitSet.class, java.util.Calendar.class, java.util.Date.class, - java.util.Locale.class, - java.util.UUID.class, - java.sql.Time.class, - java.sql.Date.class, - java.sql.Timestamp.class, - java.text.SimpleDateFormat.class, - com.alibaba.fastjson.JSONObject.class, - }; - for(Class clazz : classes){ - if(clazz == null){ - continue; - } - mappings.put(clazz.getName(), clazz); - } - String[] awt = new String[]{ - "java.awt.Rectangle", - "java.awt.Point", - "java.awt.Font", - "java.awt.Color"}; - for(String className : awt){ - Class clazz = loadClass(className); - if(clazz == null){ - break; - } - mappings.put(clazz.getName(), clazz); - } - String[] spring = new String[]{ - "org.springframework.util.LinkedMultiValueMap", - "org.springframework.util.LinkedCaseInsensitiveMap", - "org.springframework.remoting.support.RemoteInvocation", - "org.springframework.remoting.support.RemoteInvocationResult", - "org.springframework.security.web.savedrequest.DefaultSavedRequest", - "org.springframework.security.web.savedrequest.SavedCookie", - "org.springframework.security.web.csrf.DefaultCsrfToken", - "org.springframework.security.web.authentication.WebAuthenticationDetails", - "org.springframework.security.core.context.SecurityContextImpl", - "org.springframework.security.authentication.UsernamePasswordAuthenticationToken", - "org.springframework.security.core.authority.SimpleGrantedAuthority", - "org.springframework.security.core.userdetails.User" + java.util.Locale.class, + java.util.UUID.class, + java.text.SimpleDateFormat.class, + com.alibaba.fastjson.JSONObject.class, + com.alibaba.fastjson.JSONPObject.class, + com.alibaba.fastjson.JSONArray.class, }; - for(String className : spring){ - Class clazz = loadClass(className); - if(clazz == null){ - break; + for (Class clazz : classes) { + if (clazz == null) { + continue; } mappings.put(clazz.getName(), clazz); } + ModuleUtil.callWhenHasJavaSql(addBaseClassMappingsFunction, mappings); } - public static void clearClassMapping(){ + public static void clearClassMapping() { mappings.clear(); addBaseClassMappings(); } - public static Class loadClass(String className){ + public static void addMapping(String className, Class clazz) { + mappings.put(className, clazz); + } + + public static Class loadClass(String className) { return loadClass(className, null); } - public static boolean isPath(Class clazz){ - if(pathClass == null && !pathClass_error){ - try{ + public static boolean isPath(Class clazz) { + if (pathClass == null && !pathClass_error) { + try { pathClass = Class.forName("java.nio.file.Path"); - } catch(Throwable ex){ + } catch (Throwable ex) { pathClass_error = true; } } - if(pathClass != null){ + if (pathClass != null) { return pathClass.isAssignableFrom(clazz); } return false; } - public static Class getClassFromMapping(String className){ + public static Class getClassFromMapping(String className) { return mappings.get(className); } public static Class loadClass(String className, ClassLoader classLoader) { - return loadClass(className, classLoader, true); + return loadClass(className, classLoader, false); } public static Class loadClass(String className, ClassLoader classLoader, boolean cache) { - if(className == null || className.length() == 0){ + if (className == null || className.length() == 0) { return null; } + + if (className.length() > 198) { + throw new JSONException("illegal className : " + className); + } + Class clazz = mappings.get(className); - if(clazz != null){ + if (clazz != null) { return clazz; } - if(className.charAt(0) == '['){ + + if (className.charAt(0) == '[') { Class componentType = loadClass(className.substring(1), classLoader); return Array.newInstance(componentType, 0).getClass(); } - if(className.startsWith("L") && className.endsWith(";")){ + + if (className.startsWith("L") && className.endsWith(";")) { String newClassName = className.substring(1, className.length() - 1); return loadClass(newClassName, classLoader); } - try{ - if(classLoader != null){ + + try { + if (classLoader != null) { clazz = classLoader.loadClass(className); if (cache) { mappings.put(className, clazz); } return clazz; } - } catch(Throwable e){ + } catch (Throwable e) { e.printStackTrace(); // skip } - try{ + try { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - if(contextClassLoader != null && contextClassLoader != classLoader){ + if (contextClassLoader != null && contextClassLoader != classLoader) { clazz = contextClassLoader.loadClass(className); if (cache) { mappings.put(className, clazz); } return clazz; } - } catch(Throwable e){ + } catch (Throwable e) { // skip } - try{ + try { clazz = Class.forName(className); - mappings.put(className, clazz); + if (cache) { + mappings.put(className, clazz); + } return clazz; - } catch(Throwable e){ + } catch (Throwable e) { // skip } return clazz; } public static SerializeBeanInfo buildBeanInfo(Class beanType // - , Map aliasMap // - , PropertyNamingStrategy propertyNamingStrategy){ + , Map aliasMap // + , PropertyNamingStrategy propertyNamingStrategy) { return buildBeanInfo(beanType, aliasMap, propertyNamingStrategy, false); } public static SerializeBeanInfo buildBeanInfo(Class beanType // - , Map aliasMap // + , Map aliasMap // , PropertyNamingStrategy propertyNamingStrategy // , boolean fieldBased // - ){ - JSONType jsonType = TypeUtils.getAnnotation(beanType,JSONType.class); + ) { + JSONType jsonType = TypeUtils.getAnnotation(beanType, JSONType.class); String[] orders = null; final int features; String typeName = null, typeKey = null; - if(jsonType != null){ + if (jsonType != null) { orders = jsonType.orders(); typeName = jsonType.typeName(); - if(typeName.length() == 0){ + if (typeName.length() == 0) { typeName = null; } PropertyNamingStrategy jsonTypeNaming = jsonType.naming(); - if (jsonTypeNaming != null && jsonTypeNaming != PropertyNamingStrategy.CamelCase) { + if (jsonTypeNaming != PropertyNamingStrategy.NeverUseThisValueExceptDefaultValue) { propertyNamingStrategy = jsonTypeNaming; } features = SerializerFeature.of(jsonType.serialzeFeatures()); - for(Class supperClass = beanType.getSuperclass() - ; supperClass != null && supperClass != Object.class - ; supperClass = supperClass.getSuperclass()){ - JSONType superJsonType = TypeUtils.getAnnotation(supperClass,JSONType.class); - if(superJsonType == null){ + for (Class supperClass = beanType.getSuperclass() + ; supperClass != null && supperClass != Object.class + ; supperClass = supperClass.getSuperclass()) { + JSONType superJsonType = TypeUtils.getAnnotation(supperClass, JSONType.class); + if (superJsonType == null) { break; } typeKey = superJsonType.typeKey(); - if(typeKey.length() != 0){ + if (typeKey.length() != 0) { break; } } - for(Class interfaceClass : beanType.getInterfaces()){ - JSONType superJsonType = TypeUtils.getAnnotation(interfaceClass,JSONType.class); - if(superJsonType != null){ + for (Class interfaceClass : beanType.getInterfaces()) { + JSONType superJsonType = TypeUtils.getAnnotation(interfaceClass, JSONType.class); + if (superJsonType != null) { typeKey = superJsonType.typeKey(); - if(typeKey.length() != 0){ + if (typeKey.length() != 0) { break; } } } - if(typeKey != null && typeKey.length() == 0){ + if (typeKey != null && typeKey.length() == 0) { typeKey = null; } - } else{ + } else { features = 0; } // fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询 - Map fieldCacheMap = new HashMap(); + Map fieldCacheMap = new HashMap(); ParserConfig.parserAllFieldToCache(beanType, fieldCacheMap); List fieldInfoList = fieldBased ? computeGettersWithFieldBase(beanType, aliasMap, false, propertyNamingStrategy) // @@ -1245,17 +1860,17 @@ public static SerializeBeanInfo buildBeanInfo(Class beanType // fieldInfoList.toArray(fields); FieldInfo[] sortedFields; List sortedFieldList; - if(orders != null && orders.length != 0){ + if (orders != null && orders.length != 0) { sortedFieldList = fieldBased ? computeGettersWithFieldBase(beanType, aliasMap, true, propertyNamingStrategy) // : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, true, propertyNamingStrategy); - } else{ + } else { sortedFieldList = new ArrayList(fieldInfoList); Collections.sort(sortedFieldList); } sortedFields = new FieldInfo[sortedFieldList.size()]; sortedFieldList.toArray(sortedFields); - if(Arrays.equals(sortedFields, fields)){ + if (Arrays.equals(sortedFields, fields)) { sortedFields = fields; } return new SerializeBeanInfo(beanType, jsonType, typeName, typeKey, features, fields, sortedFields); @@ -1263,36 +1878,36 @@ public static SerializeBeanInfo buildBeanInfo(Class beanType // public static List computeGettersWithFieldBase( Class clazz, // - Map aliasMap, // + Map aliasMap, // boolean sorted, // - PropertyNamingStrategy propertyNamingStrategy){ - Map fieldInfoMap = new LinkedHashMap(); - for(Class currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()){ + PropertyNamingStrategy propertyNamingStrategy) { + Map fieldInfoMap = new LinkedHashMap(); + for (Class currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) { Field[] fields = currentClass.getDeclaredFields(); computeFields(currentClass, aliasMap, propertyNamingStrategy, fieldInfoMap, fields); } return getFieldInfos(clazz, sorted, fieldInfoMap); } - public static List computeGetters(Class clazz, Map aliasMap){ + public static List computeGetters(Class clazz, Map aliasMap) { return computeGetters(clazz, aliasMap, true); } - public static List computeGetters(Class clazz, Map aliasMap, boolean sorted){ - JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class); - Map fieldCacheMap = new HashMap(); + public static List computeGetters(Class clazz, Map aliasMap, boolean sorted) { + JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class); + Map fieldCacheMap = new HashMap(); ParserConfig.parserAllFieldToCache(clazz, fieldCacheMap); return computeGetters(clazz, jsonType, aliasMap, fieldCacheMap, sorted, PropertyNamingStrategy.CamelCase); } public static List computeGetters(Class clazz, // JSONType jsonType, // - Map aliasMap, // - Map fieldCacheMap, // + Map aliasMap, // + Map fieldCacheMap, // boolean sorted, // PropertyNamingStrategy propertyNamingStrategy // - ){ - Map fieldInfoMap = new LinkedHashMap(); + ) { + Map fieldInfoMap = new LinkedHashMap(); boolean kotlin = TypeUtils.isKotlin(clazz); // for kotlin Constructor[] constructors = null; @@ -1300,57 +1915,69 @@ public static List computeGetters(Class clazz, // String[] paramNames = null; short[] paramNameMapping = null; Method[] methods = clazz.getMethods(); - for(Method method : methods){ + try { + Arrays.sort(methods, new MethodInheritanceComparator()); + } catch (Throwable ignored) { + + } + + for (Method method : methods) { String methodName = method.getName(); int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; String label = null; - if(Modifier.isStatic(method.getModifiers())){ + if (Modifier.isStatic(method.getModifiers())) { continue; } - if(method.getReturnType().equals(Void.TYPE)){ + + Class returnType = method.getReturnType(); + if (returnType.equals(Void.TYPE)) { continue; } - if(method.getParameterTypes().length != 0){ + + if (method.getParameterTypes().length != 0) { continue; } - if(method.getReturnType() == ClassLoader.class){ + + if (returnType == ClassLoader.class + || returnType == InputStream.class + || returnType == Reader.class) { continue; } - if(methodName.equals("getMetaClass") - && method.getReturnType().getName().equals("groovy.lang.MetaClass")){ + if (methodName.equals("getMetaClass") + && returnType.getName().equals("groovy.lang.MetaClass")) { continue; } - if(methodName.equals("getSuppressed") - && method.getDeclaringClass() == Throwable.class){ + if (methodName.equals("getSuppressed") + && method.getDeclaringClass() == Throwable.class) { continue; } - if(kotlin && isKotlinIgnore(clazz, methodName)){ + if (kotlin && isKotlinIgnore(clazz, methodName)) { continue; } /** - * 如果在属性或者方法上存在JSONField注解,不以类上的propertyNamingStrategy设置为准,此字段的JSONField为准。 + * 如果在属性或者方法上存在JSONField注解,并且定制了name属性,不以类上的propertyNamingStrategy设置为准,以此字段的JSONField的name定制为准。 */ - Boolean fieldAnnotationExists = false; - JSONField annotation = method.getAnnotation(JSONField.class); - if(annotation == null){ + Boolean fieldAnnotationAndNameExists = false; + JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class); + if (annotation == null) { annotation = getSuperMethodAnnotation(clazz, method); } - if(annotation == null && kotlin){ - if(constructors == null){ + if (annotation == null && kotlin) { + if (constructors == null) { constructors = clazz.getDeclaredConstructors(); - Constructor creatorConstructor = TypeUtils.getKoltinConstructor(constructors); - if(creatorConstructor != null){ - paramAnnotationArrays = creatorConstructor.getParameterAnnotations(); + Constructor creatorConstructor = TypeUtils.getKotlinConstructor(constructors); + if (creatorConstructor != null) { + paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor); paramNames = TypeUtils.getKoltinConstructorParameters(clazz); - if(paramNames != null){ + if (paramNames != null) { String[] paramNames_sorted = new String[paramNames.length]; System.arraycopy(paramNames, 0, paramNames_sorted, 0, paramNames.length); Arrays.sort(paramNames_sorted); paramNameMapping = new short[paramNames.length]; - for(short p = 0; p < paramNames.length; p++){ + for (short p = 0; p < paramNames.length; p++) { int index = Arrays.binarySearch(paramNames_sorted, paramNames[p]); paramNameMapping[index] = p; } @@ -1358,7 +1985,7 @@ public static List computeGetters(Class clazz, // } } } - if(paramNames != null && paramNameMapping != null && methodName.startsWith("get")){ + if (paramNames != null && paramNameMapping != null && methodName.startsWith("get")) { String propertyName = decapitalize(methodName.substring(3)); int p = Arrays.binarySearch(paramNames, propertyName); if (p < 0) { @@ -1369,39 +1996,38 @@ public static List computeGetters(Class clazz, // } } } - if(p >= 0){ + if (p >= 0) { short index = paramNameMapping[p]; Annotation[] paramAnnotations = paramAnnotationArrays[index]; - if(paramAnnotations != null){ - for(Annotation paramAnnotation : paramAnnotations){ - if(paramAnnotation instanceof JSONField){ + if (paramAnnotations != null) { + for (Annotation paramAnnotation : paramAnnotations) { + if (paramAnnotation instanceof JSONField) { annotation = (JSONField) paramAnnotation; break; } } } - if(annotation == null){ + if (annotation == null) { Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); - if(field != null){ - annotation = field.getAnnotation(JSONField.class); + if (field != null) { + annotation = TypeUtils.getAnnotation(field, JSONField.class); } } } } } - if(annotation != null){ - fieldAnnotationExists = true; - if(!annotation.serialize()){ + if (annotation != null) { + if (!annotation.serialize()) { continue; } ordinal = annotation.ordinal(); serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures()); parserFeatures = Feature.of(annotation.parseFeatures()); - if(annotation.name().length() != 0){ + if (annotation.name().length() != 0) { String propertyName = annotation.name(); - if(aliasMap != null){ + if (aliasMap != null) { propertyName = aliasMap.get(propertyName); - if(propertyName == null){ + if (propertyName == null) { continue; } } @@ -1410,158 +2036,194 @@ public static List computeGetters(Class clazz, // fieldInfoMap.put(propertyName, fieldInfo); continue; } - if(annotation.label().length() != 0){ + if (annotation.label().length() != 0) { label = annotation.label(); } } - if(methodName.startsWith("get")){ - if(methodName.length() < 4){ + if (methodName.startsWith("get")) { + if (methodName.length() < 4) { continue; } - if(methodName.equals("getClass")){ + if (methodName.equals("getClass")) { continue; } - if(methodName.equals("getDeclaringClass") && clazz.isEnum()){ + if (methodName.equals("getDeclaringClass") && clazz.isEnum()) { continue; } char c3 = methodName.charAt(3); String propertyName; - if(Character.isUpperCase(c3) // + Field field = null; + if (Character.isUpperCase(c3) // || c3 > 512 // for unicode method name - ){ - if(compatibleWithJavaBean){ + ) { + if (compatibleWithJavaBean) { propertyName = decapitalize(methodName.substring(3)); - } else{ - propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + } else { + propertyName = TypeUtils.getPropertyNameByMethodName(methodName); } propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 3); - } else if(c3 == '_'){ - propertyName = methodName.substring(4); - } else if(c3 == 'f'){ + } else if (c3 == '_') { propertyName = methodName.substring(3); - } else if(methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))){ + field = fieldCacheMap.get(propertyName); + if (field == null) { + String temp = propertyName; + propertyName = methodName.substring(4); + field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); + if (field == null) { + propertyName = temp; //减少修改代码带来的影响 + } + } + } else if (c3 == 'f') { + propertyName = methodName.substring(3); + } else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) { propertyName = decapitalize(methodName.substring(3)); - } else{ - continue; + } else { + propertyName = methodName.substring(3); + field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); + if (field == null) { + continue; + } } boolean ignore = isJSONTypeIgnore(clazz, propertyName); - if(ignore){ + if (ignore) { continue; } - //假如bean的field很多的情况一下,轮询时将大大降低效率 - Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); - if(field == null && propertyName.length() > 1){ + + if (field == null) { + // 假如bean的field很多的情况一下,轮询时将大大降低效率 + field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); + } + + if (field == null && propertyName.length() > 1) { char ch = propertyName.charAt(1); - if(ch >= 'A' && ch <= 'Z'){ + if (ch >= 'A' && ch <= 'Z') { String javaBeanCompatiblePropertyName = decapitalize(methodName.substring(3)); field = ParserConfig.getFieldFromCache(javaBeanCompatiblePropertyName, fieldCacheMap); } } JSONField fieldAnnotation = null; - if(field != null){ - fieldAnnotation = field.getAnnotation(JSONField.class); - if(fieldAnnotation != null){ - fieldAnnotationExists = true; - if(!fieldAnnotation.serialize()){ + if (field != null) { + fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class); + if (fieldAnnotation != null) { + if (!fieldAnnotation.serialize()) { continue; } ordinal = fieldAnnotation.ordinal(); serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); - if(fieldAnnotation.name().length() != 0){ + if (fieldAnnotation.name().length() != 0) { + fieldAnnotationAndNameExists = true; propertyName = fieldAnnotation.name(); - if(aliasMap != null){ + if (aliasMap != null) { propertyName = aliasMap.get(propertyName); - if(propertyName == null){ + if (propertyName == null) { continue; } } } - if(fieldAnnotation.label().length() != 0){ + if (fieldAnnotation.label().length() != 0) { label = fieldAnnotation.label(); } } } - if(aliasMap != null){ + if (aliasMap != null) { propertyName = aliasMap.get(propertyName); - if(propertyName == null){ + if (propertyName == null) { continue; } } - if(propertyNamingStrategy != null && !fieldAnnotationExists){ + if (propertyNamingStrategy != null && !fieldAnnotationAndNameExists) { propertyName = propertyNamingStrategy.translate(propertyName); } FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, label); fieldInfoMap.put(propertyName, fieldInfo); } - if(methodName.startsWith("is")){ - if(methodName.length() < 3){ + if (methodName.startsWith("is")) { + if (methodName.length() < 3) { continue; } - if(method.getReturnType() != Boolean.TYPE - && method.getReturnType() != Boolean.class){ + if (returnType != Boolean.TYPE + && returnType != Boolean.class) { continue; } char c2 = methodName.charAt(2); String propertyName; - if(Character.isUpperCase(c2)){ - if(compatibleWithJavaBean){ + Field field = null; + if (Character.isUpperCase(c2)) { + if (compatibleWithJavaBean) { propertyName = decapitalize(methodName.substring(2)); - } else{ + } else { propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3); } propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 2); - } else if(c2 == '_'){ + } else if (c2 == '_') { propertyName = methodName.substring(3); - } else if(c2 == 'f'){ + field = fieldCacheMap.get(propertyName); + if (field == null) { + String temp = propertyName; + propertyName = methodName.substring(2); + field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); + if (field == null) { + propertyName = temp; + } + } + } else if (c2 == 'f') { propertyName = methodName.substring(2); - } else{ - continue; + } else { + propertyName = methodName.substring(2); + field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); + if (field == null) { + continue; + } } boolean ignore = isJSONTypeIgnore(clazz, propertyName); - if(ignore){ + if (ignore) { continue; } - Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); - if(field == null){ + + if (field == null) { + field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap); + } + + if (field == null) { field = ParserConfig.getFieldFromCache(methodName, fieldCacheMap); } JSONField fieldAnnotation = null; - if(field != null){ - fieldAnnotation = field.getAnnotation(JSONField.class); - if(fieldAnnotation != null){ - if(!fieldAnnotation.serialize()){ + if (field != null) { + fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class); + if (fieldAnnotation != null) { + if (!fieldAnnotation.serialize()) { continue; } ordinal = fieldAnnotation.ordinal(); serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); - if(fieldAnnotation.name().length() != 0){ + if (fieldAnnotation.name().length() != 0) { propertyName = fieldAnnotation.name(); - if(aliasMap != null){ + if (aliasMap != null) { propertyName = aliasMap.get(propertyName); - if(propertyName == null){ + if (propertyName == null) { continue; } } } - if(fieldAnnotation.label().length() != 0){ + if (fieldAnnotation.label().length() != 0) { label = fieldAnnotation.label(); } } } - if(aliasMap != null){ + if (aliasMap != null) { propertyName = aliasMap.get(propertyName); - if(propertyName == null){ + if (propertyName == null) { continue; } } - if(propertyNamingStrategy != null){ + if (propertyNamingStrategy != null) { propertyName = propertyNamingStrategy.translate(propertyName); } //优先选择get - if(fieldInfoMap.containsKey(propertyName)){ + if (fieldInfoMap.containsKey(propertyName)) { continue; } FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures, @@ -1574,34 +2236,29 @@ public static List computeGetters(Class clazz, // return getFieldInfos(clazz, sorted, fieldInfoMap); } - private static List getFieldInfos(Class clazz, boolean sorted, Map fieldInfoMap){ + private static List getFieldInfos(Class clazz, boolean sorted, Map fieldInfoMap) { List fieldInfoList = new ArrayList(); String[] orders = null; - JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class); - if(annotation != null){ + JSONType annotation = TypeUtils.getAnnotation(clazz, JSONType.class); + if (annotation != null) { orders = annotation.orders(); } - if(orders != null && orders.length > 0){ - LinkedHashMap map = new LinkedHashMap(fieldInfoList.size()); - for(FieldInfo field : fieldInfoMap.values()){ + if (orders != null && orders.length > 0) { + LinkedHashMap map = new LinkedHashMap(fieldInfoMap.size()); + for (FieldInfo field : fieldInfoMap.values()) { map.put(field.name, field); } - int i = 0; - for(String item : orders){ + for (String item : orders) { FieldInfo field = map.get(item); - if(field != null){ + if (field != null) { fieldInfoList.add(field); map.remove(item); } } - for(FieldInfo field : map.values()){ - fieldInfoList.add(field); - } - } else{ - for(FieldInfo fieldInfo : fieldInfoMap.values()){ - fieldInfoList.add(fieldInfo); - } - if(sorted){ + fieldInfoList.addAll(map.values()); + } else { + fieldInfoList.addAll(fieldInfoMap.values()); + if (sorted) { Collections.sort(fieldInfoList); } } @@ -1610,42 +2267,42 @@ private static List getFieldInfos(Class clazz, boolean sorted, Map private static void computeFields( Class clazz, // - Map aliasMap, // + Map aliasMap, // PropertyNamingStrategy propertyNamingStrategy, // - Map fieldInfoMap, // - Field[] fields){ - for(Field field : fields){ - if(Modifier.isStatic(field.getModifiers())){ + Map fieldInfoMap, // + Field[] fields) { + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers())) { continue; } - JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + JSONField fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class); int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; String propertyName = field.getName(); String label = null; - if(fieldAnnotation != null){ - if(!fieldAnnotation.serialize()){ + if (fieldAnnotation != null) { + if (!fieldAnnotation.serialize()) { continue; } ordinal = fieldAnnotation.ordinal(); serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); - if(fieldAnnotation.name().length() != 0){ + if (fieldAnnotation.name().length() != 0) { propertyName = fieldAnnotation.name(); } - if(fieldAnnotation.label().length() != 0){ + if (fieldAnnotation.label().length() != 0) { label = fieldAnnotation.label(); } } - if(aliasMap != null){ + if (aliasMap != null) { propertyName = aliasMap.get(propertyName); - if(propertyName == null){ + if (propertyName == null) { continue; } } - if(propertyNamingStrategy != null){ + if (propertyNamingStrategy != null) { propertyName = propertyNamingStrategy.translate(propertyName); } - if(!fieldInfoMap.containsKey(propertyName)){ + if (!fieldInfoMap.containsKey(propertyName)) { FieldInfo fieldInfo = new FieldInfo(propertyName, null, field, clazz, null, ordinal, serialzeFeatures, parserFeatures, null, fieldAnnotation, label); fieldInfoMap.put(propertyName, fieldInfo); @@ -1653,10 +2310,10 @@ private static void computeFields( } } - private static String getPropertyNameByCompatibleFieldName(Map fieldCacheMap, String methodName, - String propertyName, int fromIdx){ - if(compatibleWithFieldName){ - if(!fieldCacheMap.containsKey(propertyName)){ + private static String getPropertyNameByCompatibleFieldName(Map fieldCacheMap, String methodName, + String propertyName, int fromIdx) { + if (compatibleWithFieldName) { + if (!fieldCacheMap.containsKey(propertyName)) { String tempPropertyName = methodName.substring(fromIdx); return fieldCacheMap.containsKey(tempPropertyName) ? tempPropertyName : propertyName; } @@ -1664,62 +2321,62 @@ private static String getPropertyNameByCompatibleFieldName(Map fie return propertyName; } - public static JSONField getSuperMethodAnnotation(final Class clazz, final Method method){ + public static JSONField getSuperMethodAnnotation(final Class clazz, final Method method) { Class[] interfaces = clazz.getInterfaces(); - if(interfaces.length > 0){ + if (interfaces.length > 0) { Class[] types = method.getParameterTypes(); - for(Class interfaceClass : interfaces){ - for(Method interfaceMethod : interfaceClass.getMethods()){ + for (Class interfaceClass : interfaces) { + for (Method interfaceMethod : interfaceClass.getMethods()) { Class[] interfaceTypes = interfaceMethod.getParameterTypes(); - if(interfaceTypes.length != types.length){ + if (interfaceTypes.length != types.length) { continue; } - if(!interfaceMethod.getName().equals(method.getName())){ + if (!interfaceMethod.getName().equals(method.getName())) { continue; } boolean match = true; - for(int i = 0; i < types.length; ++i){ - if(!interfaceTypes[i].equals(types[i])){ + for (int i = 0; i < types.length; ++i) { + if (!interfaceTypes[i].equals(types[i])) { match = false; break; } } - if(!match){ + if (!match) { continue; } - JSONField annotation = interfaceMethod.getAnnotation(JSONField.class); - if(annotation != null){ + JSONField annotation = TypeUtils.getAnnotation(interfaceMethod, JSONField.class); + if (annotation != null) { return annotation; } } } } Class superClass = clazz.getSuperclass(); - if(superClass == null){ + if (superClass == null) { return null; } - if(Modifier.isAbstract(superClass.getModifiers())){ + if (Modifier.isAbstract(superClass.getModifiers())) { Class[] types = method.getParameterTypes(); - for(Method interfaceMethod : superClass.getMethods()){ + for (Method interfaceMethod : superClass.getMethods()) { Class[] interfaceTypes = interfaceMethod.getParameterTypes(); - if(interfaceTypes.length != types.length){ + if (interfaceTypes.length != types.length) { continue; } - if(!interfaceMethod.getName().equals(method.getName())){ + if (!interfaceMethod.getName().equals(method.getName())) { continue; } boolean match = true; - for(int i = 0; i < types.length; ++i){ - if(!interfaceTypes[i].equals(types[i])){ + for (int i = 0; i < types.length; ++i) { + if (!interfaceTypes[i].equals(types[i])) { match = false; break; } } - if(!match){ + if (!match) { continue; } - JSONField annotation = interfaceMethod.getAnnotation(JSONField.class); - if(annotation != null){ + JSONField annotation = TypeUtils.getAnnotation(interfaceMethod, JSONField.class); + if (annotation != null) { return annotation; } } @@ -1727,95 +2384,93 @@ public static JSONField getSuperMethodAnnotation(final Class clazz, final Met return null; } - private static boolean isJSONTypeIgnore(Class clazz, String propertyName){ - JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class); - if(jsonType != null){ + private static boolean isJSONTypeIgnore(Class clazz, String propertyName) { + JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class); + if (jsonType != null) { // 1、新增 includes 支持,如果 JSONType 同时设置了includes 和 ignores 属性,则以includes为准。 // 2、个人认为对于大小写敏感的Java和JS而言,使用 equals() 比 equalsIgnoreCase() 更好,改动的唯一风险就是向后兼容性的问题 // 不过,相信开发者应该都是严格按照大小写敏感的方式进行属性设置的 String[] fields = jsonType.includes(); - if(fields.length > 0){ - for(int i = 0; i < fields.length; i++){ - if(propertyName.equals(fields[i])){ + if (fields.length > 0) { + for (String field : fields) { + if (propertyName.equals(field)) { return false; } } return true; - } else{ + } else { fields = jsonType.ignores(); - for(int i = 0; i < fields.length; i++){ - if(propertyName.equals(fields[i])){ + for (String field : fields) { + if (propertyName.equals(field)) { return true; } } } } - if(clazz.getSuperclass() != Object.class && clazz.getSuperclass() != null){ - if(isJSONTypeIgnore(clazz.getSuperclass(), propertyName)){ - return true; - } + if (clazz.getSuperclass() != Object.class && clazz.getSuperclass() != null) { + return isJSONTypeIgnore(clazz.getSuperclass(), propertyName); } return false; } - public static boolean isGenericParamType(Type type){ - if(type instanceof ParameterizedType){ + public static boolean isGenericParamType(Type type) { + if (type instanceof ParameterizedType) { return true; } - if(type instanceof Class){ + if (type instanceof Class) { Type superType = ((Class) type).getGenericSuperclass(); - if(superType == Object.class){ - return false; - } - return isGenericParamType(superType); + return superType != Object.class && isGenericParamType(superType); } return false; } - public static Type getGenericParamType(Type type){ - if(type instanceof ParameterizedType){ + public static Type getGenericParamType(Type type) { + if (type instanceof ParameterizedType) { return type; } - if(type instanceof Class){ + if (type instanceof Class) { return getGenericParamType(((Class) type).getGenericSuperclass()); } return type; } - public static Type unwrapOptional(Type type){ - if(!optionalClassInited){ - try{ + public static Type unwrapOptional(Type type) { + if (!optionalClassInited) { + try { optionalClass = Class.forName("java.util.Optional"); - } catch(Exception e){ + } catch (Exception e) { // skip - } finally{ + } finally { optionalClassInited = true; } } - if(type instanceof ParameterizedType){ + if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; - if(parameterizedType.getRawType() == optionalClass){ + if (parameterizedType.getRawType() == optionalClass) { return parameterizedType.getActualTypeArguments()[0]; } } return type; } - public static Class getClass(Type type){ - if(type.getClass() == Class.class){ + public static Class getClass(Type type) { + if (type.getClass() == Class.class) { return (Class) type; } - if(type instanceof ParameterizedType){ + if (type instanceof ParameterizedType) { return getClass(((ParameterizedType) type).getRawType()); } - if(type instanceof TypeVariable){ + if (type instanceof TypeVariable) { Type boundType = ((TypeVariable) type).getBounds()[0]; - return (Class) boundType; + if (boundType instanceof Class) { + return (Class) boundType; + } + return getClass(boundType); } - if(type instanceof WildcardType){ + if (type instanceof WildcardType) { Type[] upperBounds = ((WildcardType) type).getUpperBounds(); if (upperBounds.length == 1) { return getClass(upperBounds[0]); @@ -1825,10 +2480,10 @@ public static Class getClass(Type type){ return Object.class; } - public static Field getField(Class clazz, String fieldName, Field[] declaredFields){ - for(Field field : declaredFields){ + public static Field getField(Class clazz, String fieldName, Field[] declaredFields) { + for (Field field : declaredFields) { String itemName = field.getName(); - if(fieldName.equals(itemName)){ + if (fieldName.equals(itemName)) { return field; } @@ -1841,95 +2496,171 @@ public static Field getField(Class clazz, String fieldName, Field[] declaredF } } Class superClass = clazz.getSuperclass(); - if(superClass != null && superClass != Object.class){ + if (superClass != null && superClass != Object.class) { return getField(superClass, fieldName, superClass.getDeclaredFields()); } return null; } - public static int getSerializeFeatures(Class clazz){ - JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class); - if(annotation == null){ + /** + * @deprecated + */ + public static int getSerializeFeatures(Class clazz) { + JSONType annotation = TypeUtils.getAnnotation(clazz, JSONType.class); + if (annotation == null) { return 0; } return SerializerFeature.of(annotation.serialzeFeatures()); } - public static int getParserFeatures(Class clazz){ - JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class); - if(annotation == null){ + public static int getParserFeatures(Class clazz) { + JSONType annotation = TypeUtils.getAnnotation(clazz, JSONType.class); + if (annotation == null) { return 0; } return Feature.of(annotation.parseFeatures()); } - public static String decapitalize(String name){ - if(name == null || name.length() == 0){ + public static String decapitalize(String name) { + if (name == null || name.length() == 0) { return name; } - if(name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))){ + if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))) { return name; } - char chars[] = name.toCharArray(); + char[] chars = name.toCharArray(); chars[0] = Character.toLowerCase(chars[0]); return new String(chars); } - static void setAccessible(AccessibleObject obj){ - if(!setAccessibleEnable){ + /** + * resolve property name from get/set method name + * + * @param methodName get/set method name + * @return property name + */ + public static String getPropertyNameByMethodName(String methodName) { + return Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + } + + static void setAccessible(AccessibleObject obj) { + if (!setAccessibleEnable) { return; } - if(obj.isAccessible()){ + if (obj.isAccessible()) { return; } - try{ + try { obj.setAccessible(true); - } catch(AccessControlException error){ + } catch (Throwable error) { setAccessibleEnable = false; } } - public static Type getCollectionItemType(Type fieldType){ - Type itemType = null; - Class clazz = null; - if(fieldType instanceof ParameterizedType){ - Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0]; - if(actualTypeArgument instanceof WildcardType){ - WildcardType wildcardType = (WildcardType) actualTypeArgument; - Type[] upperBounds = wildcardType.getUpperBounds(); - if(upperBounds.length == 1){ - actualTypeArgument = upperBounds[0]; - } + public static Type getCollectionItemType(Type fieldType) { + if (fieldType instanceof ParameterizedType) { + return getCollectionItemType((ParameterizedType) fieldType); + } + if (fieldType instanceof Class) { + return getCollectionItemType((Class) fieldType); + } + return Object.class; + } + + private static Type getCollectionItemType(Class clazz) { + return clazz.getName().startsWith("java.") + ? Object.class + : getCollectionItemType(getCollectionSuperType(clazz)); + } + + private static Type getCollectionItemType(ParameterizedType parameterizedType) { + Type rawType = parameterizedType.getRawType(); + Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); + if (rawType == Collection.class) { + return getWildcardTypeUpperBounds(actualTypeArguments[0]); + } + Class rawClass = (Class) rawType; + Map actualTypeMap = createActualTypeMap(rawClass.getTypeParameters(), actualTypeArguments); + Type superType = getCollectionSuperType(rawClass); + if (superType instanceof ParameterizedType) { + Class superClass = getRawClass(superType); + Type[] superClassTypeParameters = ((ParameterizedType) superType).getActualTypeArguments(); + return superClassTypeParameters.length > 0 + ? getCollectionItemType(makeParameterizedType(superClass, superClassTypeParameters, actualTypeMap)) + : getCollectionItemType(superClass); + } + return getCollectionItemType((Class) superType); + } + + private static Type getCollectionSuperType(Class clazz) { + Type assignable = null; + for (Type type : clazz.getGenericInterfaces()) { + Class rawClass = getRawClass(type); + if (rawClass == Collection.class) { + return type; } - itemType = actualTypeArgument; - } else if(fieldType instanceof Class // - && !(clazz = (Class) fieldType).getName().startsWith("java.")){ - Type superClass = clazz.getGenericSuperclass(); - itemType = TypeUtils.getCollectionItemType(superClass); + if (Collection.class.isAssignableFrom(rawClass)) { + assignable = type; + } + } + return assignable == null ? clazz.getGenericSuperclass() : assignable; + } + + private static Map createActualTypeMap(TypeVariable[] typeParameters, Type[] actualTypeArguments) { + int length = typeParameters.length; + Map actualTypeMap = new HashMap(length); + for (int i = 0; i < length; i++) { + actualTypeMap.put(typeParameters[i], actualTypeArguments[i]); + } + return actualTypeMap; + } + + private static ParameterizedType makeParameterizedType(Class rawClass, Type[] typeParameters, Map actualTypeMap) { + int length = typeParameters.length; + Type[] actualTypeArguments = new Type[length]; + for (int i = 0; i < length; i++) { + actualTypeArguments[i] = getActualType(typeParameters[i], actualTypeMap); + } + return new ParameterizedTypeImpl(actualTypeArguments, null, rawClass); + } + + private static Type getActualType(Type typeParameter, Map actualTypeMap) { + if (typeParameter instanceof TypeVariable) { + return actualTypeMap.get(typeParameter); + } else if (typeParameter instanceof ParameterizedType) { + return makeParameterizedType(getRawClass(typeParameter), ((ParameterizedType) typeParameter).getActualTypeArguments(), actualTypeMap); + } else if (typeParameter instanceof GenericArrayType) { + return new GenericArrayTypeImpl(getActualType(((GenericArrayType) typeParameter).getGenericComponentType(), actualTypeMap)); } - if(itemType == null){ - itemType = Object.class; + return typeParameter; + } + + private static Type getWildcardTypeUpperBounds(Type type) { + if (type instanceof WildcardType) { + WildcardType wildcardType = (WildcardType) type; + Type[] upperBounds = wildcardType.getUpperBounds(); + return upperBounds.length > 0 ? upperBounds[0] : Object.class; } - return itemType; + return type; } - public static Class getCollectionItemClass(Type fieldType){ - if(fieldType instanceof ParameterizedType){ + public static Class getCollectionItemClass(Type fieldType) { + if (fieldType instanceof ParameterizedType) { Class itemClass; Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0]; - if(actualTypeArgument instanceof WildcardType){ + if (actualTypeArgument instanceof WildcardType) { WildcardType wildcardType = (WildcardType) actualTypeArgument; Type[] upperBounds = wildcardType.getUpperBounds(); - if(upperBounds.length == 1){ + if (upperBounds.length == 1) { actualTypeArgument = upperBounds[0]; } } - if(actualTypeArgument instanceof Class){ + if (actualTypeArgument instanceof Class) { itemClass = (Class) actualTypeArgument; - if(!Modifier.isPublic(itemClass.getModifiers())){ + if (!Modifier.isPublic(itemClass.getModifiers())) { throw new JSONException("can not create ASMParser"); } - } else{ + } else { throw new JSONException("can not create ASMParser"); } return itemClass; @@ -1937,9 +2668,20 @@ public static Class getCollectionItemClass(Type fieldType){ return Object.class; } + private static final Map primitiveTypeMap = new HashMap(8) {{ + put(boolean.class, "Z"); + put(char.class, "C"); + put(byte.class, "B"); + put(short.class, "S"); + put(int.class, "I"); + put(long.class, "J"); + put(float.class, "F"); + put(double.class, "D"); + }}; + public static Type checkPrimitiveArray(GenericArrayType genericArrayType) { Type clz = genericArrayType; - Type genericComponentType = genericArrayType.getGenericComponentType(); + Type genericComponentType = genericArrayType.getGenericComponentType(); String prefix = "["; while (genericComponentType instanceof GenericArrayType) { @@ -1952,24 +2694,11 @@ public static Type checkPrimitiveArray(GenericArrayType genericArrayType) { Class ck = (Class) genericComponentType; if (ck.isPrimitive()) { try { - if (ck == boolean.class) { - clz = Class.forName(prefix + "Z"); - } else if (ck == char.class) { - clz = Class.forName(prefix + "C"); - } else if (ck == byte.class) { - clz = Class.forName(prefix + "B"); - } else if (ck == short.class) { - clz = Class.forName(prefix + "S"); - } else if (ck == int.class) { - clz = Class.forName(prefix + "I"); - } else if (ck == long.class) { - clz = Class.forName(prefix + "J"); - } else if (ck == float.class) { - clz = Class.forName(prefix + "F"); - } else if (ck == double.class) { - clz = Class.forName(prefix + "D"); + String postfix = (String) primitiveTypeMap.get(ck); + if (postfix != null) { + clz = Class.forName(prefix + postfix); } - } catch (ClassNotFoundException e) { + } catch (ClassNotFoundException ignored) { } } } @@ -1977,197 +2706,383 @@ public static Type checkPrimitiveArray(GenericArrayType genericArrayType) { return clz; } + public static Set createSet(Type type) { + Class rawClass = getRawClass(type); + Set set; + if (rawClass == AbstractCollection.class // + || rawClass == Collection.class) { + set = new HashSet(); + } else if (rawClass.isAssignableFrom(HashSet.class)) { + set = new HashSet(); + } else if (rawClass.isAssignableFrom(LinkedHashSet.class)) { + set = new LinkedHashSet(); + } else if (rawClass.isAssignableFrom(TreeSet.class)) { + set = new TreeSet(); + } else if (rawClass.isAssignableFrom(EnumSet.class)) { + Type itemType; + if (type instanceof ParameterizedType) { + itemType = ((ParameterizedType) type).getActualTypeArguments()[0]; + } else { + itemType = Object.class; + } + set = EnumSet.noneOf((Class) itemType); + } else { + try { + set = (Set) rawClass.newInstance(); + } catch (Exception e) { + throw new JSONException("create instance error, class " + rawClass.getName()); + } + } + return set; + } + @SuppressWarnings({"rawtypes", "unchecked"}) public static Collection createCollection(Type type) { Class rawClass = getRawClass(type); Collection list; - if(rawClass == AbstractCollection.class // - || rawClass == Collection.class){ + if (rawClass == AbstractCollection.class // + || rawClass == Collection.class) { list = new ArrayList(); - } else if(rawClass.isAssignableFrom(HashSet.class)){ + } else if (rawClass.isAssignableFrom(HashSet.class)) { list = new HashSet(); - } else if(rawClass.isAssignableFrom(LinkedHashSet.class)){ + } else if (rawClass.isAssignableFrom(LinkedHashSet.class)) { list = new LinkedHashSet(); - } else if(rawClass.isAssignableFrom(TreeSet.class)){ + } else if (rawClass.isAssignableFrom(TreeSet.class)) { list = new TreeSet(); - } else if(rawClass.isAssignableFrom(ArrayList.class)){ + } else if (rawClass.isAssignableFrom(ArrayList.class)) { list = new ArrayList(); - } else if(rawClass.isAssignableFrom(EnumSet.class)){ + } else if (rawClass.isAssignableFrom(EnumSet.class)) { Type itemType; - if(type instanceof ParameterizedType){ + if (type instanceof ParameterizedType) { itemType = ((ParameterizedType) type).getActualTypeArguments()[0]; - } else{ + } else { itemType = Object.class; } list = EnumSet.noneOf((Class) itemType); - } else{ - try{ + } else if (rawClass.isAssignableFrom(Queue.class) + || (class_deque != null && rawClass.isAssignableFrom(class_deque))) { + list = new LinkedList(); + } else { + try { list = (Collection) rawClass.newInstance(); - } catch(Exception e){ + } catch (Exception e) { throw new JSONException("create instance error, class " + rawClass.getName()); } } return list; } - public static Class getRawClass(Type type){ - if(type instanceof Class){ + public static Class getRawClass(Type type) { + if (type instanceof Class) { return (Class) type; - } else if(type instanceof ParameterizedType){ + } else if (type instanceof ParameterizedType) { return getRawClass(((ParameterizedType) type).getRawType()); - } else{ + } else if (type instanceof WildcardType) { + WildcardType wildcardType = (WildcardType) type; + Type[] upperBounds = wildcardType.getUpperBounds(); + if (upperBounds.length == 1) { + return getRawClass(upperBounds[0]); + } else { + throw new JSONException("TODO"); + } + } else { throw new JSONException("TODO"); } } - public static boolean isProxy(Class clazz){ - for(Class item : clazz.getInterfaces()){ + private static final Set isProxyClassNames = new HashSet(6) {{ + add("net.sf.cglib.proxy.Factory"); + add("org.springframework.cglib.proxy.Factory"); + add("javassist.util.proxy.ProxyObject"); + add("org.apache.ibatis.javassist.util.proxy.ProxyObject"); + add("org.hibernate.proxy.HibernateProxy"); + add("org.springframework.context.annotation.ConfigurationClassEnhancer$EnhancedConfiguration"); + }}; + + public static boolean isProxy(Class clazz) { + + for (Class item : clazz.getInterfaces()) { String interfaceName = item.getName(); - if(interfaceName.equals("net.sf.cglib.proxy.Factory") // - || interfaceName.equals("org.springframework.cglib.proxy.Factory")){ - return true; - } - if(interfaceName.equals("javassist.util.proxy.ProxyObject") // - || interfaceName.equals("org.apache.ibatis.javassist.util.proxy.ProxyObject") - ){ + if (isProxyClassNames.contains(interfaceName)) { return true; } } return false; } - public static boolean isTransient(Method method){ - if(method == null){ + public static boolean isTransient(Method method) { + if (method == null) { return false; } - if(!transientClassInited){ - try{ + if (!transientClassInited) { + try { transientClass = (Class) Class.forName("java.beans.Transient"); - } catch(Exception e){ + } catch (Exception e) { // skip - } finally{ + } finally { transientClassInited = true; } } - if(transientClass != null){ - Annotation annotation = method.getAnnotation(transientClass); + if (transientClass != null) { + Annotation annotation = TypeUtils.getAnnotation(method, transientClass); return annotation != null; } return false; } - public static boolean isAnnotationPresentOneToMany(Method method){ - if(method == null){ + public static boolean isAnnotationPresentOneToMany(Method method) { + if (method == null) { return false; } - if(class_OneToMany == null && !class_OneToMany_error){ - try{ + if (class_OneToMany == null && !class_OneToMany_error) { + try { class_OneToMany = (Class) Class.forName("javax.persistence.OneToMany"); - } catch(Throwable e){ + } catch (Throwable e) { // skip class_OneToMany_error = true; } } - if(class_OneToMany == null){ - return false; - } + return class_OneToMany != null && method.isAnnotationPresent(class_OneToMany); - return method.isAnnotationPresent(class_OneToMany); } - public static boolean isAnnotationPresentManyToMany(Method method){ - if(method == null){ + public static boolean isAnnotationPresentManyToMany(Method method) { + if (method == null) { return false; } - if(class_ManyToMany == null && !class_ManyToMany_error){ - try{ + if (class_ManyToMany == null && !class_ManyToMany_error) { + try { class_ManyToMany = (Class) Class.forName("javax.persistence.ManyToMany"); - } catch(Throwable e){ + } catch (Throwable e) { // skip class_ManyToMany_error = true; } } - if(class_ManyToMany == null){ - return false; - } + return class_ManyToMany != null && (method.isAnnotationPresent(class_OneToMany) || method.isAnnotationPresent(class_ManyToMany)); - return method.isAnnotationPresent(class_OneToMany) || method.isAnnotationPresent(class_ManyToMany); } - public static boolean isHibernateInitialized(Object object){ - if(object == null){ + public static boolean isHibernateInitialized(Object object) { + if (object == null) { return false; } - if(method_HibernateIsInitialized == null && !method_HibernateIsInitialized_error){ - try{ - Class class_Hibernate = (Class) Class.forName("org.hibernate.Hibernate"); + if (method_HibernateIsInitialized == null && !method_HibernateIsInitialized_error) { + try { + Class class_Hibernate = Class.forName("org.hibernate.Hibernate"); method_HibernateIsInitialized = class_Hibernate.getMethod("isInitialized", Object.class); - } catch(Throwable e){ + } catch (Throwable e) { // skip method_HibernateIsInitialized_error = true; } } - if(method_HibernateIsInitialized != null){ - try{ + if (method_HibernateIsInitialized != null) { + try { Boolean initialized = (Boolean) method_HibernateIsInitialized.invoke(null, object); - return initialized.booleanValue(); - } catch(Throwable e){ + return initialized; + } catch (Throwable e) { // skip } } return true; } - public static long fnv1a_64_lower(String key){ - long hashCode = 0xcbf29ce484222325L; - for(int i = 0; i < key.length(); ++i){ + public static double parseDouble(String str) { + final int len = str.length(); + if (len > 10) { + return Double.parseDouble(str); + } + + boolean negative = false; + + long longValue = 0; + int scale = 0; + for (int i = 0; i < len; ++i) { + char ch = str.charAt(i); + if (ch == '-' && i == 0) { + negative = true; + continue; + } + + if (ch == '.') { + if (scale != 0) { + return Double.parseDouble(str); + } + scale = len - i - 1; + continue; + } + + if (ch >= '0' && ch <= '9') { + int digit = ch - '0'; + longValue = longValue * 10 + digit; + } else { + return Double.parseDouble(str); + } + } + + if (negative) { + longValue = -longValue; + } + + switch (scale) { + case 0: + return (double) longValue; + case 1: + return ((double) longValue) / 10; + case 2: + return ((double) longValue) / 100; + case 3: + return ((double) longValue) / 1000; + case 4: + return ((double) longValue) / 10000; + case 5: + return ((double) longValue) / 100000; + case 6: + return ((double) longValue) / 1000000; + case 7: + return ((double) longValue) / 10000000; + case 8: + return ((double) longValue) / 100000000; + case 9: + return ((double) longValue) / 1000000000; + } + + return Double.parseDouble(str); + } + + public static float parseFloat(String str) { + final int len = str.length(); + if (len >= 10) { + return Float.parseFloat(str); + } + + boolean negative = false; + + long longValue = 0; + int scale = 0; + for (int i = 0; i < len; ++i) { + char ch = str.charAt(i); + if (ch == '-' && i == 0) { + negative = true; + continue; + } + + if (ch == '.') { + if (scale != 0) { + return Float.parseFloat(str); + } + scale = len - i - 1; + continue; + } + + if (ch >= '0' && ch <= '9') { + int digit = ch - '0'; + longValue = longValue * 10 + digit; + } else { + return Float.parseFloat(str); + } + } + + if (negative) { + longValue = -longValue; + } + + switch (scale) { + case 0: + return (float) longValue; + case 1: + return ((float) longValue) / 10; + case 2: + return ((float) longValue) / 100; + case 3: + return ((float) longValue) / 1000; + case 4: + return ((float) longValue) / 10000; + case 5: + return ((float) longValue) / 100000; + case 6: + return ((float) longValue) / 1000000; + case 7: + return ((float) longValue) / 10000000; + case 8: + return ((float) longValue) / 100000000; + case 9: + return ((float) longValue) / 1000000000; + } + + return Float.parseFloat(str); + } + + public static final long fnv1a_64_magic_hashcode = 0xcbf29ce484222325L; + public static final long fnv1a_64_magic_prime = 0x100000001b3L; + + public static long fnv1a_64_extract(String key) { + long hashCode = fnv1a_64_magic_hashcode; + for (int i = 0; i < key.length(); ++i) { char ch = key.charAt(i); - if(ch == '_' || ch == '-'){ + if (ch == '_' || ch == '-') { continue; } - if(ch >= 'A' && ch <= 'Z'){ + if (ch >= 'A' && ch <= 'Z') { + ch = (char) (ch + 32); + } + hashCode ^= ch; + hashCode *= fnv1a_64_magic_prime; + } + return hashCode; + } + + public static long fnv1a_64_lower(String key) { + long hashCode = fnv1a_64_magic_hashcode; + for (int i = 0; i < key.length(); ++i) { + char ch = key.charAt(i); + if (ch >= 'A' && ch <= 'Z') { ch = (char) (ch + 32); } hashCode ^= ch; - hashCode *= 0x100000001b3L; + hashCode *= fnv1a_64_magic_prime; } return hashCode; } - public static long fnv1a_64(String key){ - long hashCode = 0xcbf29ce484222325L; - for(int i = 0; i < key.length(); ++i){ + public static long fnv1a_64(String key) { + long hashCode = fnv1a_64_magic_hashcode; + for (int i = 0; i < key.length(); ++i) { char ch = key.charAt(i); hashCode ^= ch; - hashCode *= 0x100000001b3L; + hashCode *= fnv1a_64_magic_prime; } return hashCode; } - public static boolean isKotlin(Class clazz){ - if(kotlin_metadata == null && !kotlin_metadata_error){ - try{ + public static boolean isKotlin(Class clazz) { + if (kotlin_metadata == null && !kotlin_metadata_error) { + try { kotlin_metadata = Class.forName("kotlin.Metadata"); - } catch(Throwable e){ + } catch (Throwable e) { kotlin_metadata_error = true; } } - if(kotlin_metadata == null){ - return false; - } - return clazz.isAnnotationPresent(kotlin_metadata); + return kotlin_metadata != null && clazz.isAnnotationPresent(kotlin_metadata); + } + + public static Constructor getKotlinConstructor(Constructor[] constructors) { + return getKotlinConstructor(constructors, null); } - public static Constructor getKoltinConstructor(Constructor[] constructors){ + public static Constructor getKotlinConstructor(Constructor[] constructors, String[] paramNames) { Constructor creatorConstructor = null; - for(Constructor constructor : constructors){ + for (Constructor constructor : constructors) { Class[] parameterTypes = constructor.getParameterTypes(); - if(parameterTypes.length > 0 && parameterTypes[parameterTypes.length - 1].getName().equals("kotlin.jvm.internal.DefaultConstructorMarker")){ + if (paramNames != null && parameterTypes.length != paramNames.length) { + continue; + } + + if (parameterTypes.length > 0 && parameterTypes[parameterTypes.length - 1].getName().equals("kotlin.jvm.internal.DefaultConstructorMarker")) { continue; } - if(creatorConstructor != null && creatorConstructor.getParameterTypes().length >= parameterTypes.length){ + if (creatorConstructor != null && creatorConstructor.getParameterTypes().length >= parameterTypes.length) { continue; } creatorConstructor = constructor; @@ -2175,55 +3090,55 @@ public static Constructor getKoltinConstructor(Constructor[] constructors){ return creatorConstructor; } - public static String[] getKoltinConstructorParameters(Class clazz){ - if(kotlin_kclass_constructor == null && !kotlin_class_klass_error){ - try{ + public static String[] getKoltinConstructorParameters(Class clazz) { + if (kotlin_kclass_constructor == null && !kotlin_class_klass_error) { + try { Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl"); kotlin_kclass_constructor = class_kotlin_kclass.getConstructor(Class.class); - } catch(Throwable e){ + } catch (Throwable e) { kotlin_class_klass_error = true; } } - if (kotlin_kclass_constructor == null){ + if (kotlin_kclass_constructor == null) { return null; } if (kotlin_kclass_getConstructors == null && !kotlin_class_klass_error) { - try{ + try { Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl"); kotlin_kclass_getConstructors = class_kotlin_kclass.getMethod("getConstructors"); - } catch(Throwable e){ + } catch (Throwable e) { kotlin_class_klass_error = true; } } if (kotlin_kfunction_getParameters == null && !kotlin_class_klass_error) { - try{ + try { Class class_kotlin_kfunction = Class.forName("kotlin.reflect.KFunction"); kotlin_kfunction_getParameters = class_kotlin_kfunction.getMethod("getParameters"); - } catch(Throwable e){ + } catch (Throwable e) { kotlin_class_klass_error = true; } } if (kotlin_kparameter_getName == null && !kotlin_class_klass_error) { - try{ + try { Class class_kotlinn_kparameter = Class.forName("kotlin.reflect.KParameter"); kotlin_kparameter_getName = class_kotlinn_kparameter.getMethod("getName"); - } catch(Throwable e){ + } catch (Throwable e) { kotlin_class_klass_error = true; } } - if (kotlin_error){ + if (kotlin_error) { return null; } - try{ + try { Object constructor = null; Object kclassImpl = kotlin_kclass_constructor.newInstance(clazz); Iterable it = (Iterable) kotlin_kclass_getConstructors.invoke(kclassImpl); - for(Iterator iterator = it.iterator(); iterator.hasNext(); iterator.hasNext()){ + for (Iterator iterator = it.iterator(); iterator.hasNext(); iterator.hasNext()) { Object item = iterator.next(); List parameters = (List) kotlin_kfunction_getParameters.invoke(item); if (constructor != null && parameters.size() == 0) { @@ -2231,24 +3146,29 @@ public static String[] getKoltinConstructorParameters(Class clazz){ } constructor = item; } + + if (constructor == null) { + return null; + } + List parameters = (List) kotlin_kfunction_getParameters.invoke(constructor); String[] names = new String[parameters.size()]; - for(int i = 0; i < parameters.size(); i++){ + for (int i = 0; i < parameters.size(); i++) { Object param = parameters.get(i); names[i] = (String) kotlin_kparameter_getName.invoke(param); } return names; - } catch(Throwable e){ + } catch (Throwable e) { e.printStackTrace(); kotlin_error = true; } return null; } - private static boolean isKotlinIgnore(Class clazz, String methodName){ - if(kotlinIgnores == null && !kotlinIgnores_error){ - try{ - Map map = new HashMap(); + private static boolean isKotlinIgnore(Class clazz, String methodName) { + if (kotlinIgnores == null && !kotlinIgnores_error) { + try { + Map map = new HashMap(); Class charRangeClass = Class.forName("kotlin.ranges.CharRange"); map.put(charRangeClass, new String[]{"getEndInclusive", "isEmpty"}); Class intRangeClass = Class.forName("kotlin.ranges.IntRange"); @@ -2260,34 +3180,278 @@ private static boolean isKotlinIgnore(Class clazz, String methodName){ Class doubleRangeClass = Class.forName("kotlin.ranges.ClosedDoubleRange"); map.put(doubleRangeClass, new String[]{"getEndInclusive", "isEmpty"}); kotlinIgnores = map; - } catch(Throwable error){ + } catch (Throwable error) { kotlinIgnores_error = true; } } - if(kotlinIgnores == null){ + if (kotlinIgnores == null) { return false; } String[] ignores = kotlinIgnores.get(clazz); - if(ignores == null){ + return ignores != null && Arrays.binarySearch(ignores, methodName) >= 0; + } + + public static A getAnnotation(Class targetClass, Class annotationClass) { + A targetAnnotation = targetClass.getAnnotation(annotationClass); + + Class mixInClass = null; + Type type = JSON.getMixInAnnotations(targetClass); + if (type instanceof Class) { + mixInClass = (Class) type; + } + + if (mixInClass != null) { + A mixInAnnotation = mixInClass.getAnnotation(annotationClass); + Annotation[] annotations = mixInClass.getAnnotations(); + if (mixInAnnotation == null && annotations.length > 0) { + for (Annotation annotation : annotations) { + mixInAnnotation = annotation.annotationType().getAnnotation(annotationClass); + if (mixInAnnotation != null) { + break; + } + } + } + if (mixInAnnotation != null) { + return mixInAnnotation; + } + } + + Annotation[] targetClassAnnotations = targetClass.getAnnotations(); + if (targetAnnotation == null && targetClassAnnotations.length > 0) { + for (Annotation annotation : targetClassAnnotations) { + targetAnnotation = annotation.annotationType().getAnnotation(annotationClass); + if (targetAnnotation != null) { + break; + } + } + } + return targetAnnotation; + } + + public static A getAnnotation(Field field, Class annotationClass) { + A targetAnnotation = field.getAnnotation(annotationClass); + + Class clazz = field.getDeclaringClass(); + A mixInAnnotation; + Class mixInClass = null; + Type type = JSON.getMixInAnnotations(clazz); + if (type instanceof Class) { + mixInClass = (Class) type; + } + + if (mixInClass != null) { + Field mixInField = null; + String fieldName = field.getName(); + // 递归从MixIn类的父类中查找注解(如果有父类的话) + for (Class currClass = mixInClass; currClass != null && currClass != Object.class; + currClass = currClass.getSuperclass()) { + try { + mixInField = currClass.getDeclaredField(fieldName); + break; + } catch (NoSuchFieldException e) { + // skip + } + } + if (mixInField == null) { + return targetAnnotation; + } + mixInAnnotation = mixInField.getAnnotation(annotationClass); + if (mixInAnnotation != null) { + return mixInAnnotation; + } + } + return targetAnnotation; + } + + public static A getAnnotation(Method method, Class annotationClass) { + A targetAnnotation = method.getAnnotation(annotationClass); + + Class clazz = method.getDeclaringClass(); + A mixInAnnotation; + Class mixInClass = null; + Type type = JSON.getMixInAnnotations(clazz); + if (type instanceof Class) { + mixInClass = (Class) type; + } + + if (mixInClass != null) { + Method mixInMethod = null; + String methodName = method.getName(); + Class[] parameterTypes = method.getParameterTypes(); + // 递归从MixIn类的父类中查找注解(如果有父类的话) + for (Class currClass = mixInClass; currClass != null && currClass != Object.class; + currClass = currClass.getSuperclass()) { + try { + mixInMethod = currClass.getDeclaredMethod(methodName, parameterTypes); + break; + } catch (NoSuchMethodException e) { + // skip + } + } + if (mixInMethod == null) { + return targetAnnotation; + } + mixInAnnotation = mixInMethod.getAnnotation(annotationClass); + if (mixInAnnotation != null) { + return mixInAnnotation; + } + } + return targetAnnotation; + } + + public static Annotation[][] getParameterAnnotations(Method method) { + Annotation[][] targetAnnotations = method.getParameterAnnotations(); + + Class clazz = method.getDeclaringClass(); + Annotation[][] mixInAnnotations; + Class mixInClass = null; + Type type = JSON.getMixInAnnotations(clazz); + if (type instanceof Class) { + mixInClass = (Class) type; + } + + if (mixInClass != null) { + Method mixInMethod = null; + String methodName = method.getName(); + Class[] parameterTypes = method.getParameterTypes(); + // 递归从MixIn类的父类中查找注解(如果有父类的话) + for (Class currClass = mixInClass; currClass != null && currClass != Object.class; + currClass = currClass.getSuperclass()) { + try { + mixInMethod = currClass.getDeclaredMethod(methodName, parameterTypes); + break; + } catch (NoSuchMethodException e) { + continue; + } + } + if (mixInMethod == null) { + return targetAnnotations; + } + mixInAnnotations = mixInMethod.getParameterAnnotations(); + if (mixInAnnotations != null) { + return mixInAnnotations; + } + } + return targetAnnotations; + } + + public static Annotation[][] getParameterAnnotations(Constructor constructor) { + Annotation[][] targetAnnotations = constructor.getParameterAnnotations(); + + Class clazz = constructor.getDeclaringClass(); + Annotation[][] mixInAnnotations; + Class mixInClass = null; + Type type = JSON.getMixInAnnotations(clazz); + if (type instanceof Class) { + mixInClass = (Class) type; + } + + if (mixInClass != null) { + Constructor mixInConstructor = null; + Class[] parameterTypes = constructor.getParameterTypes(); + // 构建参数列表,因为内部类的构造函数需要传入外部类的引用 + List> enclosingClasses = new ArrayList>(2); + for (Class enclosingClass = mixInClass.getEnclosingClass(); enclosingClass != null; enclosingClass = enclosingClass.getEnclosingClass()) { + enclosingClasses.add(enclosingClass); + } + int level = enclosingClasses.size(); + // 递归从MixIn类的父类中查找注解(如果有父类的话) + for (Class currClass = mixInClass; currClass != null && currClass != Object.class; + currClass = currClass.getSuperclass()) { + try { + if (level != 0) { + Class[] outerClassAndParameterTypes = new Class[level + parameterTypes.length]; + System.arraycopy(parameterTypes, 0, outerClassAndParameterTypes, level, parameterTypes.length); + for (int i = level; i > 0; i--) { + outerClassAndParameterTypes[i - 1] = enclosingClasses.get(i - 1); + } + mixInConstructor = mixInClass.getDeclaredConstructor(outerClassAndParameterTypes); + } else { + mixInConstructor = mixInClass.getDeclaredConstructor(parameterTypes); + } + break; + } catch (NoSuchMethodException e) { + level--; + } + } + if (mixInConstructor == null) { + return targetAnnotations; + } + mixInAnnotations = mixInConstructor.getParameterAnnotations(); + if (mixInAnnotations != null) { + return mixInAnnotations; + } + } + return targetAnnotations; + } + + public static boolean isJacksonCreator(Method method) { + if (method == null) { return false; } - return Arrays.binarySearch(ignores, methodName) >= 0; + + if (class_JacksonCreator == null && !class_JacksonCreator_error) { + try { + class_JacksonCreator = (Class) Class.forName("com.fasterxml.jackson.annotation.JsonCreator"); + } catch (Throwable e) { + // skip + class_JacksonCreator_error = true; + } + } + return class_JacksonCreator != null && method.isAnnotationPresent(class_JacksonCreator); } - public static A getAnnotation(Class clazz, Class annotationClass){ - A a = clazz.getAnnotation(annotationClass); - if (a != null){ - return a; + private static Object OPTIONAL_EMPTY; + private static boolean OPTIONAL_ERROR = false; + + public static Object optionalEmpty(Type type) { + if (OPTIONAL_ERROR) { + return null; + } + + Class clazz = getClass(type); + if (clazz == null) { + return null; } - if(clazz.getAnnotations().length > 0){ - for(Annotation annotation : clazz.getAnnotations()){ - a = annotation.annotationType().getAnnotation(annotationClass); - if(a != null){ - return a; + String className = clazz.getName(); + + if ("java.util.Optional".equals(className)) { + if (OPTIONAL_EMPTY == null) { + try { + Method empty = Class.forName(className).getMethod("empty"); + OPTIONAL_EMPTY = empty.invoke(null); + } catch (Throwable e) { + OPTIONAL_ERROR = true; } } + return OPTIONAL_EMPTY; } return null; } + + public static class MethodInheritanceComparator implements Comparator { + public int compare(Method m1, Method m2) { + int cmp = m1.getName().compareTo(m2.getName()); + if (cmp != 0) { + return cmp; + } + + Class class1 = m1.getReturnType(); + Class class2 = m2.getReturnType(); + + if (class1.equals(class2)) { + return 0; + } + + if (class1.isAssignableFrom(class2)) { + return -1; + } + + if (class2.isAssignableFrom(class1)) { + return 1; + } + return 0; + } + } } diff --git a/src/main/java/com/alibaba/fastjson/util/UTF8Decoder.java b/src/main/java/com/alibaba/fastjson/util/UTF8Decoder.java index 27d5b232c9..b76c2e686c 100644 --- a/src/main/java/com/alibaba/fastjson/util/UTF8Decoder.java +++ b/src/main/java/com/alibaba/fastjson/util/UTF8Decoder.java @@ -106,12 +106,14 @@ public static CoderResult malformedN(ByteBuffer src, int nb) { private static CoderResult malformed(ByteBuffer src, int sp, CharBuffer dst, int dp, int nb) { src.position(sp - src.arrayOffset()); CoderResult cr = malformedN(src, nb); - updatePositions(src, sp, dst, dp); + src.position(sp); + dst.position(dp); return cr; } private static CoderResult xflow(Buffer src, int sp, int sl, Buffer dst, int dp, int nb) { - updatePositions(src, sp, dst, dp); + src.position(sp); + dst.position(dp); return (nb == 0 || sl - sp < nb) ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; } @@ -172,11 +174,11 @@ private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) { int b3 = srcArray[srcPosition + 2]; int b4 = srcArray[srcPosition + 3]; int uc = ((b1 & 0x07) << 18) | ((b2 & 0x3f) << 12) | ((b3 & 0x3f) << 06) | (b4 & 0x3f); - if (isMalformed4(b2, b3, b4) || !Surrogate.neededFor(uc)) { + if (isMalformed4(b2, b3, b4) || !((uc >= 0x10000) && (uc <= 1114111))) { return malformed(src, srcPosition, dst, destPosition, 4); } - destArray[destPosition++] = Surrogate.high(uc); - destArray[destPosition++] = Surrogate.low(uc); + destArray[destPosition++] = (char) (0xd800 | (((uc - 0x10000) >> 10) & 0x3ff)); + destArray[destPosition++] = (char) (0xdc00 | ((uc - 0x10000) & 0x3ff)); srcPosition += 4; } else { return malformed(src, srcPosition, dst, destPosition, 1); @@ -189,30 +191,7 @@ protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { return decodeArrayLoop(src, dst); } - static void updatePositions(Buffer src, int sp, Buffer dst, int dp) { -// src.position(sp - src.arrayOffset()); -// dst.position(dp - dst.arrayOffset()); - src.position(sp); - dst.position(dp); - } - private static class Surrogate { - public static final int UCS4_MIN = 0x10000; - public static final int UCS4_MAX = (1 << 20) + UCS4_MIN - 1; - public static boolean neededFor(int uc) { - return (uc >= UCS4_MIN) && (uc <= UCS4_MAX); - } - - public static char high(int uc) { - assert neededFor(uc); - return (char) (0xd800 | (((uc - UCS4_MIN) >> 10) & 0x3ff)); - } - - public static char low(int uc) { - assert neededFor(uc); - return (char) (0xdc00 | ((uc - UCS4_MIN) & 0x3ff)); - } - } } diff --git a/src/test/java/cn/com/tx/domain/notifyDetail/NotifyDetail.java b/src/test/java/cn/com/tx/domain/notifyDetail/NotifyDetail.java old mode 100755 new mode 100644 diff --git a/src/test/java/cn/com/tx/domain/pagination/Pagination.java b/src/test/java/cn/com/tx/domain/pagination/Pagination.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/fastjson/JSONPathTest.java b/src/test/java/com/alibaba/fastjson/JSONPathTest.java new file mode 100644 index 0000000000..cf74af65f3 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/JSONPathTest.java @@ -0,0 +1,177 @@ +/* + * Copyright 2018 Diffblue Limited + * + * 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. + * + */ + +package com.alibaba.fastjson; + +import com.alibaba.fastjson.JSONPath; +import com.diffblue.deeptestutils.Reflector; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + + +public class JSONPathTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + /* testedClasses: JSONPath */ + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 2547 branch to line 2551 + * - conditional line 2551 branch to line 2551 + * - conditional line 2551 branch to line 2552 + */ + @Test + public void eq1() throws Throwable { + // Arrange + Object a = -1; + Object b = null; + // Act + Class c = Reflector.forName("com.alibaba.fastjson.JSONPath"); + Method m = c.getDeclaredMethod("eq", Reflector.forName("java.lang.Object"), Reflector.forName("java.lang.Object")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, a, b); + // Assert result + Assert.assertEquals(false, retval); + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 2547 branch to line 2548 + */ + @Test + public void eq2() throws Throwable { + // Arrange + Object a = null; + Object b = null; + // Act + Class c = Reflector.forName("com.alibaba.fastjson.JSONPath"); + Method m = c.getDeclaredMethod("eq", Reflector.forName("java.lang.Object"), Reflector.forName("java.lang.Object")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, a, b); + // Assert result + Assert.assertEquals(true, retval); + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 1434 branch to line 1434 + */ + @Test + public void isDigitFirst1() throws Throwable { + // Arrange + char ch = '2'; + // Act + Class c = Reflector.forName("com.alibaba.fastjson.JSONPath$JSONPathParser"); + Method m = c.getDeclaredMethod("isDigitFirst", Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, ch); + // Assert result + Assert.assertEquals(true, retval); + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 1434 branch to line 1434 + */ + @Test + public void isDigitFirst2() throws Throwable { + // Arrange + char ch = ':'; + // Act + Class c = Reflector.forName("com.alibaba.fastjson.JSONPath$JSONPathParser"); + Method m = c.getDeclaredMethod("isDigitFirst", Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, ch); + // Assert result + Assert.assertEquals(false, retval); + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 1434 branch to line 1434 + */ + @Test + public void isDigitFirst3() throws Throwable { + // Arrange + char ch = '\u0000'; + // Act + Class c = Reflector.forName("com.alibaba.fastjson.JSONPath$JSONPathParser"); + Method m = c.getDeclaredMethod("isDigitFirst", Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, ch); + // Assert result + Assert.assertEquals(false, retval); + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 674 branch to line 674 + */ + @Test + public void isEOF1() throws Throwable { + // Arrange + Object objectUnderTest = Reflector.getInstance("com.alibaba.fastjson.JSONPath$JSONPathParser"); + Reflector.setField(objectUnderTest, "path", ""); + Reflector.setField(objectUnderTest, "pos", -2147483647); + Reflector.setField(objectUnderTest, "level", 0); + Reflector.setField(objectUnderTest, "ch", '\u0000'); + // Act + Class c = Reflector.forName("com.alibaba.fastjson.JSONPath$JSONPathParser"); + Method m = c.getDeclaredMethod("isEOF"); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest); + // Assert result + Assert.assertEquals(false, retval); + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 674 branch to line 674 + */ + @Test + public void isEOF2() throws Throwable { + // Arrange + Object objectUnderTest = Reflector.getInstance("com.alibaba.fastjson.JSONPath$JSONPathParser"); + Reflector.setField(objectUnderTest, "path", "!"); + Reflector.setField(objectUnderTest, "pos", 1); + Reflector.setField(objectUnderTest, "level", 0); + Reflector.setField(objectUnderTest, "ch", '\u0000'); + // Act + Class c = Reflector.forName("com.alibaba.fastjson.JSONPath$JSONPathParser"); + Method m = c.getDeclaredMethod("isEOF"); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest); + // Assert result + Assert.assertEquals(true, retval); + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/IgnoreTypeDeserializer.java b/src/test/java/com/alibaba/fastjson/deserializer/IgnoreTypeDeserializer.java index 8282a05d54..cd05cd720d 100644 --- a/src/test/java/com/alibaba/fastjson/deserializer/IgnoreTypeDeserializer.java +++ b/src/test/java/com/alibaba/fastjson/deserializer/IgnoreTypeDeserializer.java @@ -4,7 +4,10 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; @@ -12,6 +15,17 @@ * Created by jiangyu on 2017-03-03 11:33. */ public class IgnoreTypeDeserializer { + + @Before + public void before() { + ParserConfig.global.setAutoTypeSupport(true); + } + + @After + public void after() { + ParserConfig.global.setAutoTypeSupport(false); + } + @Test(expected = JSONException.class) public void parseObjectWithNotExistTypeThrowException() { String s = "{\"@type\":\"com.alibaba.fastjson.ValueBean\",\"val\":1}"; diff --git a/src/test/java/com/alibaba/fastjson/deserializer/TestISO8601Date.java b/src/test/java/com/alibaba/fastjson/deserializer/TestISO8601Date.java new file mode 100644 index 0000000000..5719a20f82 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/TestISO8601Date.java @@ -0,0 +1,61 @@ +package com.alibaba.fastjson.deserializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; +import org.junit.*; + +import java.util.*; + +/** + * Issue #1884 Test Case + * + * @author cnzgray@qq.com + * @since 2018-05-31 17:15 + */ +public class TestISO8601Date { + @Before + public void init() { + JSON.DEFAULT_PARSER_FEATURE |= Feature.AllowISO8601DateFormat.mask; + } + + @Test + public void testBug1884() { + Calendar cale = Calendar.getInstance(); + cale.clear(); + cale.setTimeZone( TimeZone.getTimeZone( "GMT+7" ) ); + cale.set( 2018, Calendar.MAY, 31, 19, 13, 42 ); + Date date = cale.getTime(); + + String s1 = "{date: \"2018-05-31T19:13:42+07:00\"}"; // 错误的 + String s2 = "{date: \"2018-05-31T19:13:42.000+07:00\"}"; // 正确的 + Date date1 = JSON.parseObject( s1, JSONObject.class ).getDate( "date" ); + Date date2 = JSON.parseObject( s2, JSONObject.class ).getDate( "date" ); + assertEquals(date1, date2); + assertEquals(date, date1); + assertEquals(date, date2); + } + + @Test + public void testBug376() { + Calendar cale = Calendar.getInstance(); + cale.clear(); + cale.setTimeZone( TimeZone.getTimeZone( "GMT" ) ); + cale.set( 2018, Calendar.MAY, 31, 19, 13, 42 ); + Date date = cale.getTime(); + + String s1 = "{date: \"2018-05-31T19:13:42Z\"}"; + String s2 = "{date: \"2018-05-31T19:13:42.000Z\"}"; + + Date date1 = JSON.parseObject( s1, JSONObject.class ).getDate( "date" ); + Date date2 = JSON.parseObject( s2, JSONObject.class ).getDate( "date" ); + + assertEquals( date1, date2 ); + assertEquals( date, date1 ); + assertEquals( date, date2 ); + } + + private void assertEquals( Date expected, Date actual ) { + Assert.assertEquals( 0, expected.compareTo( actual ) ); + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2358/TestJson.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2358/TestJson.java new file mode 100644 index 0000000000..21a74766f5 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2358/TestJson.java @@ -0,0 +1,64 @@ +package com.alibaba.fastjson.deserializer.issue2358; + +import com.alibaba.fastjson.JSONObject; + +import java.util.List; + +/** + * Created by liangchuyi on 2019/4/8. + */ +public class TestJson { + + private String test1; + private String test2; + + public String getTest1() { + return test1; + } + + public void setTest1(String test1) { + this.test1 = test1; + } + + public String getTest2() { + return test2; + } + + public void setTest2(String test2) { + this.test2 = test2; + } + + class TestJson2 { + private String test1; + private String test2; + + public String getTest1() { + return test1; + } + + public void setTest1(String test1) { + this.test1 = test1; + } + + public String getTest2() { + return test2; + } + + public void setTest2(String test2) { + this.test2 = test2; + } + } + + public static void main(String args[]) { + String str = "[{\n" + + " \"test1\":\"1\",\n" + + " \"test2\":\"2\"\n" + + "},\n" + + " {\n" + + " \"test1\":\"1\",\n" + + " \"test2\":\"2\"\n" + + " }]"; + List testJsons = JSONObject.parseArray(str, TestJson2.class); + System.out.println(testJsons); + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2638/Person.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2638/Person.java new file mode 100644 index 0000000000..46f5d18def --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2638/Person.java @@ -0,0 +1,26 @@ +package com.alibaba.fastjson.deserializer.issue2638; + +class Person { + private String name; + private Integer age; + + public Person(){} + + public Person(String name, Integer age) { + super(); + this.name = name; + this.age = age; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public Integer getAge() { + return age; + } + public void setAge(Integer age) { + this.age = age; + } + } \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2638/TestIssue2638.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2638/TestIssue2638.java new file mode 100644 index 0000000000..c41fe15d73 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2638/TestIssue2638.java @@ -0,0 +1,18 @@ +package com.alibaba.fastjson.deserializer.issue2638; + +import com.alibaba.fastjson.JSON; +import org.junit.Test; + +/** + * @Author:JacceYang chaoyang_sjtu@126.com + * @Description: + * @Data:Initialized in 7:54 PM 2019/8/17 + **/ +public class TestIssue2638 { + + @Test + public void testBug2638() { + String str="}"; + JSON.parseObject(str,Person.class); + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2711/PageRequest.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2711/PageRequest.java new file mode 100644 index 0000000000..2d1e17ae66 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2711/PageRequest.java @@ -0,0 +1,34 @@ +package com.alibaba.fastjson.deserializer.issue2711; + +import com.alibaba.fastjson.annotation.JSONField; + +public class PageRequest { + @JSONField(unwrapped = true) + T data; + int from = 0; + int size = 10; + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public int getFrom() { + return from; + } + + public void setFrom(int from) { + this.from = from; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2711/TestIssue.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2711/TestIssue.java new file mode 100644 index 0000000000..0038359172 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2711/TestIssue.java @@ -0,0 +1,21 @@ +package com.alibaba.fastjson.deserializer.issue2711; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import org.junit.Assert; +import org.junit.Test; + +public class TestIssue { + @Test + public void testDeserializeGenericsUnwrapped() { + PageRequest req = new PageRequest(); + req.setData(new User(1L, "jack")); + req.setFrom(10); + req.setSize(20); + String s = JSON.toJSONString(req); + System.out.println(s); + + PageRequest newReq = JSON.parseObject(s, new TypeReference>() {}); + Assert.assertNotNull(newReq); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2711/User.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2711/User.java new file mode 100644 index 0000000000..0ee099019f --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2711/User.java @@ -0,0 +1,35 @@ +package com.alibaba.fastjson.deserializer.issue2711; + +public class User { + Long id; + String name; + + public User(Long id, String name) { + this.id = id; + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2779/Issue2779Test.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2779/Issue2779Test.java new file mode 100644 index 0000000000..e86736819f --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2779/Issue2779Test.java @@ -0,0 +1,12 @@ +package com.alibaba.fastjson.deserializer.issue2779; + +import com.alibaba.fastjson.JSON; +import org.junit.Test; + +// https://github.com/alibaba/fastjson/issues/2779 +public class Issue2779Test { + @Test + public void canDeserializeLargeJavaBean() { + JSON.parseObject("{}", LargeJavaBean.class); + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2779/LargeJavaBean.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2779/LargeJavaBean.java new file mode 100644 index 0000000000..49570e2524 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2779/LargeJavaBean.java @@ -0,0 +1,615 @@ +package com.alibaba.fastjson.deserializer.issue2779; + +import java.util.List; + +public class LargeJavaBean { + public List getList100() { + return list100; + } + + public void setList100(List list100) { + this.list100 = list100; + } + + public List getList101() { + return list101; + } + + public void setList101(List list101) { + this.list101 = list101; + } + + public List getList102() { + return list102; + } + + public void setList102(List list102) { + this.list102 = list102; + } + + public List getList103() { + return list103; + } + + public void setList103(List list103) { + this.list103 = list103; + } + + public List getList104() { + return list104; + } + + public void setList104(List list104) { + this.list104 = list104; + } + + public List getList105() { + return list105; + } + + public void setList105(List list105) { + this.list105 = list105; + } + + public List getList106() { + return list106; + } + + public void setList106(List list106) { + this.list106 = list106; + } + + public List getList107() { + return list107; + } + + public void setList107(List list107) { + this.list107 = list107; + } + + public List getList108() { + return list108; + } + + public void setList108(List list108) { + this.list108 = list108; + } + + public List getList109() { + return list109; + } + + public void setList109(List list109) { + this.list109 = list109; + } + + public List getList110() { + return list110; + } + + public void setList110(List list110) { + this.list110 = list110; + } + + public List getList111() { + return list111; + } + + public void setList111(List list111) { + this.list111 = list111; + } + + public List getList112() { + return list112; + } + + public void setList112(List list112) { + this.list112 = list112; + } + + public List getList113() { + return list113; + } + + public void setList113(List list113) { + this.list113 = list113; + } + + public List getList114() { + return list114; + } + + public void setList114(List list114) { + this.list114 = list114; + } + + public List getList115() { + return list115; + } + + public void setList115(List list115) { + this.list115 = list115; + } + + public List getList116() { + return list116; + } + + public void setList116(List list116) { + this.list116 = list116; + } + + public List getList117() { + return list117; + } + + public void setList117(List list117) { + this.list117 = list117; + } + + public List getList118() { + return list118; + } + + public void setList118(List list118) { + this.list118 = list118; + } + + public List getList119() { + return list119; + } + + public void setList119(List list119) { + this.list119 = list119; + } + + public List getList120() { + return list120; + } + + public void setList120(List list120) { + this.list120 = list120; + } + + public List getList121() { + return list121; + } + + public void setList121(List list121) { + this.list121 = list121; + } + + public List getList122() { + return list122; + } + + public void setList122(List list122) { + this.list122 = list122; + } + + public List getList123() { + return list123; + } + + public void setList123(List list123) { + this.list123 = list123; + } + + public List getList124() { + return list124; + } + + public void setList124(List list124) { + this.list124 = list124; + } + + public List getList125() { + return list125; + } + + public void setList125(List list125) { + this.list125 = list125; + } + + public List getList126() { + return list126; + } + + public void setList126(List list126) { + this.list126 = list126; + } + + public List getList127() { + return list127; + } + + public void setList127(List list127) { + this.list127 = list127; + } + + public List getList128() { + return list128; + } + + public void setList128(List list128) { + this.list128 = list128; + } + + public List getList129() { + return list129; + } + + public void setList129(List list129) { + this.list129 = list129; + } + + public List getList130() { + return list130; + } + + public void setList130(List list130) { + this.list130 = list130; + } + + public List getList131() { + return list131; + } + + public void setList131(List list131) { + this.list131 = list131; + } + + public List getList132() { + return list132; + } + + public void setList132(List list132) { + this.list132 = list132; + } + + public List getList133() { + return list133; + } + + public void setList133(List list133) { + this.list133 = list133; + } + + public List getList134() { + return list134; + } + + public void setList134(List list134) { + this.list134 = list134; + } + + public List getList135() { + return list135; + } + + public void setList135(List list135) { + this.list135 = list135; + } + + public List getList136() { + return list136; + } + + public void setList136(List list136) { + this.list136 = list136; + } + + public List getList137() { + return list137; + } + + public void setList137(List list137) { + this.list137 = list137; + } + + public List getList138() { + return list138; + } + + public void setList138(List list138) { + this.list138 = list138; + } + + public List getList139() { + return list139; + } + + public void setList139(List list139) { + this.list139 = list139; + } + + public List getList140() { + return list140; + } + + public void setList140(List list140) { + this.list140 = list140; + } + + public List getList141() { + return list141; + } + + public void setList141(List list141) { + this.list141 = list141; + } + + public List getList142() { + return list142; + } + + public void setList142(List list142) { + this.list142 = list142; + } + + public List getList143() { + return list143; + } + + public void setList143(List list143) { + this.list143 = list143; + } + + public List getList144() { + return list144; + } + + public void setList144(List list144) { + this.list144 = list144; + } + + public List getList145() { + return list145; + } + + public void setList145(List list145) { + this.list145 = list145; + } + + public List getList146() { + return list146; + } + + public void setList146(List list146) { + this.list146 = list146; + } + + public List getList147() { + return list147; + } + + public void setList147(List list147) { + this.list147 = list147; + } + + public List getList148() { + return list148; + } + + public void setList148(List list148) { + this.list148 = list148; + } + + public List getList149() { + return list149; + } + + public void setList149(List list149) { + this.list149 = list149; + } + + public List getList150() { + return list150; + } + + public void setList150(List list150) { + this.list150 = list150; + } + + public List getList151() { + return list151; + } + + public void setList151(List list151) { + this.list151 = list151; + } + + public List getList152() { + return list152; + } + + public void setList152(List list152) { + this.list152 = list152; + } + + public List getList153() { + return list153; + } + + public void setList153(List list153) { + this.list153 = list153; + } + + public List getList154() { + return list154; + } + + public void setList154(List list154) { + this.list154 = list154; + } + + public List getList155() { + return list155; + } + + public void setList155(List list155) { + this.list155 = list155; + } + + public List getList156() { + return list156; + } + + public void setList156(List list156) { + this.list156 = list156; + } + + public List getList157() { + return list157; + } + + public void setList157(List list157) { + this.list157 = list157; + } + + public List getList158() { + return list158; + } + + public void setList158(List list158) { + this.list158 = list158; + } + + public List getList159() { + return list159; + } + + public void setList159(List list159) { + this.list159 = list159; + } + + public List getList160() { + return list160; + } + + public void setList160(List list160) { + this.list160 = list160; + } + + public List getList161() { + return list161; + } + + public void setList161(List list161) { + this.list161 = list161; + } + + public List getList162() { + return list162; + } + + public void setList162(List list162) { + this.list162 = list162; + } + + public List getList163() { + return list163; + } + + public void setList163(List list163) { + this.list163 = list163; + } + + // provide by zhaiyao, for fastjson test + private List list100; + private List list101; + private List list102; + private List list103; + private List list104; + private List list105; + private List list106; + private List list107; + private List list108; + private List list109; + private List list110; + private List list111; + private List list112; + private List list113; + private List list114; + private List list115; + private List list116; + private List list117; + private List list118; + private List list119; + private List list120; + private List list121; + private List list122; + private List list123; + private List list124; + private List list125; + private List list126; + private List list127; + private List list128; + private List list129; + private List list130; + private List list131; + private List list132; + private List list133; + private List list134; + private List list135; + private List list136; + private List list137; + private List list138; + private List list139; + private List list140; + private List list141; + private List list142; + private List list143; + private List list144; + private List list145; + private List list146; + private List list147; + private List list148; + private List list149; + private List list150; + private List list151; + private List list152; + private List list153; + private List list154; + private List list155; + private List list156; + private List list157; + private List list158; + private List list159; + private List list160; + private List list161; + private List list162; + private List list163; + + + public static class Alphabet { + // provide by zhaiyao, for fastjson test + private List a; + private List b; + private List c; + private List d; + private List e; + private List f; + private List g; + private List h; + private List i; + private List j; + private List k; + private List l; + private List m; + private List n; + private List o; + private List p; + private List q; + private List r; + private List s; + private List t; + private List u; + private List v; + private List w; + private List x; + private List y; + private List z; + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2898/TestIssue2898.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2898/TestIssue2898.java new file mode 100644 index 0000000000..5ff4ec1a2a --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2898/TestIssue2898.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.deserializer.issue2898; + +import java.io.IOException; +import java.io.InputStream; + +import com.alibaba.fastjson.JSON; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.Test; + +public class TestIssue2898 { + @Test + public void testDeserialzeComplexGenericType() throws Exception { + String s = "{\"props\": {\"test\": [{\"foo\": \"bar\"}]}}"; + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("DataClassPropsGeneric"); + Object d = JSON.parseObject(s, clazz); + System.out.println(d); + Assert.assertNotNull(d); + } + + public static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException { + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( + "kotlin/DataClassPropsGeneric.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("DataClassPropsGeneric", bytes, 0, bytes.length); + } + } + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue2951/TestIssue2951.java b/src/test/java/com/alibaba/fastjson/deserializer/issue2951/TestIssue2951.java new file mode 100644 index 0000000000..28fd7c44ce --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue2951/TestIssue2951.java @@ -0,0 +1,49 @@ +package com.alibaba.fastjson.deserializer.issue2951; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class TestIssue2951 { + @Test + public void test() { + String data = "{\"field1\": null, \"field2\": null, \"field3\": \"1\", \"field4\": null}"; + + Model model; + + model = JSON.parseObject(data, Model.class); + + Assert.assertEquals(model.field1, 0); + Assert.assertEquals(model.field2, 0F, 0); + Assert.assertEquals(model.field3, "1"); + Assert.assertNull(model.field4); + + String data1 = "{\"field1\": null, \"field2\": null, \"field3\": \"1\", \"field4\": \"null\"}"; + model = JSON.parseObject(data1, Model.class); + Assert.assertEquals(model.field1, 0); + Assert.assertEquals(model.field2, 0F, 0); + Assert.assertEquals(model.field3, "1"); + + List actualField4 = new ArrayList(); + actualField4.add("null"); + Assert.assertEquals(model.field4, actualField4); + } + + public static class Model { + public final int field1; + public final float field2; + public final String field3; + public final List field4; + + public Model(int field1, float field2, String field3, List field4) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + } + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue3050/TestIssue3050.java b/src/test/java/com/alibaba/fastjson/deserializer/issue3050/TestIssue3050.java new file mode 100644 index 0000000000..797060292c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue3050/TestIssue3050.java @@ -0,0 +1,27 @@ +package com.alibaba.fastjson.deserializer.issue3050; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.deserializer.issue3050.beans.Person; +import com.alibaba.fastjson.parser.Feature; +import org.junit.Assert; +import org.junit.Test; + +/** + * https://github.com/alibaba/fastjson/issues/3050 + * + * @author yangy + * @since 2020年05月03日 + */ +public class TestIssue3050 { + + @Test + public void testIssue3050() { + String jsonStr = "{\"name\":5, \"address\":\"beijing\", \"id\":\"100\", \"age\":10}"; + Person person = JSON.parseObject(jsonStr, Person.class, Feature.InitStringFieldAsEmpty); + Assert.assertEquals("5", person.getName()); + Assert.assertEquals("beijing", person.getAddress()); + Assert.assertEquals("100", person.getId()); + Assert.assertEquals(10, person.getAge()); + } + +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue3050/beans/Person.java b/src/test/java/com/alibaba/fastjson/deserializer/issue3050/beans/Person.java new file mode 100644 index 0000000000..d00e74c781 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue3050/beans/Person.java @@ -0,0 +1,56 @@ +package com.alibaba.fastjson.deserializer.issue3050.beans; + +/** + * issue3050 + * + * @author yangy + * @since 2020年05月03日 + */ +public class Person { + private String name; + private String address; + private String id; + private int age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return "Person{" + + "name='" + name + '\'' + + ", address='" + address + '\'' + + ", id='" + id + '\'' + + ", age=" + age + + '}'; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue3248/TestIssue3248.kt b/src/test/java/com/alibaba/fastjson/deserializer/issue3248/TestIssue3248.kt new file mode 100644 index 0000000000..45310045af --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue3248/TestIssue3248.kt @@ -0,0 +1,33 @@ +package com.alibaba.fastjson.deserializer.issue3248 + +import com.alibaba.fastjson.JSON +import com.alibaba.fastjson.annotation.JSONField +import org.junit.Assert +import org.junit.Test + +/** + * https://github.com/alibaba/fastjson/issues/3248 + * @author 佐井 + * @since 2020-06-10 09:19 + */ +class TestIssue3248 { + + @JSONField(name = "namex") + var name = "" + + var isTest: Boolean = false + + @Test + fun test() { + + val test = TestIssue3248().also { + it.name = "my name" + it.isTest = true + } + val raw = JSON.toJSONString(test) + val parsed = JSON.parseObject(raw, TestIssue3248::class.java) + Assert.assertEquals(test.name, parsed.name) + Assert.assertEquals(test.isTest, parsed.isTest) + + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issue3804/TestIssue3804.java b/src/test/java/com/alibaba/fastjson/deserializer/issue3804/TestIssue3804.java new file mode 100644 index 0000000000..31de37dd91 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issue3804/TestIssue3804.java @@ -0,0 +1,17 @@ +package com.alibaba.fastjson.deserializer.issue3804; +import com.alibaba.fastjson.JSONValidator; +import org.junit.Test; + +public class TestIssue3804 { + @Test + public void testIssue3804() { + //String textResponse="{\"error\":false,\"code\":0}"; + String textResponse="{\"error\":false,\"code"; + JSONValidator validator = JSONValidator.from(textResponse); + if (validator.validate() && validator.getType() == JSONValidator.Type.Object) { + System.out.println("Yes, it is Object"); + } else { + System.out.println("No, it is not Object"); + } + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3671/TestIssue3671.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3671/TestIssue3671.java new file mode 100644 index 0000000000..e686202100 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3671/TestIssue3671.java @@ -0,0 +1,32 @@ +package com.alibaba.fastjson.deserializer.issues3671; + +import com.alibaba.fastjson.JSONValidator; +import org.junit.Assert; +import org.junit.Test; + +/** + * https://github.com/alibaba/fastjson/issues/3671 + * + * @author ryc + * @date 2021/03/12 15:40 + */ +public class TestIssue3671 { + + @Test + public void testIssue3671() { + String json = "[{\n" + + " \"filters\": [],\n" + + " \"id\": \"baidu_route2\",\n" + + " \"order\": 0,\n" + + " \"predicates\": [{\n" + + " \"args\": {\n" + + " \"pattern\": \"/baidu/**\"\n" + + " },\n" + + " \"name\": \"Path\"\n" + + " }],\n" + + " \"uri\": \"https://www.baidu.com\"\n" + + "}]\n "; + Assert.assertTrue(JSONValidator.from(json).validate()); + } + +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/TestIssues3796.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/TestIssues3796.java new file mode 100644 index 0000000000..db31c2366c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/TestIssues3796.java @@ -0,0 +1,18 @@ +package com.alibaba.fastjson.deserializer.issues3796; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.deserializer.issues3796.bean.LargeJavaBean; +import org.junit.Test; + +/** + * @author kurisu9az + * @description 修复issues3796 + * @date 2021/6/2 18:48 + **/ +public class TestIssues3796 { + + @Test + public void testIssues3796() { + JSON.parseObject("{}", LargeJavaBean.class); + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject.java new file mode 100644 index 0000000000..af419a66b8 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject.java @@ -0,0 +1,44 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + +public class CommonObject { + + private int a; + + private int b; + + + private int c; + + public CommonObject() { + } + + public CommonObject(int a, int b) { + this.a = a; + this.b = b; + } + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject2.java new file mode 100644 index 0000000000..6a0cd9a230 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject2.java @@ -0,0 +1,25 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + +public class CommonObject2 { + + private int a; + + private long b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject3.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject3.java new file mode 100644 index 0000000000..8b33661155 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/CommonObject3.java @@ -0,0 +1,34 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class CommonObject3 { + + private long a; + + private long b; + + private int c; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/LargeJavaBean.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/LargeJavaBean.java new file mode 100644 index 0000000000..04913f9b01 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/LargeJavaBean.java @@ -0,0 +1,1431 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.List; + +public class LargeJavaBean { + public static final String testName = "testName"; + + @JSONField(name = "_id") + private long id; + + private String a = "null"; + + + private String b = "null"; + + private String c = "null"; + + private int d = -1; + + private String e = "null"; + + private String f = "null"; + + private String g = "null"; + + + @JSONField(serialize = false) + private ObjectA h = new ObjectA(); + + private int i; + + private int j; + + + private String k; + + private String l; + + + private ObjectB m = new ObjectB(); + + + private int n; + + + private String o; + + + private int p; + + + private long q; + + + private long r; + + private long s; + + + private long t; + + private long u; + + private long v; + + + private int w = 0; + + private int x = 0; + + private boolean y = false; + + private List z; + + + private List a1; + + + private List b1; + + + private List c1; + + + private List d1; + + + @JSONField(serialize = false) + private List e1; + + + private long f1; + + + private long g1; + + + private List h1; + + + + private List j1; + + + private ObjectI k1; + + private List l1; + + private List m1; + + + private ObjectL n1; + + private List o1; + + + private ObjectN p1; + + + private int q1; + + + private long r1; + + + private long[] s1; + + @JSONField(serialize = false) + private ObjectO t1; + + @JSONField(serialize = false) + private ObjectP u1; + + + private List v1; + + + private List w1; + + private List x1; + + private List y1; + + private List z1; + + + private ObjectT a2 = new ObjectT(); + + private List b2; + + private ObjectV c2 = new ObjectV(); + + private List d2; + + + private List e2; + + + private ObjectX f2; + + + private ObjectY g2; + + + private ObjectZ h2; + + + private int i2 = 0; + + + private ObjectA1 j2; + + + private List k2; + + + private ObjectB1 l2; + + + private List m2; + + + private int n2; + + + private ObjectD1 o2; + + + private int p2; + + + long q2; + + + long r2; + + + int s2; + + + int t2; + + + int u2; + + + int v2; + + + int w2; + + + private List x2; + + + private List y2; + + ObjectF1 z2 = new ObjectF1(); + + private List a3; + + + private List b3; + + private List c3; + + private ObjectH1 d3; + + + private List e3; + + + private ObjectI1 f3; + + + private ObjectJ1 g3; + + + private ObjectK1 h3; + + + ObjectL1 i3 = new ObjectL1(); + + + private ObjectM1 j3; + + private ObjectN1 k3; + + + private List l3; + + + private List m3; + + + private ObjectP1 n3; + + + private List o3; + + + private ObjectR1 p3; + + + private ObjectS1 q3; + + + private List r3; + + + private List s3; + + + private ObjectV1 t3; + + + private List u3; + + + private int v3; + + + private ObjectW1 w3; + + + private List x3; + + private List y3; + + private List z3; + + private int a4; + + private List b4; + + + private ObjectZ1 c4; + + + private List d4; + + + private ObjectB2 e4; + + + private List f4; + + private List g4 ; + + + private List h4; + + + private ObjectF2 i4; + + + private ObjectG2 j4; + + private ObjectH2 k4; + + private ObjectI2 l4; + + private int m4; + + private ObjectJ2 n4; + + private List o4; + private int p4; + private int q4; + private List r4; + + + private List s4; + + + private int t4; + private boolean u4 = false; + + private List v4; + + + private int w4; + + + private ObjectM2 x4; + + + private ObjectM2 y4; + + + private List z4; + + + private List a5; + + + private boolean[] b5; + + + private ObjectO2 c5; + + public static String getTestName() { + return testName; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getA() { + return a; + } + + public void setA(String a) { + this.a = a; + } + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public String getE() { + return e; + } + + public void setE(String e) { + this.e = e; + } + + public String getF() { + return f; + } + + public void setF(String f) { + this.f = f; + } + + public String getG() { + return g; + } + + public void setG(String g) { + this.g = g; + } + + public ObjectA getH() { + return h; + } + + public void setH(ObjectA h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public String getK() { + return k; + } + + public void setK(String k) { + this.k = k; + } + + public String getL() { + return l; + } + + public void setL(String l) { + this.l = l; + } + + public ObjectB getM() { + return m; + } + + public void setM(ObjectB m) { + this.m = m; + } + + public int getN() { + return n; + } + + public void setN(int n) { + this.n = n; + } + + public String getO() { + return o; + } + + public void setO(String o) { + this.o = o; + } + + public int getP() { + return p; + } + + public void setP(int p) { + this.p = p; + } + + public long getQ() { + return q; + } + + public void setQ(long q) { + this.q = q; + } + + public long getR() { + return r; + } + + public void setR(long r) { + this.r = r; + } + + public long getS() { + return s; + } + + public void setS(long s) { + this.s = s; + } + + public long getT() { + return t; + } + + public void setT(long t) { + this.t = t; + } + + public long getU() { + return u; + } + + public void setU(long u) { + this.u = u; + } + + public long getV() { + return v; + } + + public void setV(long v) { + this.v = v; + } + + public int getW() { + return w; + } + + public void setW(int w) { + this.w = w; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public boolean isY() { + return y; + } + + public void setY(boolean y) { + this.y = y; + } + + public List getZ() { + return z; + } + + public void setZ(List z) { + this.z = z; + } + + public List getA1() { + return a1; + } + + public void setA1(List a1) { + this.a1 = a1; + } + + public List getB1() { + return b1; + } + + public void setB1(List b1) { + this.b1 = b1; + } + + public List getC1() { + return c1; + } + + public void setC1(List c1) { + this.c1 = c1; + } + + public List getD1() { + return d1; + } + + public void setD1(List d1) { + this.d1 = d1; + } + + public List getE1() { + return e1; + } + + public void setE1(List e1) { + this.e1 = e1; + } + + public long getF1() { + return f1; + } + + public void setF1(long f1) { + this.f1 = f1; + } + + public long getG1() { + return g1; + } + + public void setG1(long g1) { + this.g1 = g1; + } + + public List getH1() { + return h1; + } + + public void setH1(List h1) { + this.h1 = h1; + } + + public List getJ1() { + return j1; + } + + public void setJ1(List j1) { + this.j1 = j1; + } + + public ObjectI getK1() { + return k1; + } + + public void setK1(ObjectI k1) { + this.k1 = k1; + } + + public List getL1() { + return l1; + } + + public void setL1(List l1) { + this.l1 = l1; + } + + public List getM1() { + return m1; + } + + public void setM1(List m1) { + this.m1 = m1; + } + + public ObjectL getN1() { + return n1; + } + + public void setN1(ObjectL n1) { + this.n1 = n1; + } + + public List getO1() { + return o1; + } + + public void setO1(List o1) { + this.o1 = o1; + } + + public ObjectN getP1() { + return p1; + } + + public void setP1(ObjectN p1) { + this.p1 = p1; + } + + public int getQ1() { + return q1; + } + + public void setQ1(int q1) { + this.q1 = q1; + } + + public long getR1() { + return r1; + } + + public void setR1(long r1) { + this.r1 = r1; + } + + public long[] getS1() { + return s1; + } + + public void setS1(long[] s1) { + this.s1 = s1; + } + + public ObjectO getT1() { + return t1; + } + + public void setT1(ObjectO t1) { + this.t1 = t1; + } + + public ObjectP getU1() { + return u1; + } + + public void setU1(ObjectP u1) { + this.u1 = u1; + } + + public List getV1() { + return v1; + } + + public void setV1(List v1) { + this.v1 = v1; + } + + public List getW1() { + return w1; + } + + public void setW1(List w1) { + this.w1 = w1; + } + + public List getX1() { + return x1; + } + + public void setX1(List x1) { + this.x1 = x1; + } + + public List getY1() { + return y1; + } + + public void setY1(List y1) { + this.y1 = y1; + } + + public List getZ1() { + return z1; + } + + public void setZ1(List z1) { + this.z1 = z1; + } + + public ObjectT getA2() { + return a2; + } + + public void setA2(ObjectT a2) { + this.a2 = a2; + } + + public List getB2() { + return b2; + } + + public void setB2(List b2) { + this.b2 = b2; + } + + public ObjectV getC2() { + return c2; + } + + public void setC2(ObjectV c2) { + this.c2 = c2; + } + + public List getD2() { + return d2; + } + + public void setD2(List d2) { + this.d2 = d2; + } + + public List getE2() { + return e2; + } + + public void setE2(List e2) { + this.e2 = e2; + } + + public ObjectX getF2() { + return f2; + } + + public void setF2(ObjectX f2) { + this.f2 = f2; + } + + public ObjectY getG2() { + return g2; + } + + public void setG2(ObjectY g2) { + this.g2 = g2; + } + + public ObjectZ getH2() { + return h2; + } + + public void setH2(ObjectZ h2) { + this.h2 = h2; + } + + public int getI2() { + return i2; + } + + public void setI2(int i2) { + this.i2 = i2; + } + + public ObjectA1 getJ2() { + return j2; + } + + public void setJ2(ObjectA1 j2) { + this.j2 = j2; + } + + public List getK2() { + return k2; + } + + public void setK2(List k2) { + this.k2 = k2; + } + + public ObjectB1 getL2() { + return l2; + } + + public void setL2(ObjectB1 l2) { + this.l2 = l2; + } + + public List getM2() { + return m2; + } + + public void setM2(List m2) { + this.m2 = m2; + } + + public int getN2() { + return n2; + } + + public void setN2(int n2) { + this.n2 = n2; + } + + public ObjectD1 getO2() { + return o2; + } + + public void setO2(ObjectD1 o2) { + this.o2 = o2; + } + + public int getP2() { + return p2; + } + + public void setP2(int p2) { + this.p2 = p2; + } + + public long getQ2() { + return q2; + } + + public void setQ2(long q2) { + this.q2 = q2; + } + + public long getR2() { + return r2; + } + + public void setR2(long r2) { + this.r2 = r2; + } + + public int getS2() { + return s2; + } + + public void setS2(int s2) { + this.s2 = s2; + } + + public int getT2() { + return t2; + } + + public void setT2(int t2) { + this.t2 = t2; + } + + public int getU2() { + return u2; + } + + public void setU2(int u2) { + this.u2 = u2; + } + + public int getV2() { + return v2; + } + + public void setV2(int v2) { + this.v2 = v2; + } + + public int getW2() { + return w2; + } + + public void setW2(int w2) { + this.w2 = w2; + } + + public List getX2() { + return x2; + } + + public void setX2(List x2) { + this.x2 = x2; + } + + public List getY2() { + return y2; + } + + public void setY2(List y2) { + this.y2 = y2; + } + + public ObjectF1 getZ2() { + return z2; + } + + public void setZ2(ObjectF1 z2) { + this.z2 = z2; + } + + public List getA3() { + return a3; + } + + public void setA3(List a3) { + this.a3 = a3; + } + + public List getB3() { + return b3; + } + + public void setB3(List b3) { + this.b3 = b3; + } + + public List getC3() { + return c3; + } + + public void setC3(List c3) { + this.c3 = c3; + } + + public ObjectH1 getD3() { + return d3; + } + + public void setD3(ObjectH1 d3) { + this.d3 = d3; + } + + public List getE3() { + return e3; + } + + public void setE3(List e3) { + this.e3 = e3; + } + + public ObjectI1 getF3() { + return f3; + } + + public void setF3(ObjectI1 f3) { + this.f3 = f3; + } + + public ObjectJ1 getG3() { + return g3; + } + + public void setG3(ObjectJ1 g3) { + this.g3 = g3; + } + + public ObjectK1 getH3() { + return h3; + } + + public void setH3(ObjectK1 h3) { + this.h3 = h3; + } + + public ObjectL1 getI3() { + return i3; + } + + public void setI3(ObjectL1 i3) { + this.i3 = i3; + } + + public ObjectM1 getJ3() { + return j3; + } + + public void setJ3(ObjectM1 j3) { + this.j3 = j3; + } + + public ObjectN1 getK3() { + return k3; + } + + public void setK3(ObjectN1 k3) { + this.k3 = k3; + } + + public List getL3() { + return l3; + } + + public void setL3(List l3) { + this.l3 = l3; + } + + public List getM3() { + return m3; + } + + public void setM3(List m3) { + this.m3 = m3; + } + + public ObjectP1 getN3() { + return n3; + } + + public void setN3(ObjectP1 n3) { + this.n3 = n3; + } + + public List getO3() { + return o3; + } + + public void setO3(List o3) { + this.o3 = o3; + } + + public ObjectR1 getP3() { + return p3; + } + + public void setP3(ObjectR1 p3) { + this.p3 = p3; + } + + public ObjectS1 getQ3() { + return q3; + } + + public void setQ3(ObjectS1 q3) { + this.q3 = q3; + } + + public List getR3() { + return r3; + } + + public void setR3(List r3) { + this.r3 = r3; + } + + public List getS3() { + return s3; + } + + public void setS3(List s3) { + this.s3 = s3; + } + + public ObjectV1 getT3() { + return t3; + } + + public void setT3(ObjectV1 t3) { + this.t3 = t3; + } + + public List getU3() { + return u3; + } + + public void setU3(List u3) { + this.u3 = u3; + } + + public int getV3() { + return v3; + } + + public void setV3(int v3) { + this.v3 = v3; + } + + public ObjectW1 getW3() { + return w3; + } + + public void setW3(ObjectW1 w3) { + this.w3 = w3; + } + + public List getX3() { + return x3; + } + + public void setX3(List x3) { + this.x3 = x3; + } + + public List getY3() { + return y3; + } + + public void setY3(List y3) { + this.y3 = y3; + } + + public List getZ3() { + return z3; + } + + public void setZ3(List z3) { + this.z3 = z3; + } + + public int getA4() { + return a4; + } + + public void setA4(int a4) { + this.a4 = a4; + } + + public List getB4() { + return b4; + } + + public void setB4(List b4) { + this.b4 = b4; + } + + public ObjectZ1 getC4() { + return c4; + } + + public void setC4(ObjectZ1 c4) { + this.c4 = c4; + } + + public List getD4() { + return d4; + } + + public void setD4(List d4) { + this.d4 = d4; + } + + public ObjectB2 getE4() { + return e4; + } + + public void setE4(ObjectB2 e4) { + this.e4 = e4; + } + + public List getF4() { + return f4; + } + + public void setF4(List f4) { + this.f4 = f4; + } + + public List getG4() { + return g4; + } + + public void setG4(List g4) { + this.g4 = g4; + } + + public List getH4() { + return h4; + } + + public void setH4(List h4) { + this.h4 = h4; + } + + public ObjectF2 getI4() { + return i4; + } + + public void setI4(ObjectF2 i4) { + this.i4 = i4; + } + + public ObjectG2 getJ4() { + return j4; + } + + public void setJ4(ObjectG2 j4) { + this.j4 = j4; + } + + public ObjectH2 getK4() { + return k4; + } + + public void setK4(ObjectH2 k4) { + this.k4 = k4; + } + + public ObjectI2 getL4() { + return l4; + } + + public void setL4(ObjectI2 l4) { + this.l4 = l4; + } + + public int getM4() { + return m4; + } + + public void setM4(int m4) { + this.m4 = m4; + } + + public ObjectJ2 getN4() { + return n4; + } + + public void setN4(ObjectJ2 n4) { + this.n4 = n4; + } + + public List getO4() { + return o4; + } + + public void setO4(List o4) { + this.o4 = o4; + } + + public int getP4() { + return p4; + } + + public void setP4(int p4) { + this.p4 = p4; + } + + public int getQ4() { + return q4; + } + + public void setQ4(int q4) { + this.q4 = q4; + } + + public List getR4() { + return r4; + } + + public void setR4(List r4) { + this.r4 = r4; + } + + public List getS4() { + return s4; + } + + public void setS4(List s4) { + this.s4 = s4; + } + + public int getT4() { + return t4; + } + + public void setT4(int t4) { + this.t4 = t4; + } + + public boolean isU4() { + return u4; + } + + public void setU4(boolean u4) { + this.u4 = u4; + } + + public List getV4() { + return v4; + } + + public void setV4(List v4) { + this.v4 = v4; + } + + public int getW4() { + return w4; + } + + public void setW4(int w4) { + this.w4 = w4; + } + + public ObjectM2 getX4() { + return x4; + } + + public void setX4(ObjectM2 x4) { + this.x4 = x4; + } + + public ObjectM2 getY4() { + return y4; + } + + public void setY4(ObjectM2 y4) { + this.y4 = y4; + } + + public List getZ4() { + return z4; + } + + public void setZ4(List z4) { + this.z4 = z4; + } + + public List getA5() { + return a5; + } + + public void setA5(List a5) { + this.a5 = a5; + } + + public boolean[] getB5() { + return b5; + } + + public void setB5(boolean[] b5) { + this.b5 = b5; + } + + public ObjectO2 getC5() { + return c5; + } + + public void setC5(ObjectO2 c5) { + this.c5 = c5; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA.java new file mode 100644 index 0000000000..3e458ff82b --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA.java @@ -0,0 +1,270 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +public class ObjectA { + + private static final String NULL = "NULL"; + + private String a = NULL; + + private String b = NULL; + + private String c = NULL; + + private String d = NULL; + + + + private String e = NULL; + + + + private int f; + + + + private int g; + + + + private float h; + + + + private String i = NULL; + + + + private int j; + + + + private String k = NULL; + + + + private String l = NULL; + + + + private String m = NULL; + + + + private int n = 1; + + + + private String o = NULL; + + + + private String p = NULL; + + + + private int q; + + + + private int r; + + + + private String s = "NULL"; + + + + + private String t = "NULL"; + + + + private String u = "NULL"; + + + + private String v = "NULL"; + + + public static String getNULL() { + return NULL; + } + + public String getA() { + return a; + } + + public void setA(String a) { + this.a = a; + } + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public String getD() { + return d; + } + + public void setD(String d) { + this.d = d; + } + + public String getE() { + return e; + } + + public void setE(String e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public float getH() { + return h; + } + + public void setH(float h) { + this.h = h; + } + + public String getI() { + return i; + } + + public void setI(String i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public String getK() { + return k; + } + + public void setK(String k) { + this.k = k; + } + + public String getL() { + return l; + } + + public void setL(String l) { + this.l = l; + } + + public String getM() { + return m; + } + + public void setM(String m) { + this.m = m; + } + + public int getN() { + return n; + } + + public void setN(int n) { + this.n = n; + } + + public String getO() { + return o; + } + + public void setO(String o) { + this.o = o; + } + + public String getP() { + return p; + } + + public void setP(String p) { + this.p = p; + } + + public int getQ() { + return q; + } + + public void setQ(int q) { + this.q = q; + } + + public int getR() { + return r; + } + + public void setR(int r) { + this.r = r; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } + + public String getT() { + return t; + } + + public void setT(String t) { + this.t = t; + } + + public String getU() { + return u; + } + + public void setU(String u) { + this.u = u; + } + + public String getV() { + return v; + } + + public void setV(String v) { + this.v = v; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA1.java new file mode 100644 index 0000000000..b1b45e9624 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA1.java @@ -0,0 +1,61 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + + +public class ObjectA1 { + + private List a; + + private CommonObject b; + + + + private CommonObject c; + + + private List d; + + + private boolean e = true; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public CommonObject getB() { + return b; + } + + public void setB(CommonObject b) { + this.b = b; + } + + public CommonObject getC() { + return c; + } + + public void setC(CommonObject c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } + + public boolean isE() { + return e; + } + + public void setE(boolean e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA2.java new file mode 100644 index 0000000000..59cc967880 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectA2.java @@ -0,0 +1,47 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + +public class ObjectA2 { + + private int a; + + private int b; + + + private long c; + + + private int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB.java new file mode 100644 index 0000000000..698980d5eb --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB.java @@ -0,0 +1,183 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class ObjectB { + + private long a; + + private long b; + + private long c; + + private long d; + + private long e; + + private long f; + + private long g; + + + private long h; + + + private long i; + + + private long j; + + + private long k = 0; + + + private long l = 0; + + private long m = 0; + + + private long n; + + + private long o; + + + private long p; + + + private int q; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public long getD() { + return d; + } + + public void setD(long d) { + this.d = d; + } + + public long getE() { + return e; + } + + public void setE(long e) { + this.e = e; + } + + public long getF() { + return f; + } + + public void setF(long f) { + this.f = f; + } + + public long getG() { + return g; + } + + public void setG(long g) { + this.g = g; + } + + public long getH() { + return h; + } + + public void setH(long h) { + this.h = h; + } + + public long getI() { + return i; + } + + public void setI(long i) { + this.i = i; + } + + public long getJ() { + return j; + } + + public void setJ(long j) { + this.j = j; + } + + public long getK() { + return k; + } + + public void setK(long k) { + this.k = k; + } + + public long getL() { + return l; + } + + public void setL(long l) { + this.l = l; + } + + public long getM() { + return m; + } + + public void setM(long m) { + this.m = m; + } + + public long getN() { + return n; + } + + public void setN(long n) { + this.n = n; + } + + public long getO() { + return o; + } + + public void setO(long o) { + this.o = o; + } + + public long getP() { + return p; + } + + public void setP(long p) { + this.p = p; + } + + public int getQ() { + return q; + } + + public void setQ(int q) { + this.q = q; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB1.java new file mode 100644 index 0000000000..bd77100b22 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB1.java @@ -0,0 +1,27 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + +public class ObjectB1 { + + List a; + + + private int b; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB2.java new file mode 100644 index 0000000000..e2eedc93ef --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectB2.java @@ -0,0 +1,56 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.List; + +public class ObjectB2 { + + + + @JSONField(serialize = false) + private int a = 1; + + + + @JSONField(serialize = false) + private long b; + + + private List c; + + + private List d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC.java new file mode 100644 index 0000000000..0ccd9dc8e5 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC.java @@ -0,0 +1,44 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class ObjectC { + + private int a; + + private int b = 0; + + private long c; + + private int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC1.java new file mode 100644 index 0000000000..0298926602 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC1.java @@ -0,0 +1,55 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class ObjectC1 { + + private int a; + + + private int b; + + private int c; + + private int d; + + private int e; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC2.java new file mode 100644 index 0000000000..2dece499ef --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectC2.java @@ -0,0 +1,23 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class ObjectC2 { + private int a; + + private boolean b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD.java new file mode 100644 index 0000000000..fba0cfdf65 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD.java @@ -0,0 +1,178 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + +public class ObjectD { + + private int a; + + + private int b; + + + private int c; + + + private int d; + + + private boolean e; + + + private List f; + + + private int g; + + + private int h; + + + private long i; + + + private long j; + + + private int k; + + + private int l; + + + private ObjectD_B m; + + private long n; + + private long o; + + private long dieFans; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public boolean isE() { + return e; + } + + public void setE(boolean e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public long getI() { + return i; + } + + public void setI(long i) { + this.i = i; + } + + public long getJ() { + return j; + } + + public void setJ(long j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public ObjectD_B getM() { + return m; + } + + public void setM(ObjectD_B m) { + this.m = m; + } + + public long getN() { + return n; + } + + public void setN(long n) { + this.n = n; + } + + public long getO() { + return o; + } + + public void setO(long o) { + this.o = o; + } + + public long getDieFans() { + return dieFans; + } + + public void setDieFans(long dieFans) { + this.dieFans = dieFans; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD1.java new file mode 100644 index 0000000000..99da04bfe0 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD1.java @@ -0,0 +1,36 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + +public class ObjectD1 { + + private int a; + + private int b; + + private List c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD1_A.java new file mode 100644 index 0000000000..5d6cef4004 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD1_A.java @@ -0,0 +1,69 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + +public class ObjectD1_A { + + private int a; + + private List b; + + private int c; + + + private CommonObject d; + + + private int e; + + + private int f; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public CommonObject getD() { + return d; + } + + public void setD(CommonObject d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD2.java new file mode 100644 index 0000000000..5c939a972b --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD2.java @@ -0,0 +1,151 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + + +public class ObjectD2 { + + private int a; + + private int b; + + private int c; + + private List d; + private List e; + private List f; + private List g; + private List h; + + private List i; + + private int j; + + private int k; + + private int l; + private boolean m; + private boolean n; + + private int o; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public boolean isM() { + return m; + } + + public void setM(boolean m) { + this.m = m; + } + + public boolean isN() { + return n; + } + + public void setN(boolean n) { + this.n = n; + } + + public int getO() { + return o; + } + + public void setO(int o) { + this.o = o; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD_A.java new file mode 100644 index 0000000000..89169eb86d --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD_A.java @@ -0,0 +1,29 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectD_A { + + private int a; + + + private boolean b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD_B.java new file mode 100644 index 0000000000..35ed5dc618 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectD_B.java @@ -0,0 +1,49 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectD_B { + + private int a; + + private int b; + + private int c; + + private int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE.java new file mode 100644 index 0000000000..66fffaf786 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE.java @@ -0,0 +1,112 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectE { + + private int a; + + + private int b; + + + private int c; + + + private int d; + + + private int e; + + + private boolean f; + + + private long g; + + + private int h; + + + private int i; + + + public int j() { + return -1; + } + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public boolean isF() { + return f; + } + + public void setF(boolean f) { + this.f = f; + } + + public long getG() { + return g; + } + + public void setG(long g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE1.java new file mode 100644 index 0000000000..b25310e3b0 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE1.java @@ -0,0 +1,110 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + + +public class ObjectE1 { + + private int a; + + private int b; + + private int c; + + private int d; + + private long e; + + private long f; + + private boolean g; + + private int h; + + private int i; + + private int j; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public long getE() { + return e; + } + + public void setE(long e) { + this.e = e; + } + + public long getF() { + return f; + } + + public void setF(long f) { + this.f = f; + } + + public boolean isG() { + return g; + } + + public void setG(boolean g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE2.java new file mode 100644 index 0000000000..7b3f4ea8d0 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectE2.java @@ -0,0 +1,29 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectE2 { + + private int a; + + + private boolean b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF.java new file mode 100644 index 0000000000..fc0583730c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF.java @@ -0,0 +1,177 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + + +public class ObjectF { + + protected long a; + + + protected int b; + + + protected int c; + + + protected long d; + + + protected long e; + + + protected String f = ""; + + + protected long g; + + protected String h = ""; + + protected String i = ""; + + protected int j; + + protected long k; + + + protected int l; + + + private int m; + + protected List n; + + + protected List o; + + + protected List p; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public long getD() { + return d; + } + + public void setD(long d) { + this.d = d; + } + + public long getE() { + return e; + } + + public void setE(long e) { + this.e = e; + } + + public String getF() { + return f; + } + + public void setF(String f) { + this.f = f; + } + + public long getG() { + return g; + } + + public void setG(long g) { + this.g = g; + } + + public String getH() { + return h; + } + + public void setH(String h) { + this.h = h; + } + + public String getI() { + return i; + } + + public void setI(String i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public long getK() { + return k; + } + + public void setK(long k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public int getM() { + return m; + } + + public void setM(int m) { + this.m = m; + } + + public List getN() { + return n; + } + + public void setN(List n) { + this.n = n; + } + + public List getO() { + return o; + } + + public void setO(List o) { + this.o = o; + } + + public List getP() { + return p; + } + + public void setP(List p) { + this.p = p; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF1.java new file mode 100644 index 0000000000..1432ce5da9 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF1.java @@ -0,0 +1,187 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.List; + + +public class ObjectF1 { + + long a = -1; + int b = 0; + + long c = 0; + + int d = 0; + + int e = 0; + + + @JSONField(serialize = false) + String f = ""; + + transient boolean g; + + long h; + + + long i; + + + int j; + + int k; + + int l; + + + int m; + + + int n; + + + List o; + + + int p; + + + int q; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public String getF() { + return f; + } + + public void setF(String f) { + this.f = f; + } + + public boolean isG() { + return g; + } + + public void setG(boolean g) { + this.g = g; + } + + public long getH() { + return h; + } + + public void setH(long h) { + this.h = h; + } + + public long getI() { + return i; + } + + public void setI(long i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public int getM() { + return m; + } + + public void setM(int m) { + this.m = m; + } + + public int getN() { + return n; + } + + public void setN(int n) { + this.n = n; + } + + public List getO() { + return o; + } + + public void setO(List o) { + this.o = o; + } + + public int getP() { + return p; + } + + public void setP(int p) { + this.p = p; + } + + public int getQ() { + return q; + } + + public void setQ(int q) { + this.q = q; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF2.java new file mode 100644 index 0000000000..80c6d8288a --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectF2.java @@ -0,0 +1,51 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + + +public class ObjectF2 { + + + private int a; + + + private int b; + + + private List c; + + + private boolean d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG.java new file mode 100644 index 0000000000..5f7c17c3ad --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG.java @@ -0,0 +1,43 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import com.alibaba.fastjson.annotation.JSONField; + + +public class ObjectG { + + public static final String tesdt = "tesdt"; + + + @JSONField(name = "a") + private long a; + + + private long b; + + + private ObjectF c; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public ObjectF getC() { + return c; + } + + public void setC(ObjectF c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG1.java new file mode 100644 index 0000000000..83193acc7b --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG1.java @@ -0,0 +1,12 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectG1 { + private int a; + private int b; + private int c; +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG2.java new file mode 100644 index 0000000000..41e2bde0ea --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectG2.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + +import java.util.List; + + +public class ObjectG2 { + + private int a; + + + private boolean b = true; + + + private List c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH.java new file mode 100644 index 0000000000..6e252ecb74 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH.java @@ -0,0 +1,192 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectH { + + private int a; + + + private long b; + + private int c; + + private int d; + + private int e; + + private int f; + + private int g; + + private int h; + + private int i; + + private int j; + + + + private int k; + + + + private int l; + + + + private List m; + + + + private int n; + + + private int o; + + + private boolean p = false; + + + private boolean q = false; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public List getM() { + return m; + } + + public void setM(List m) { + this.m = m; + } + + public int getN() { + return n; + } + + public void setN(int n) { + this.n = n; + } + + public int getO() { + return o; + } + + public void setO(int o) { + this.o = o; + } + + public boolean isP() { + return p; + } + + public void setP(boolean p) { + this.p = p; + } + + public boolean isQ() { + return q; + } + + public void setQ(boolean q) { + this.q = q; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH1.java new file mode 100644 index 0000000000..f78fd8bb0c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH1.java @@ -0,0 +1,163 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectH1 { + + + private List a; + + + private List b; + + private List c; + + private List d; + + private int e; + + + private int f; + + private int g; + + private int h; + + private int i; + + private int j; + + private int k; + + private int l; + + private List m; + + private List n; + + private List o; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public List getM() { + return m; + } + + public void setM(List m) { + this.m = m; + } + + public List getN() { + return n; + } + + public void setN(List n) { + this.n = n; + } + + public List getO() { + return o; + } + + public void setO(List o) { + this.o = o; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH2.java new file mode 100644 index 0000000000..adcc3be7ae --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH2.java @@ -0,0 +1,63 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + + +public class ObjectH2 { + + + private boolean a; + + + + private int b; + + + private int c; + + + private boolean d; + + + private List e; + + public boolean isA() { + return a; + } + + public void setA(boolean a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH_A.java new file mode 100644 index 0000000000..050055f034 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectH_A.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectH_A { + + private int a; + + private int b; + + private int c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI.java new file mode 100644 index 0000000000..63df7227f0 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI.java @@ -0,0 +1,133 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectI { + + private String a; + + private int b; + + private long c; + + private int d; + + private int e; + + private int f; + + + private int g; + + + private List h; + + + private List i; + + + private int j; + + private int k; + private int l; + + public String getA() { + return a; + } + + public void setA(String a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI1.java new file mode 100644 index 0000000000..5c2b8ba118 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI1.java @@ -0,0 +1,52 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectI1 { + + private int a = 0; + + private long b = 0; + + + private int c = 0; + + + private List d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI2.java new file mode 100644 index 0000000000..5d132ef20e --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI2.java @@ -0,0 +1,38 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import java.util.List; + + +public class ObjectI2 { + private int a; + + + private List b; + + + private boolean c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public boolean isC() { + return c; + } + + public void setC(boolean c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI_A.java new file mode 100644 index 0000000000..3575d9ea71 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectI_A.java @@ -0,0 +1,32 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + +public class ObjectI_A { + int a; + int b; + boolean c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public boolean isC() { + return c; + } + + public void setC(boolean c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ.java new file mode 100644 index 0000000000..f25fe25bad --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ.java @@ -0,0 +1,333 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectJ { + + private long a; + + private int b; + + + private int c; + + private int d; + + + private int e; + + + + private int f; + + + private int g; + + + private int h; + + private List i; + + private int j; + + private int k; + + + private int l; + + private int m; + + private List n; + + + private List o; + + private int p; + + private int q; + + private int r; + + private int s; + + private int t; + + private int x; + + + private int y; + + private int z; + + private int a1; + + + private int b1; + + private List c1; + + private List d1; + + private List e1; + + + private int f1; + + + private int g1; + + + boolean h1; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public int getM() { + return m; + } + + public void setM(int m) { + this.m = m; + } + + public List getN() { + return n; + } + + public void setN(List n) { + this.n = n; + } + + public List getO() { + return o; + } + + public void setO(List o) { + this.o = o; + } + + public int getP() { + return p; + } + + public void setP(int p) { + this.p = p; + } + + public int getQ() { + return q; + } + + public void setQ(int q) { + this.q = q; + } + + public int getR() { + return r; + } + + public void setR(int r) { + this.r = r; + } + + public int getS() { + return s; + } + + public void setS(int s) { + this.s = s; + } + + public int getT() { + return t; + } + + public void setT(int t) { + this.t = t; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public int getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + + public int getA1() { + return a1; + } + + public void setA1(int a1) { + this.a1 = a1; + } + + public int getB1() { + return b1; + } + + public void setB1(int b1) { + this.b1 = b1; + } + + public List getC1() { + return c1; + } + + public void setC1(List c1) { + this.c1 = c1; + } + + public List getD1() { + return d1; + } + + public void setD1(List d1) { + this.d1 = d1; + } + + public List getE1() { + return e1; + } + + public void setE1(List e1) { + this.e1 = e1; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int getG1() { + return g1; + } + + public void setG1(int g1) { + this.g1 = g1; + } + + public boolean isH1() { + return h1; + } + + public void setH1(boolean h1) { + this.h1 = h1; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1.java new file mode 100644 index 0000000000..b0d791f99f --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1.java @@ -0,0 +1,100 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectJ1 { + + private int a = 0; + + private int b = 0; + + private List c; + + private int d = 0; + + private List e; + + private List f; + + private List g; + + private List h; + + private boolean i = false; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public boolean isI() { + return i; + } + + public void setI(boolean i) { + this.i = i; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1_A.java new file mode 100644 index 0000000000..dd168c240f --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1_A.java @@ -0,0 +1,80 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectJ1_A { + + private int a = 0; + + private int b = 0; + + private int c = 0; + + private int d = 0; + + private int e = 0; + + private List f; + + private List g; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1_C.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1_C.java new file mode 100644 index 0000000000..dccd6f3adf --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ1_C.java @@ -0,0 +1,59 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectJ1_C { + + private int a = 0; + + private int b = 0; + + private int c = 0; + + private int d = 0; + + private boolean e = false; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public boolean isE() { + return e; + } + + public void setE(boolean e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ2.java new file mode 100644 index 0000000000..23433a0192 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ2.java @@ -0,0 +1,31 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectJ2 { + + + private boolean a; + + + private boolean b; + + public boolean isA() { + return a; + } + + public void setA(boolean a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_A.java new file mode 100644 index 0000000000..49befa18d9 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_A.java @@ -0,0 +1,153 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectJ_A { + + + private long a; + + + private int b; + + + private int c; + + + private int d; + + + private int e; + + + private int f; + + + private int g; + + + private int h; + + + private int i; + + + private List j; + + + private List k; + + + private List l; + + + private List m; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public List getJ() { + return j; + } + + public void setJ(List j) { + this.j = j; + } + + public List getK() { + return k; + } + + public void setK(List k) { + this.k = k; + } + + public List getL() { + return l; + } + + public void setL(List l) { + this.l = l; + } + + public List getM() { + return m; + } + + public void setM(List m) { + this.m = m; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_B.java new file mode 100644 index 0000000000..7b20be121f --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_B.java @@ -0,0 +1,100 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + + +public class ObjectJ_B { + + private long a; + + private int b; + + private long c; + + private int d; + + private int e; + + private int f; + + private int g; + + private int h; + + private int i; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_C.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_C.java new file mode 100644 index 0000000000..72aad74572 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectJ_C.java @@ -0,0 +1,29 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectJ_C { + + private int a; + + + private int b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK.java new file mode 100644 index 0000000000..bb704cbbc6 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK.java @@ -0,0 +1,48 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectK { + + private int a; + + private int b = 0; + + private int c = 0; + + private int d = 0; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1.java new file mode 100644 index 0000000000..199570aefb --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1.java @@ -0,0 +1,106 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectK1 { + + + private int a = 0; + + private boolean b = false; + + private int c = 0; + + private int d = 0; + + private int e = 0; + + private List f; + + private List g; + + + + + + + private int h = 0; + + private List i; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1_A.java new file mode 100644 index 0000000000..28e82ced95 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1_A.java @@ -0,0 +1,49 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectK1_A { + + private int a = 0; + + private int b = 0; + + private int c = 0; + + private int d = 0; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1_C.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1_C.java new file mode 100644 index 0000000000..f0621d982e --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK1_C.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectK1_C { + + private int a = 0; + + private int b = 0; + + private boolean c = false; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public boolean isC() { + return c; + } + + public void setC(boolean c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK2.java new file mode 100644 index 0000000000..7386cf24ad --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK2.java @@ -0,0 +1,27 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectK2 { + private int a; + private List b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK2_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK2_A.java new file mode 100644 index 0000000000..c59c401683 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectK2_A.java @@ -0,0 +1,54 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectK2_A { + private int a; + private int b; + private int c; + private int d; + private int e; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL.java new file mode 100644 index 0000000000..e69894c48a --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL.java @@ -0,0 +1,41 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectL { + + private List a; + + + private List b; + + + private List c; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL1.java new file mode 100644 index 0000000000..f0027732c9 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL1.java @@ -0,0 +1,113 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.HashMap; +import java.util.List; + + +public class ObjectL1 { + + + List a; + + int b; + + int c; + + int d; + + + long e; + + long f; + + List g; + + List h; + + HashMap> i; + + boolean j = false; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public long getE() { + return e; + } + + public void setE(long e) { + this.e = e; + } + + public long getF() { + return f; + } + + public void setF(long f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public HashMap> getI() { + return i; + } + + public void setI(HashMap> i) { + this.i = i; + } + + public boolean isJ() { + return j; + } + + public void setJ(boolean j) { + this.j = j; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL1_A.java new file mode 100644 index 0000000000..7744522cc5 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL1_A.java @@ -0,0 +1,48 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectL1_A { + + protected int a; + + protected int b; + + protected int c; + + protected int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2.java new file mode 100644 index 0000000000..9aefec1909 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2.java @@ -0,0 +1,49 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectL2 { + + int a; + + ObjectL2_A b; + + List c ; + + int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public ObjectL2_A getB() { + return b; + } + + public void setB(ObjectL2_A b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_A.java new file mode 100644 index 0000000000..0cc4026169 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_A.java @@ -0,0 +1,48 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectL2_A { + int a = 1; + + int b = 2; + + int c = 4; + + int d = 5; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_B.java new file mode 100644 index 0000000000..05e318d33e --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_B.java @@ -0,0 +1,28 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectL2_B { + + int a; + + int b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_C.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_C.java new file mode 100644 index 0000000000..005d52f74d --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL2_C.java @@ -0,0 +1,26 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectL2_C { + int a; + int b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL_A.java new file mode 100644 index 0000000000..f8d5604d0d --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL_A.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectL_A { + + private int a; + + + private int b; + + + private long c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL_B.java new file mode 100644 index 0000000000..d906709ded --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectL_B.java @@ -0,0 +1,51 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectL_B { + + + private int a; + + private List b; + + private List c; + + private long d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public long getD() { + return d; + } + + public void setD(long d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM.java new file mode 100644 index 0000000000..853c8ca5d8 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM.java @@ -0,0 +1,114 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectM { + + private int a; + + private int b; + + private String c = ""; + + private long d; + + private int e; + + private int f; + + + private List g; + + + private List h; + + + private ObjectM_B i; + + + private long j; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public long getD() { + return d; + } + + public void setD(long d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public ObjectM_B getI() { + return i; + } + + public void setI(ObjectM_B i) { + this.i = i; + } + + public long getJ() { + return j; + } + + public void setJ(long j) { + this.j = j; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1.java new file mode 100644 index 0000000000..c5d4e0cedb --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1.java @@ -0,0 +1,219 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectM1 { + + + private int a; + + + private int b; + + + private int c; + + + private int d; + + + private List e; + + + private List f; + + + private int g; + + private int h; + + private int i; + + private int j; + + private int k; + + private boolean l; + + private int m; + + private int n; + + + private int o; + + private int p; + + private boolean q; + + private CommonObject r; + + private int s; + + + private long t; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public boolean isL() { + return l; + } + + public void setL(boolean l) { + this.l = l; + } + + public int getM() { + return m; + } + + public void setM(int m) { + this.m = m; + } + + public int getN() { + return n; + } + + public void setN(int n) { + this.n = n; + } + + public int getO() { + return o; + } + + public void setO(int o) { + this.o = o; + } + + public int getP() { + return p; + } + + public void setP(int p) { + this.p = p; + } + + public boolean isQ() { + return q; + } + + public void setQ(boolean q) { + this.q = q; + } + + public CommonObject getR() { + return r; + } + + public void setR(CommonObject r) { + this.r = r; + } + + public int getS() { + return s; + } + + public void setS(int s) { + this.s = s; + } + + public long getT() { + return t; + } + + public void setT(long t) { + this.t = t; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_A.java new file mode 100644 index 0000000000..8da35707d4 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_A.java @@ -0,0 +1,28 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectM1_A { + + private int a; + + private int b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_B.java new file mode 100644 index 0000000000..61ef1e08da --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_B.java @@ -0,0 +1,137 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectM1_B { + + private long a; + + private String b; + + private String c; + + private int d; + + + private long e; + + private int f; + + + private int g; + + + private List h; + + + private List i; + + + private int j; + + + private int k; + + + private boolean l; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public long getE() { + return e; + } + + public void setE(long e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public boolean isL() { + return l; + } + + public void setL(boolean l) { + this.l = l; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_C.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_C.java new file mode 100644 index 0000000000..71c7b3ffa9 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM1_C.java @@ -0,0 +1,175 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectM1_C { + + private int a; + + + private int b; + + + private int c; + + + + private int d; + + + private int e; + + + private int f; + + + private int g; + + + private List h; + + + private List i; + + + private int j; + + + private int k; + + + private int l; + + + private int m; + + + private int n; + + + private int o; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public int getM() { + return m; + } + + public void setM(int m) { + this.m = m; + } + + public int getN() { + return n; + } + + public void setN(int n) { + this.n = n; + } + + public int getO() { + return o; + } + + public void setO(int o) { + this.o = o; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM2.java new file mode 100644 index 0000000000..12d2084615 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM2.java @@ -0,0 +1,65 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectM2 { + + + private long a; + + + private int b; + + + private boolean c; + + + private int d; + + + private List e; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public boolean isC() { + return c; + } + + public void setC(boolean c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM2_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM2_A.java new file mode 100644 index 0000000000..01357abbea --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM2_A.java @@ -0,0 +1,19 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectM2_A { + + + private int a; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM_A.java new file mode 100644 index 0000000000..9a5bf14d54 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM_A.java @@ -0,0 +1,38 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectM_A { + + private int a; + + private int b; + + private long c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM_B.java new file mode 100644 index 0000000000..778db6555f --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectM_B.java @@ -0,0 +1,59 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectM_B { + + private int a; + + private int b; + + private int c; + + private long d; + + private List e; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public long getD() { + return d; + } + + public void setD(long d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN.java new file mode 100644 index 0000000000..663f0514c8 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN.java @@ -0,0 +1,142 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +import java.util.List; + + +public class ObjectN { + + private List a; + + private List b; + + + private List c; + + + private List d; + + + private List e; + + + private List f; + + + private List g; + + + private List h; + + + private List i; + + + private List j; + + + private List k; + + + private List l; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public List getJ() { + return j; + } + + public void setJ(List j) { + this.j = j; + } + + public List getK() { + return k; + } + + public void setK(List k) { + this.k = k; + } + + public List getL() { + return l; + } + + public void setL(List l) { + this.l = l; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN1.java new file mode 100644 index 0000000000..d6d67bcbd8 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN1.java @@ -0,0 +1,52 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class ObjectN1 { + + private int a; + private int b; + + private boolean c; + private boolean d; + + private int e; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public boolean isC() { + return c; + } + + public void setC(boolean c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN2.java new file mode 100644 index 0000000000..0900d3a0c9 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectN2.java @@ -0,0 +1,51 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectN2 { + + private int a; + + private int b; + + + private long c; + + + private int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO.java new file mode 100644 index 0000000000..4d7b26378b --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO.java @@ -0,0 +1,31 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.List; + + +public class ObjectO { + public static final String tstN = "tstN"; + + @JSONField(name = "a") + private long a; + + private List b; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO1.java new file mode 100644 index 0000000000..321125b683 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO1.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + +import java.io.Serializable; +import java.util.List; + + +public class ObjectO1 implements Serializable { + + int a; + + int b; + + List c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO1_A.java new file mode 100644 index 0000000000..71498941bb --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO1_A.java @@ -0,0 +1,49 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.io.Serializable; + + +public class ObjectO1_A implements Serializable { + + int a; + + int b; + + int c; + + int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO2.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO2.java new file mode 100644 index 0000000000..7590241732 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO2.java @@ -0,0 +1,36 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class ObjectO2 { + + private int a; + + + private boolean b = true; + + + private int c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO_A.java new file mode 100644 index 0000000000..af8378de31 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectO_A.java @@ -0,0 +1,69 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectO_A { + + private int a; + + private int b; + + private int c; + + private int d; + + private int e; + + private int f; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP.java new file mode 100644 index 0000000000..24364ce8f7 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP.java @@ -0,0 +1,36 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.List; + + +public class ObjectP { + + public static final String tsnst = "tsnst"; + + @JSONField(name = "a") + private long a; + + private List b; + + public static String getTsnst() { + return tsnst; + } + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1.java new file mode 100644 index 0000000000..937c9a35ce --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1.java @@ -0,0 +1,110 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectP1 { + + private int a; + + private int b; + + private int c; + + private List d; + + private int e = 0; + + private int f = 0; + + private List g; + + private List h; + + private List i; + + private boolean j = true; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public boolean isJ() { + return j; + } + + public void setJ(boolean j) { + this.j = j; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1_A.java new file mode 100644 index 0000000000..4647304956 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1_A.java @@ -0,0 +1,69 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectP1_A { + + private int a = 0; + + private int b = 0; + + private int c = 0; + + private boolean d = false; + + private int e = 0; + + private int f = 0; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1_B.java new file mode 100644 index 0000000000..6a2cad02fb --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP1_B.java @@ -0,0 +1,89 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectP1_B { + + private long a = 0; + + private int b = 0; + + private int c = 0; + + private int d = 0; + + private int e = 0; + + private int f = 0; + + private long g = 0; + + private boolean h = true; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public long getG() { + return g; + } + + public void setG(long g) { + this.g = g; + } + + public boolean isH() { + return h; + } + + public void setH(boolean h) { + this.h = h; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP_A.java new file mode 100644 index 0000000000..c55da772b7 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectP_A.java @@ -0,0 +1,69 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectP_A { + + private int a; + + private int b; + + private int c; + + private boolean d; + + private boolean e; + + private boolean f; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public boolean isE() { + return e; + } + + public void setE(boolean e) { + this.e = e; + } + + public boolean isF() { + return f; + } + + public void setF(boolean f) { + this.f = f; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ.java new file mode 100644 index 0000000000..0dabeecd04 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ.java @@ -0,0 +1,50 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectQ { + + private int a; + + private int b; + + private boolean c = false; + + private List d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public boolean isC() { + return c; + } + + public void setC(boolean c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1.java new file mode 100644 index 0000000000..50616c125d --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1.java @@ -0,0 +1,201 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectQ1 { + + private int a; + + + private int b; + + private long c; + + private int d; + + private int e; + + private int f; + + private int g; + + private int h; + + + private int i; + + private int j; + + private int k; + + private int l; + + private int m; + + private List n; + + private int o; + + private long p; + + private int q; + + private int r; + + private int s; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public int getK() { + return k; + } + + public void setK(int k) { + this.k = k; + } + + public int getL() { + return l; + } + + public void setL(int l) { + this.l = l; + } + + public int getM() { + return m; + } + + public void setM(int m) { + this.m = m; + } + + public List getN() { + return n; + } + + public void setN(List n) { + this.n = n; + } + + public int getO() { + return o; + } + + public void setO(int o) { + this.o = o; + } + + public long getP() { + return p; + } + + public void setP(long p) { + this.p = p; + } + + public int getQ() { + return q; + } + + public void setQ(int q) { + this.q = q; + } + + public int getR() { + return r; + } + + public void setR(int r) { + this.r = r; + } + + public int getS() { + return s; + } + + public void setS(int s) { + this.s = s; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1_A.java new file mode 100644 index 0000000000..faeddf8ac1 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1_A.java @@ -0,0 +1,64 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectQ1_A { + + private int a; + + + private List b; + + + private int c; + + + private boolean d; + + + private boolean e; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public boolean isE() { + return e; + } + + public void setE(boolean e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1_B.java new file mode 100644 index 0000000000..b3cc3be7fe --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectQ1_B.java @@ -0,0 +1,30 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectQ1_B { + + + private int a; + + + private boolean b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectR.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectR.java new file mode 100644 index 0000000000..e4f4fcda30 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectR.java @@ -0,0 +1,63 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectR { + private int a; + private int b; + private int c; + private int d; + private List e; + private int f; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectR1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectR1.java new file mode 100644 index 0000000000..2f6e0e4ea1 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectR1.java @@ -0,0 +1,129 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectR1 { + + private List a; + + + private int b; + + + private List c; + + private boolean d; + + + private boolean e; + + + private int f; + + + private int g; + + + private boolean h; + + + private long i; + + + private long j; + + + private List k; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public boolean isE() { + return e; + } + + public void setE(boolean e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public boolean isH() { + return h; + } + + public void setH(boolean h) { + this.h = h; + } + + public long getI() { + return i; + } + + public void setI(long i) { + this.i = i; + } + + public long getJ() { + return j; + } + + public void setJ(long j) { + this.j = j; + } + + public List getK() { + return k; + } + + public void setK(List k) { + this.k = k; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS.java new file mode 100644 index 0000000000..336e548828 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS.java @@ -0,0 +1,29 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectS { + + private int a; + + private int b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS1.java new file mode 100644 index 0000000000..057c6e210b --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS1.java @@ -0,0 +1,131 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +import java.util.List; + + +public class ObjectS1 { + + private int a; + + + private int b; + + + private int c = 0; + + + private int d; + + + private int e; + + + private List f; + + + private boolean g = false; + + + private List h; + + + private List i; + + + private List j; + + + private boolean k = true; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public boolean isG() { + return g; + } + + public void setG(boolean g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } + + public List getJ() { + return j; + } + + public void setJ(List j) { + this.j = j; + } + + public boolean isK() { + return k; + } + + public void setK(boolean k) { + this.k = k; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS1_A.java new file mode 100644 index 0000000000..278106b477 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectS1_A.java @@ -0,0 +1,50 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectS1_A { + + private int a; + + private int b; + + private int c; + + + private boolean d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT.java new file mode 100644 index 0000000000..885942b5d1 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT.java @@ -0,0 +1,130 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectT { + + private int a = 0; + + + private int b = 0; + + private int c = 0; + + + private List d; + + + private int e = 0; + + + private int f; + + + private int g; + + + private int h; + + + private int i; + + + private int j; + + + private boolean k = false; + + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } + + public boolean isK() { + return k; + } + + public void setK(boolean k) { + this.k = k; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT1.java new file mode 100644 index 0000000000..fe8af233cf --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT1.java @@ -0,0 +1,100 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectT1 { + + private int a; + + + private int b; + + private int c; + + private int d; + + private int e; + + private int f; + + private int g; + + private int h; + + private long i; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public long getI() { + return i; + } + + public void setI(long i) { + this.i = i; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT_A.java new file mode 100644 index 0000000000..c2d46cff29 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectT_A.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectT_A { + + private int a; + + + private boolean b; + + + private long c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU.java new file mode 100644 index 0000000000..13289cc1d8 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU.java @@ -0,0 +1,81 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectU { + + private int a; + + + private Integer b; + + private int c; + + + private int d; + + private int e; + + + private int f; + + private boolean g; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public Integer getB() { + return b; + } + + public void setB(Integer b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public boolean isG() { + return g; + } + + public void setG(boolean g) { + this.g = g; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1.java new file mode 100644 index 0000000000..9473ee34ab --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1.java @@ -0,0 +1,140 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectU1 { + + private int a; + + private String b = ""; + + private String c = ""; + + private String d = ""; + + private List e; + + private List f; + + private long g; + + private long h; + + private long i; + + private long j; + + private long k; + + private long l; + + private List m; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public String getD() { + return d; + } + + public void setD(String d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public long getG() { + return g; + } + + public void setG(long g) { + this.g = g; + } + + public long getH() { + return h; + } + + public void setH(long h) { + this.h = h; + } + + public long getI() { + return i; + } + + public void setI(long i) { + this.i = i; + } + + public long getJ() { + return j; + } + + public void setJ(long j) { + this.j = j; + } + + public long getK() { + return k; + } + + public void setK(long k) { + this.k = k; + } + + public long getL() { + return l; + } + + public void setL(long l) { + this.l = l; + } + + public List getM() { + return m; + } + + public void setM(List m) { + this.m = m; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_A.java new file mode 100644 index 0000000000..c3d6a38e7c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_A.java @@ -0,0 +1,38 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectU1_A { + + private int a; + + private long b; + + private int c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_B.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_B.java new file mode 100644 index 0000000000..4347c818e0 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_B.java @@ -0,0 +1,59 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectU1_B { + + private int a; + + private long b; + + private List c; + + private boolean d; + + private boolean e; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public boolean isE() { + return e; + } + + public void setE(boolean e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_C.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_C.java new file mode 100644 index 0000000000..8560276ea2 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectU1_C.java @@ -0,0 +1,28 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectU1_C { + + private int a; + + private boolean b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public boolean isB() { + return b; + } + + public void setB(boolean b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV.java new file mode 100644 index 0000000000..b52c5200db --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV.java @@ -0,0 +1,31 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectV { + + private List a; + + + private List b; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV1.java new file mode 100644 index 0000000000..8bcb319158 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV1.java @@ -0,0 +1,50 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectV1 { + + private int a; + + private int b; + + private List c; + + private List d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public List getD() { + return d; + } + + public void setD(List d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV1_A.java new file mode 100644 index 0000000000..8413ada7dc --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV1_A.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectV1_A { + + private int a; + + private List b; + + private boolean c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public List getB() { + return b; + } + + public void setB(List b) { + this.b = b; + } + + public boolean isC() { + return c; + } + + public void setC(boolean c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV_A.java new file mode 100644 index 0000000000..851ae2b4d1 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectV_A.java @@ -0,0 +1,49 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectV_A { + + private int a; + + + private int b; + + private int c; + + private int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectW.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectW.java new file mode 100644 index 0000000000..2019889b53 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectW.java @@ -0,0 +1,72 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectW { + + private long a; + + + private int b; + + private long c; + + + private int d; + + private String e; + + + private long f; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public long getC() { + return c; + } + + public void setC(long c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public String getE() { + return e; + } + + public void setE(String e) { + this.e = e; + } + + public long getF() { + return f; + } + + public void setF(long f) { + this.f = f; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectW1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectW1.java new file mode 100644 index 0000000000..4686fa4234 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectW1.java @@ -0,0 +1,76 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectW1 { + + + private int a; + + + private int b; + + + private List c; + + + private boolean d; + + + private List e; + + + private int f = 0; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public List getE() { + return e; + } + + public void setE(List e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectX.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectX.java new file mode 100644 index 0000000000..30d708d266 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectX.java @@ -0,0 +1,96 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + +import java.util.List; + + +public class ObjectX { + + + private long a = 0; + + private int b; + + + private List c; + + + private int d = 0; + + + private int e; + + + private List f; + + + private List g; + + private List h; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public List getC() { + return c; + } + + public void setC(List c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectX1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectX1.java new file mode 100644 index 0000000000..aa075309a0 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectX1.java @@ -0,0 +1,60 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + + +public class ObjectX1 { + + int a; + + int b; + + String c; + + String d; + + long e; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public String getD() { + return d; + } + + public void setD(String d) { + this.d = d; + } + + public long getE() { + return e; + } + + public void setE(long e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY.java new file mode 100644 index 0000000000..4491cece1e --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY.java @@ -0,0 +1,130 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +import java.util.List; + + +public class ObjectY { + + private List a; + + + private long b; + + + private int c = 0; + + + private boolean d = false; + + + private int e = -1; + + + private int f = 0; + + + private int g = 0; + + + + + private int h; + + private boolean i =false; + + private List j; + + private List k; + + public List getA() { + return a; + } + + public void setA(List a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public boolean isD() { + return d; + } + + public void setD(boolean d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public int getF() { + return f; + } + + public void setF(int f) { + this.f = f; + } + + public int getG() { + return g; + } + + public void setG(int g) { + this.g = g; + } + + public int getH() { + return h; + } + + public void setH(int h) { + this.h = h; + } + + public boolean isI() { + return i; + } + + public void setI(boolean i) { + this.i = i; + } + + public List getJ() { + return j; + } + + public void setJ(List j) { + this.j = j; + } + + public List getK() { + return k; + } + + public void setK(List k) { + this.k = k; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY1.java new file mode 100644 index 0000000000..15de0d37e6 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY1.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectY1 { + + private int a; + + + private int b; + + private int c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY_A.java new file mode 100644 index 0000000000..3ce5195c38 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectY_A.java @@ -0,0 +1,53 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectY_A { + + + private int a = 0; + + + private int b; + + + private int c; + + + private int d; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ.java new file mode 100644 index 0000000000..b0d03e24d6 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ.java @@ -0,0 +1,28 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + +public class ObjectZ { + + private int a; + + private long b; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public long getB() { + return b; + } + + public void setB(long b) { + this.b = b; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ1.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ1.java new file mode 100644 index 0000000000..b2b85d4008 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ1.java @@ -0,0 +1,106 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + +import java.util.List; + + +public class ObjectZ1 { + private int a; + + + private int b; + + + private int c; + + + private int d; + + + private int e; + + + private List f; + + + private List g; + + + private List h; + + + private List i; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public int getE() { + return e; + } + + public void setE(int e) { + this.e = e; + } + + public List getF() { + return f; + } + + public void setF(List f) { + this.f = f; + } + + public List getG() { + return g; + } + + public void setG(List g) { + this.g = g; + } + + public List getH() { + return h; + } + + public void setH(List h) { + this.h = h; + } + + public List getI() { + return i; + } + + public void setI(List i) { + this.i = i; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ1_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ1_A.java new file mode 100644 index 0000000000..3b1f6ba825 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/ObjectZ1_A.java @@ -0,0 +1,41 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + + + + + + +public class ObjectZ1_A { + + private int a; + + + private int b; + + + private int c; + + public int getA() { + return a; + } + + public void setA(int a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public int getC() { + return c; + } + + public void setC(int c) { + this.c = c; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/OjectN_A.java b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/OjectN_A.java new file mode 100644 index 0000000000..d0c964330f --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues3796/bean/OjectN_A.java @@ -0,0 +1,49 @@ +package com.alibaba.fastjson.deserializer.issues3796.bean; + +public class OjectN_A { + private long a; + private String b; + private String c; + private int d; + private String e; + + public long getA() { + return a; + } + + public void setA(long a) { + this.a = a; + } + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public int getD() { + return d; + } + + public void setD(int d) { + this.d = d; + } + + public String getE() { + return e; + } + + public void setE(String e) { + this.e = e; + } +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/issues569/parser/ParserConfigBug569.java b/src/test/java/com/alibaba/fastjson/deserializer/issues569/parser/ParserConfigBug569.java index 6ce58e407d..e56eca69f0 100644 --- a/src/test/java/com/alibaba/fastjson/deserializer/issues569/parser/ParserConfigBug569.java +++ b/src/test/java/com/alibaba/fastjson/deserializer/issues569/parser/ParserConfigBug569.java @@ -53,19 +53,19 @@ public FieldDeserializer createFieldDeserializer(ParserConfig mapping, // } public ObjectDeserializer getDeserializer(Class clazz, Type type) { - com.alibaba.fastjson.util.IdentityHashMap derializers = super.getDeserializers(); - ObjectDeserializer derializer = derializers.get(type); - if (derializer != null) { - return derializer; + com.alibaba.fastjson.util.IdentityHashMap deserializers = super.getDeserializers(); + ObjectDeserializer deserializer = deserializers.get(type); + if (deserializer != null) { + return deserializer; } if (type == null) { type = clazz; } - derializer = derializers.get(type); - if (derializer != null) { - return derializer; + deserializer = deserializers.get(type); + if (deserializer != null) { + return deserializer; } { @@ -79,11 +79,11 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { } if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) { - derializer = derializers.get(clazz); + deserializer = deserializers.get(clazz); } - if (derializer != null) { - return derializer; + if (deserializer != null) { + return deserializer; } String className = clazz.getName(); @@ -99,16 +99,16 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { && AwtCodec.support(clazz)) { if (!awtError) { try { - derializers.put(Class.forName("java.awt.Point"), AwtCodec.instance); - derializers.put(Class.forName("java.awt.Font"), AwtCodec.instance); - derializers.put(Class.forName("java.awt.Rectangle"), AwtCodec.instance); - derializers.put(Class.forName("java.awt.Color"), AwtCodec.instance); + deserializers.put(Class.forName("java.awt.Point"), AwtCodec.instance); + deserializers.put(Class.forName("java.awt.Font"), AwtCodec.instance); + deserializers.put(Class.forName("java.awt.Rectangle"), AwtCodec.instance); + deserializers.put(Class.forName("java.awt.Color"), AwtCodec.instance); } catch (Throwable e) { // skip awtError = true; } - derializer = AwtCodec.instance; + deserializer = AwtCodec.instance; } } @@ -116,28 +116,28 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { try { if (className.startsWith("java.time.")) { - derializers.put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.ZoneId"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.Period"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance); - derializers.put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance); - - derializer = derializers.get(clazz); + deserializers.put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.ZoneId"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.Period"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance); + deserializers.put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance); + + deserializer = deserializers.get(clazz); } else if (className.startsWith("java.util.Optional")) { - derializers.put(Class.forName("java.util.Optional"), OptionalCodec.instance); - derializers.put(Class.forName("java.util.OptionalDouble"), OptionalCodec.instance); - derializers.put(Class.forName("java.util.OptionalInt"), OptionalCodec.instance); - derializers.put(Class.forName("java.util.OptionalLong"), OptionalCodec.instance); + deserializers.put(Class.forName("java.util.Optional"), OptionalCodec.instance); + deserializers.put(Class.forName("java.util.OptionalDouble"), OptionalCodec.instance); + deserializers.put(Class.forName("java.util.OptionalInt"), OptionalCodec.instance); + deserializers.put(Class.forName("java.util.OptionalLong"), OptionalCodec.instance); - derializer = derializers.get(clazz); + deserializer = deserializers.get(clazz); } } catch (Throwable e) { // skip @@ -146,7 +146,7 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { } if (className.equals("java.nio.file.Path")) { - derializers.put(clazz, MiscCodec.instance); + deserializers.put(clazz, MiscCodec.instance); } final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); @@ -154,41 +154,41 @@ public ObjectDeserializer getDeserializer(Class clazz, Type type) { for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader)) { for (Type forType : autowired.getAutowiredFor()) { - derializers.put(forType, autowired); + deserializers.put(forType, autowired); } } } catch (Exception ex) { // skip } - if (derializer == null) { - derializer = derializers.get(type); + if (deserializer == null) { + deserializer = deserializers.get(type); } - if (derializer != null) { - return derializer; + if (deserializer != null) { + return deserializer; } if (clazz.isEnum()) { - derializer = new EnumDeserializer(clazz); + deserializer = new EnumDeserializer(clazz); } else if (clazz.isArray()) { - derializer = ObjectArrayCodec.instance; + deserializer = ObjectArrayCodec.instance; } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class || clazz == ArrayList.class) { - derializer = CollectionCodec.instance; + deserializer = CollectionCodec.instance; } else if (Collection.class.isAssignableFrom(clazz)) { - derializer = CollectionCodec.instance; + deserializer = CollectionCodec.instance; } else if (Map.class.isAssignableFrom(clazz)) { - derializer = MapDeserializer.instance; + deserializer = MapDeserializer.instance; } else if (Throwable.class.isAssignableFrom(clazz)) { - derializer = new ThrowableDeserializer(this, clazz); + deserializer = new ThrowableDeserializer(this, clazz); } else { - derializer = createJavaBeanDeserializer(clazz, type); + deserializer = createJavaBeanDeserializer(clazz, type); } - putDeserializer(type, derializer); + putDeserializer(type, deserializer); - return derializer; + return deserializer; } } diff --git a/src/test/java/com/alibaba/fastjson/deserializer/javabean/ConvertDO.java b/src/test/java/com/alibaba/fastjson/deserializer/javabean/ConvertDO.java new file mode 100644 index 0000000000..5f72842987 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/javabean/ConvertDO.java @@ -0,0 +1,59 @@ +package com.alibaba.fastjson.deserializer.javabean; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * @author ylyue + * @since 2021/3/23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConvertDO implements Serializable { + + private static final long serialVersionUID = 3987648902475498726L; + + private int inta; + private Integer intb; + private long longa; + private Long longb; + private boolean booleana; + private Boolean booleanb; + private Character character; + private String str; + + private String[] arrayStr; + private long[] arrayLong; + private List list; + + private Date date; +// private DateTime dateTime; +// private LocalDate localDate; +// private LocalTime localTime; +// private LocalDateTime localDateTime; + + private Map map; + private JSONObject jsonObject; + private JSONArray jsonArray; + private List jsonObjectList; + + private Map strToMap; + private JSONObject strToJsonObject; + private JSONArray strToJsonArray; + private List strToJsonObjectList; + + private ConvertEnum convertEnum; + +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/javabean/ConvertEnum.java b/src/test/java/com/alibaba/fastjson/deserializer/javabean/ConvertEnum.java new file mode 100644 index 0000000000..a4187bc14c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/javabean/ConvertEnum.java @@ -0,0 +1,12 @@ +package com.alibaba.fastjson.deserializer.javabean; + +/** + * @author ylyue + * @since 2021/3/24 + */ + +public enum ConvertEnum { + + A_A, BB_B; + +} diff --git a/src/test/java/com/alibaba/fastjson/deserializer/javabean/JavaBeanConvertTest.java b/src/test/java/com/alibaba/fastjson/deserializer/javabean/JavaBeanConvertTest.java new file mode 100644 index 0000000000..adfbea0243 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/deserializer/javabean/JavaBeanConvertTest.java @@ -0,0 +1,77 @@ +package com.alibaba.fastjson.deserializer.javabean; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.util.TypeUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * JavaBean类型转换器测试 + * + * @author ylyue + * @since 2021/3/23 + */ +public class JavaBeanConvertTest { + + @Test + public void javaBeanDeserializerTest() { + Map map = new HashMap(); + map.put("key1", "value1"); + map.put("key2", "value2"); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("aaa", 1); + jsonObject.put("bbb", 2); + jsonObject.put("ccc", "11111"); + + JSONArray jsonArray = new JSONArray(); + jsonArray.add(jsonObject); + + JSONObject paramJson = new JSONObject(); + // JSON - JSON + paramJson.put("map", map); + paramJson.put("jsonObject", jsonObject); + paramJson.put("jsonArray", jsonArray); + paramJson.put("jsonObjectList", jsonArray); + // JSONString - JSON + paramJson.put("strToMap", map); + paramJson.put("strToJsonObject", jsonObject.toJSONString()); + paramJson.put("strToJsonArray", jsonArray.toJSONString()); + paramJson.put("strToJsonObjectList", jsonArray.toJSONString()); + + // 基本类型 + paramJson.put("character", "c"); + paramJson.put("str", "STR"); + paramJson.put("inta", "1"); + paramJson.put("intb", "2"); + paramJson.put("longa", "3"); + paramJson.put("longb", 888l); + paramJson.put("booleana", "1"); + paramJson.put("booleanb", true); + + // 数组 + paramJson.put("arrayStr", new String[]{"aaaa", "bbbbb", "cccc"}); + paramJson.put("arrayLong", new Long[]{1L, 2L, 3L}); + paramJson.put("list", new String[]{"aaaa", "bbbbb", "cccc"}); + + // 时间类型 + paramJson.put("date", "2021-03-23"); + paramJson.put("dateTime", "2021-03-24"); + paramJson.put("localDate", "2021-03-24"); + paramJson.put("localTime", "16:03:24"); + paramJson.put("localDateTime", "2021-03-24 16:03:24"); + + // 其它 + paramJson.put("convertEnum", "A_A"); + + ConvertDO convertDO = TypeUtils.castToJavaBean(paramJson, ConvertDO.class, ParserConfig.getGlobalInstance()); + Assert.assertNotNull(convertDO); +// System.out.println(convertDO); + } + +} diff --git a/src/test/java/com/alibaba/fastjson/jsonpath/issue3493/TestIssue3493.java b/src/test/java/com/alibaba/fastjson/jsonpath/issue3493/TestIssue3493.java new file mode 100644 index 0000000000..a20d0e4050 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/jsonpath/issue3493/TestIssue3493.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.jsonpath.issue3493; + + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONPath; +import org.junit.Assert; +import org.junit.Test; + + +/** + * @author wangzn + * @since 2020/10/27 10:27 + */ +public class TestIssue3493 { + + @Test + public void testIssue3493(){ + String json = "{\n" + + "\"result\": [\n" + + "{\n" + + "\"puid\": \"21025318\"\n" + + "},\n" + + "{\n" + + "\"puid\": \"21482682\"\n" + + "},\n" + + "{\n" + + "\"puid\": \"21025345\"\n" + + "}\n" + + "],\n" + + "\"state\": 0\n" + + "}"; + Object list = JSONPath.extract(json, "$.result[0,2].puid"); + JSONArray jsonArray = JSON.parseArray(list.toString()); + Assert.assertEquals(jsonArray.size(), 2); + Assert.assertEquals(jsonArray.get(0), "21025318"); + Assert.assertEquals(jsonArray.get(1), "21025345"); + } +} + diff --git a/src/test/java/com/alibaba/fastjson/jsonpath/issue3607/TestIssue3607.java b/src/test/java/com/alibaba/fastjson/jsonpath/issue3607/TestIssue3607.java new file mode 100644 index 0000000000..d0c769981c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/jsonpath/issue3607/TestIssue3607.java @@ -0,0 +1,189 @@ +package com.alibaba.fastjson.jsonpath.issue3607; + + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +/** + * @author : ganyu + *

@Date: 2021/1/6 10:57

+ */ +public class TestIssue3607 { + + @Test + public void testIssue3607() { + TestData testData = JSON.parseObject("{\n" + + " \"data\": {\n" + + " \"dataRows\": [\n" + + " {\n" + + " \"dataFields\": [\n" + + " {\n" + + " \"id\": 1332,\n" + + " \"name\": \"gmtRegular\",\n" + + " \"status\": \"success\",\n" + + " \"valueType\": \"DATE\"\n" + + " },\n" + + " {\n" + + " \"id\": 302,\n" + + " \"name\": \"deptNo\",\n" + + " \"status\": \"success\",\n" + + " \"value\": \"C3736\",\n" + + " \"valueType\": \"STRING\"\n" + + " },\n" + + " {\n" + + " \"id\": 143,\n" + + " \"name\": \"gmtOrigRegular\",\n" + + " \"status\": \"success\",\n" + + " \"value\": 1621126800000,\n" + + " \"valueType\": \"DATE\"\n" + + " },\n" + + " {\n" + + " \"id\": 135,\n" + + " \"name\": \"name\",\n" + + " \"status\": \"success\",\n" + + " \"value\": \"\",\n" + + " \"valueType\": \"STRING\"\n" + + " },\n" + + " {\n" + + " \"id\": 133,\n" + + " \"name\": \"workNo\",\n" + + " \"status\": \"success\",\n" + + " \"value\": \"29*6\",\n" + + " \"valueType\": \"STRING\"\n" + + " },\n" + + " {\n" + + " \"id\": 140,\n" + + " \"name\": \"gmtEntry\",\n" + + " \"status\": \"success\",\n" + + " \"value\": 1605456000000,\n" + + " \"valueType\": \"DATE\"\n" + + " },\n" + + " {\n" + + " \"id\": 199,\n" + + " \"name\": \"superWorkNo\",\n" + + " \"status\": \"success\",\n" + + " \"value\": \"240397\",\n" + + " \"valueType\": \"STRING\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"status\": \"success\",\n" + + " \"success\": true\n" + + "}", TestData.class); + + + List evalResult = (List) JSONPath.eval(testData, "$.data.dataRows[*].dataFields[*].value", false); + Assert.assertEquals(testData.getData().getDataRows().get(0).getDataFields().size(), evalResult.size()); + + } + + static class TestData { + private Test1 data; + private String status; + private Boolean success; + + public Test1 getData() { + return data; + } + + public void setData(Test1 data) { + this.data = data; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + } + + static class Test1 { + List dataRows; + + public List getDataRows() { + return dataRows; + } + + public void setDataRows(List dataRows) { + this.dataRows = dataRows; + } + } + + static class Test2 { + List dataFields; + + public List getDataFields() { + return dataFields; + } + + public void setDataFields(List dataFields) { + this.dataFields = dataFields; + } + } + + static class Test3 { + private Integer id; + private String name; + private String status; + private String value; + private String valueType; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueType() { + return valueType; + } + + public void setValueType(String valueType) { + this.valueType = valueType; + } + } + +} + diff --git a/src/test/java/com/alibaba/fastjson/parser/JSONScannerTest.java b/src/test/java/com/alibaba/fastjson/parser/JSONScannerTest.java new file mode 100644 index 0000000000..53b460d9bf --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/parser/JSONScannerTest.java @@ -0,0 +1,1852 @@ +/* + * Copyright 2018 Diffblue Limited + * + * 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. + * + */ + +package com.alibaba.fastjson.parser; + +import com.alibaba.fastjson.parser.JSONScanner; +import com.diffblue.deeptestutils.Reflector; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Calendar; +import java.util.Locale; + + +public class JSONScannerTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + /* testedClasses: JSONScanner */ + + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 82 branch to line 83 + */ + + @Test + public void charArrayCompare1() throws Throwable { + + // Arrange + String src = ""; + int offset = 7; + char[] dest = { '\u0000' }; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("charArrayCompare", Reflector.forName("java.lang.String"), Reflector.forName("int"), Reflector.forName("char []")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, src, offset, dest); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest.This test covers `boolean + * charArrayCompare(String, char [])' block 2 (line 81) + * This test covers `boolean charArrayCompare(String, char [])' block 3 (line + * 82) + * This test covers `boolean charArrayCompare(String, char [])' block 4 (line + * 82) + * This test covers `boolean charArrayCompare(String, char [])' block 5 (line + * 86) + * This test covers `boolean charArrayCompare(String, char [])' block 7 (line + * 86) + * This test covers `boolean charArrayCompare(String, char [])' block 8 (line + * 86) + * This test covers `boolean charArrayCompare(String, char [])' block 10 + * (line 87) + * This test covers `boolean charArrayCompare(String, char [])' block 11 + * (line 87) + * This test covers `boolean charArrayCompare(String, char [])' block 13 + * (line 88) + * + */ + + @Test + public void charArrayCompare3() throws Throwable { + + // Arrange + String src = "!!!!!!!\"&&"; + int offset = 6; + char[] dest = { '\u0000' }; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("charArrayCompare", Reflector.forName("java.lang.String"), Reflector.forName("int"), Reflector.forName("char []")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, src, offset, dest); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 82 branch to line 86 + * + */ + + @Test + public void charArrayCompare4() throws Throwable { + + // Arrange + String src = "!\"&&&&&"; + int offset = 0; + char[] dest = { }; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("charArrayCompare", Reflector.forName("java.lang.String"), Reflector.forName("int"), Reflector.forName("char []")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, src, offset, dest); + + // Assert result + Assert.assertEquals(true, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 719 + * - conditional line 719 branch to line 719 + * - conditional line 719 branch to line 723 + * - conditional line 723 branch to line 724 + * - conditional line 724 branch to line 731 + */ + + @Test + public void checkDate1() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 51; + int d1 = 48; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(true, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 704 + * - conditional line 704 branch to line 704 + * - conditional line 704 branch to line 705 + */ + + @Test + public void checkDate2() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '0'; + char M1 = '\u8031'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 719 + * - conditional line 719 branch to line 720 + * - conditional line 720 branch to line 720 + * - conditional line 720 branch to line 721 + */ + + @Test + public void checkDate3() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 49; + int d1 = 32810; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 719 + * - conditional line 719 branch to line 719 + * - conditional line 719 branch to line 720 + * - conditional line 720 branch to line 720 + * - conditional line 720 branch to line 721 + */ + + @Test + public void checkDate4() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 50; + int d1 = 32810; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 691 + */ + + @Test + public void checkDate5() throws Throwable { + + // Arrange + char y0 = '4'; + char y1 = '\u0000'; + char y2 = '\u0000'; + char y3 = '\u0000'; + char M0 = '\u0000'; + char M1 = '\u0000'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 691 + */ + + @Test + public void checkDate6() throws Throwable { + + // Arrange + char y0 = '\u0000'; + char y1 = '\u0000'; + char y2 = '\u0000'; + char y3 = '\u0000'; + char M0 = '\u0000'; + char M1 = '\u0000'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 704 + * - conditional line 704 branch to line 705 + */ + + @Test + public void checkDate7() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '0'; + char y3 = '0'; + char M0 = '0'; + char M1 = '\u0000'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 694 + */ + + @Test + public void checkDate8() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '\u0011'; + char y2 = '0'; + char y3 = '\u0830'; + char M0 = '1'; + char M1 = '\u0000'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 719 + * - conditional line 719 branch to line 720 + * - conditional line 720 branch to line 720 + * - conditional line 720 branch to line 731 + */ + + @Test + public void checkDate9() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 49; + int d1 = 49; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(true, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 719 + * - conditional line 719 branch to line 719 + * - conditional line 719 branch to line 723 + * - conditional line 723 branch to line 728 + */ + + @Test + public void checkDate10() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 8388658; + int d1 = 32810; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 716 + * - conditional line 716 branch to line 716 + * - conditional line 716 branch to line 731 + */ + + @Test + public void checkDate11() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 48; + int d1 = 49; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(true, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 697 + */ + + @Test + public void checkDate12() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '\u8030'; + char y3 = '\u0830'; + char M0 = '1'; + char M1 = '\u0000'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 716 + * - conditional line 716 branch to line 717 + */ + + @Test + public void checkDate13() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 48; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 715 + * - conditional line 715 branch to line 719 + * - conditional line 719 branch to line 719 + * - conditional line 719 branch to line 723 + * - conditional line 723 branch to line 724 + * - conditional line 724 branch to line 724 + * - conditional line 724 branch to line 725 + */ + + @Test + public void checkDate14() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '0'; + int d0 = 51; + int d1 = -2147483600; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 708 + * - conditional line 708 branch to line 708 + * - conditional line 708 branch to line 709 + */ + + @Test + public void checkDate15() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '1'; + char y3 = '1'; + char M0 = '1'; + char M1 = '\u8031'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 700 + */ + + @Test + public void checkDate16() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '0'; + char y3 = '\u0830'; + char M0 = '1'; + char M1 = '\u0000'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 690 branch to line 690 + * - conditional line 690 branch to line 693 + * - conditional line 693 branch to line 693 + * - conditional line 693 branch to line 696 + * - conditional line 696 branch to line 696 + * - conditional line 696 branch to line 699 + * - conditional line 699 branch to line 699 + * - conditional line 699 branch to line 703 + * - conditional line 703 branch to line 707 + * - conditional line 707 branch to line 712 + */ + + @Test + public void checkDate17() throws Throwable { + + // Arrange + char y0 = '2'; + char y1 = '1'; + char y2 = '0'; + char y3 = '0'; + char M0 = '\u0000'; + char M1 = '\u0000'; + int d0 = 0; + int d1 = 0; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 643 + * - conditional line 643 branch to line 648 + */ + + @Test + public void checkTime1() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '\u0000'; + char h1 = '\u0000'; + char m0 = '\u0000'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 643 + * - conditional line 643 branch to line 644 + * - conditional line 644 branch to line 645 + */ + + @Test + public void checkTime2() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '2'; + char h1 = '\u0000'; + char m0 = '\u0000'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 636 + * - conditional line 636 branch to line 636 + * - conditional line 636 branch to line 637 + */ + + @Test + public void checkTime3() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '0'; + char h1 = '<'; + char m0 = '\u0000'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 636 + * - conditional line 636 branch to line 637 + */ + + @Test + public void checkTime4() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '0'; + char h1 = ' '; + char m0 = '\u0000'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 643 + * - conditional line 643 branch to line 644 + * - conditional line 644 branch to line 644 + * - conditional line 644 branch to line 645 + */ + + @Test + public void checkTime5() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '2'; + char h1 = '5'; + char m0 = '\u0000'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 636 + * - conditional line 636 branch to line 636 + * - conditional line 636 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 652 + * - conditional line 652 branch to line 653 + */ + + @Test + public void checkTime6() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '0'; + char h1 = '9'; + char m0 = '1'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 641 + */ + + @Test + public void checkTime7() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '='; + char m0 = '1'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 652 + * - conditional line 652 branch to line 653 + */ + + @Test + public void checkTime8() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '1'; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 655 + * - conditional line 655 branch to line 660 + */ + + @Test + public void checkTime9() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = ' '; + char m1 = '\u0000'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 652 + * - conditional line 652 branch to line 652 + * - conditional line 652 branch to line 663 + * - conditional line 663 branch to line 663 + * - conditional line 663 branch to line 664 + * - conditional line 664 branch to line 665 + */ + + @Test + public void checkTime10() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '4'; + char m1 = '3'; + char s0 = '1'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 655 + * - conditional line 655 branch to line 656 + * - conditional line 656 branch to line 663 + * - conditional line 663 branch to line 663 + * - conditional line 663 branch to line 664 + * - conditional line 664 branch to line 664 + * - conditional line 664 branch to line 665 + */ + + @Test + public void checkTime11() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '6'; + char m1 = '0'; + char s0 = '1'; + char s1 = '\u0430'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 655 + * - conditional line 655 branch to line 656 + * - conditional line 656 branch to line 663 + * - conditional line 663 branch to line 663 + * - conditional line 663 branch to line 667 + * - conditional line 667 branch to line 668 + * - conditional line 668 branch to line 669 + */ + + @Test + public void checkTime12() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '6'; + char m1 = '0'; + char s0 = '6'; + char s1 = '\u0430'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 655 + * - conditional line 655 branch to line 656 + * - conditional line 656 branch to line 663 + * - conditional line 663 branch to line 663 + * - conditional line 663 branch to line 667 + * - conditional line 667 branch to line 672 + */ + + @Test + public void checkTime13() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '6'; + char m1 = '0'; + char s0 = '>'; + char s1 = '\u0430'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 655 + * - conditional line 655 branch to line 656 + * - conditional line 656 branch to line 663 + * - conditional line 663 branch to line 663 + * - conditional line 663 branch to line 667 + * - conditional line 667 branch to line 668 + * - conditional line 668 branch to line 675 + */ + + @Test + public void checkTime14() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '6'; + char m1 = '0'; + char s0 = '6'; + char s1 = '0'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(true, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 652 + * - conditional line 652 branch to line 652 + * - conditional line 652 branch to line 663 + * - conditional line 663 branch to line 663 + * - conditional line 663 branch to line 664 + * - conditional line 664 branch to line 664 + * - conditional line 664 branch to line 665 + */ + + @Test + public void checkTime15() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '4'; + char m1 = '3'; + char s0 = '1'; + char s1 = '\u0430'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 652 + * - conditional line 652 branch to line 652 + * - conditional line 652 branch to line 653 + */ + + @Test + public void checkTime16() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '4'; + char m1 = ':'; + char s0 = '\u0000'; + char s1 = '\u0000'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 635 branch to line 639 + * - conditional line 639 branch to line 640 + * - conditional line 640 branch to line 640 + * - conditional line 640 branch to line 651 + * - conditional line 651 branch to line 651 + * - conditional line 651 branch to line 655 + * - conditional line 655 branch to line 656 + * - conditional line 656 branch to line 657 + */ + + @Test + public void checkTime17() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", ""); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = ""; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + char h0 = '1'; + char h1 = '9'; + char m0 = '6'; + char m1 = '1'; + char s0 = '1'; + char s1 = '\u0430'; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkTime", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(objectUnderTest, h0, h1, m0, m1, s0, s1); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 2040 branch to line 2040 + */ + + @Test + public void info1() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + Locale locale = ((Locale)Reflector.getInstance("java.util.Locale")); + objectUnderTest.locale = locale; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", "(((("); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 7; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = "!!!!"; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + char[] charArray = { '\u0000' }; + objectUnderTest.sbuf = charArray; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + + // Act + String retval = objectUnderTest.info(); + + // Assert result + Assert.assertEquals("pos 7, json : ((((", retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 736 branch to line 736 + */ + + @Test + public void isEOF1() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", null); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 0; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = null; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u001a'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + + // Act + boolean retval = objectUnderTest.isEOF(); + + // Assert result + Assert.assertEquals(true, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 736 branch to line 736 + */ + + @Test + public void isEOF2() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", null); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 1; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = null; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u0000'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + + // Act + boolean retval = objectUnderTest.isEOF(); + + // Assert result + Assert.assertEquals(false, retval); + + } + + /* + * Test generated by Diffblue Deeptest. + * This test case covers: + * - conditional line 736 branch to line 736 + */ + + @Test + public void isEOF3() throws Throwable { + + // Arrange + JSONScanner objectUnderTest = ((JSONScanner)Reflector.getInstance("com.alibaba.fastjson.parser.JSONScanner")); + objectUnderTest.hasSpecial = false; + objectUnderTest.token = 0; + objectUnderTest.locale = null; + objectUnderTest.np = 0; + objectUnderTest.features = 0; + Reflector.setField(objectUnderTest, "text", null); + objectUnderTest.calendar = null; + objectUnderTest.matchStat = 0; + objectUnderTest.bp = 1; + Reflector.setField(objectUnderTest, "len", 0); + objectUnderTest.stringDefaultValue = null; + objectUnderTest.pos = 0; + objectUnderTest.sp = 0; + objectUnderTest.sbuf = null; + objectUnderTest.ch = '\u001a'; + objectUnderTest.timeZone = null; + objectUnderTest.eofPos = 0; + + // Act + boolean retval = objectUnderTest.isEOF(); + + // Assert result + Assert.assertEquals(false, retval); + + } +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/SerializeWriterTest.java b/src/test/java/com/alibaba/fastjson/serializer/SerializeWriterTest.java index 05fe403343..43530b3f80 100644 --- a/src/test/java/com/alibaba/fastjson/serializer/SerializeWriterTest.java +++ b/src/test/java/com/alibaba/fastjson/serializer/SerializeWriterTest.java @@ -3,6 +3,7 @@ import java.io.ByteArrayOutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; import java.util.logging.Logger; import org.junit.After; @@ -62,12 +63,17 @@ private String makeSpecialChars() { @Test public void testWriteLargeBasicStr() throws UnsupportedEncodingException { + String str = createLargeBasicStr(); + this.doTestWrite(str); + } + + private String createLargeBasicStr() { String tmp = new String(IOUtils.DIGITS); StringBuilder builder = new StringBuilder(); - for (int i = 0; i < 200; i++) { + for (int i = 0; i < 400; i++) { builder.append(tmp); } - this.doTestWrite(builder.toString()); + return builder.toString(); } @Test @@ -80,4 +86,34 @@ public void testWriteLargeSpecialStr() throws UnsupportedEncodingException { } this.doTestWrite(builder.toString()); } + + @Test + public void test_large() throws Exception { + SerializeWriter writer = new SerializeWriter(); + + for (int i = 0; i < 1024 * 1024; ++i) { + writer.write(i); + } + + writer.close(); + } + + @Test + public void testBytesBufLocal() throws Exception { + String str = createLargeBasicStr(); + SerializeWriter writer = new SerializeWriter(); + //写入大于12K的字符串 + writer.writeString(str); + writer.writeString(str); + byte[] bytes = writer.toBytes("UTF-8"); + writer.close(); + + //检查bytesLocal大小,如果缓存成功应该大于等于输出的bytes长度 + Field bytesBufLocalField = SerializeWriter.class.getDeclaredField("bytesBufLocal"); + bytesBufLocalField.setAccessible(true); + ThreadLocal bytesBufLocal = (ThreadLocal) bytesBufLocalField.get(null); + byte[] bytesLocal = bytesBufLocal.get(); + Assert.assertNotNull("bytesLocal is null", bytesLocal); + Assert.assertTrue("bytesLocal is smaller than expected", bytesLocal.length >= bytes.length); + } } diff --git a/src/test/java/com/alibaba/fastjson/serializer/SerializeWriterToBytesTest.java b/src/test/java/com/alibaba/fastjson/serializer/SerializeWriterToBytesTest.java new file mode 100644 index 0000000000..a546453609 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/SerializeWriterToBytesTest.java @@ -0,0 +1,66 @@ +package com.alibaba.fastjson.serializer; + +import com.alibaba.fastjson.util.IOUtils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * @author gongdewei 2020/5/15 + */ +public class SerializeWriterToBytesTest { + + /** + * Execute toBytes periodically, use tools to analyze JVM memory allocation. + * For example, Memory Allocation Record of YourKit java profiler + */ + public static void testLargeStrToBytes() { + String str = createTestStr(); + for (int i = 0; i < 600; i++) { + SerializeWriter writer = new SerializeWriter(); + try { + writer.writeString(str); + writer.toBytes("UTF-8"); + } finally { + writer.close(); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + } + + public static void testLargeStrWriteToEx() throws IOException { + String str = createTestStr(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(str.length()+2); + for (int i = 0; i < 600; i++) { + SerializeWriter writer = new SerializeWriter(); + try { + writer.writeString(str); + writer.writeToEx(baos, IOUtils.UTF8); + } finally { + writer.close(); + baos.reset(); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + } + + private static String createTestStr() { + String tmp = new String(IOUtils.DIGITS); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < 400; i++) { + builder.append(tmp); + } + return builder.toString(); + } + + public static void main(String[] args) throws IOException { + testLargeStrToBytes(); +// testLargeStrWriteToEx(); + } +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issue3084/TestRefWithQuote.java b/src/test/java/com/alibaba/fastjson/serializer/issue3084/TestRefWithQuote.java new file mode 100644 index 0000000000..6340f9cf15 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issue3084/TestRefWithQuote.java @@ -0,0 +1,45 @@ +package com.alibaba.fastjson.serializer.issue3084; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +public class TestRefWithQuote { + + public static class X { + private String x; + + public X(String x) { + this.x = x; + } + + public String getX() { + return x; + } + + public void setX(String x) { + this.x = x; + } + } + + @Test + public void testIssue3084() { + Map origin = new HashMap(); + TestRefWithQuote.X x = new TestRefWithQuote.X("x"); + origin.put("aaaa\"", x); + origin.put("bbbb\"", x); + + try { + String json = JSON.toJSONString(origin, true); + JSONObject root = JSON.parseObject(json); + assertSame(root.get("bbbb\\"), root.get("aaaa\\")); + } catch (Exception e) { + fail("should not fail !!!"); + } + } +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issue3177/Test3177Bean.java b/src/test/java/com/alibaba/fastjson/serializer/issue3177/Test3177Bean.java new file mode 100644 index 0000000000..47073ed96d --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issue3177/Test3177Bean.java @@ -0,0 +1,35 @@ +package com.alibaba.fastjson.serializer.issue3177; + +/** + * + * @author shenzhou-6 + * @since 2020年05月26日 + * + * https://github.com/alibaba/fastjson/issues/3177 + */ +public class Test3177Bean { + static class Parent { + private String _status; + + public String get_status() { + return _status; + } + + public void set_status(String _status) { + this._status = _status; + } + } + + static class Son extends Parent { + + private String status; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issue3177/TestIssues3177.java b/src/test/java/com/alibaba/fastjson/serializer/issue3177/TestIssues3177.java new file mode 100644 index 0000000000..99bcd79546 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issue3177/TestIssues3177.java @@ -0,0 +1,22 @@ +package com.alibaba.fastjson.serializer.issue3177; + +import com.alibaba.fastjson.JSON; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author shenzhou-6 + * @since 2020年05月26日 + * + * https://github.com/alibaba/fastjson/issues/3177 + */ +public class TestIssues3177 { + + @Test + public void testIssues3177(){ + Test3177Bean.Son son = new Test3177Bean.Son(); + son.setStatus("status"); + Assert.assertEquals("{\"status\":\"status\"}",JSON.toJSONString(son)); + } +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issue3473/SerializeWriterJavaSqlDateTest.java b/src/test/java/com/alibaba/fastjson/serializer/issue3473/SerializeWriterJavaSqlDateTest.java new file mode 100644 index 0000000000..e7c8a9f948 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issue3473/SerializeWriterJavaSqlDateTest.java @@ -0,0 +1,45 @@ +package com.alibaba.fastjson.serializer.issue3473; + +import java.sql.Date; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.time.DateUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +/** + * package com.alibaba.fastjson.serializer.issue3473
+ * description: java.sql.Date序列化测试
+ * Copyright 2019 thunisoft, Inc. All rights reserved. + * + * @author fanzhongwei + * @date 20-9-29 + */ +public class SerializeWriterJavaSqlDateTest { + + private Map data = new HashMap(1, 1); + + @Before + public void before() throws ParseException { + data.put("sqlDate", new Date(DateUtils.parseDate("2020-09-29", "yyyy-MM-dd") + .getTime())); + } + + @Test + public void yyyy_MM_dd_HH_mm_ss_test() { + String json = JSON.toJSONString(data, SerializerFeature.WriteDateUseDateFormat); + Assert.assertEquals("{\"sqlDate\":\"2020-09-29 00:00:00\"}", json); + } + + @Test + public void yyyy_MM_dd_test() { + String json = JSON.toJSONString(data); + Assert.assertEquals("{\"sqlDate\":\"2020-09-29\"}", json); + } +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issue3479/TestIssue3479.java b/src/test/java/com/alibaba/fastjson/serializer/issue3479/TestIssue3479.java new file mode 100644 index 0000000000..3e68b4481c --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issue3479/TestIssue3479.java @@ -0,0 +1,76 @@ +package com.alibaba.fastjson.serializer.issue3479; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestIssue3479 { + + @JSONType(seeAlso = {Dog.class, Cat.class}, typeKey = "typeKey") + public static abstract class Animal { + + private String typeKey; + + public String getTypeKey() { + return typeKey; + } + + public void setTypeKey(String typeKey) { + this.typeKey = typeKey; + } + } + + @JSONType(typeName = "dog") + public static class Dog extends Animal { + private String dogName; + + public String getDogName() { + return dogName; + } + + public void setDogName(String dogName) { + this.dogName = dogName; + } + + @Override + public String toString() { + return "Dog{" + + "dogName='" + dogName + '\'' + + '}'; + } + } + + @JSONType(typeName = "cat") + public static class Cat extends Animal { + private String catName; + + public String getCatName() { + return catName; + } + + public void setCatName(String catName) { + this.catName = catName; + } + + @Override + public String toString() { + return "Cat{" + + "catName='" + catName + '\'' + + '}'; + } + } + + + public static void main(String[] args) { + Dog dog = new Dog(); + dog.dogName = "dog1001"; + + String text = JSON.toJSONString(dog, SerializerFeature.WriteClassName); + System.out.println(text); + + Dog dog2 = (Dog) JSON.parseObject(text, Animal.class); + + System.out.println(dog2); + } + +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issue3638and3067/Issue3638and3067Test.java b/src/test/java/com/alibaba/fastjson/serializer/issue3638and3067/Issue3638and3067Test.java new file mode 100644 index 0000000000..b35388eecb --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issue3638and3067/Issue3638and3067Test.java @@ -0,0 +1,47 @@ +package com.alibaba.fastjson.serializer.issue3638and3067; + +import com.alibaba.fastjson.JSONObject; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.sql.Timestamp; + +/** + * @author Shilong Li (Lori) + * @project fastjson + * @filename Issue3638and3067Test + * @date 2021/4/17 14:47 + */ +public class Issue3638and3067Test { + JSONObject jo; + + @Before + public void init() { + jo = new JSONObject(); + } + + @Test + public void testTime1() { + jo.put("d1", "2021-04-17 15:14:00"); + Assert.assertEquals(new Timestamp(jo.getDate("d1").getTime()), jo.getTimestamp("d1")); + } + + @Test + public void testTime2() { + jo.put("d2", "1970-01-01 08:00:00"); + Assert.assertEquals(new Timestamp(jo.getDate("d2").getTime()), jo.getTimestamp("d2")); + } + + @Test + public void testTime3() { + jo.put("d3", "1970-01-01 07:00:00"); + Assert.assertEquals(new Timestamp(jo.getDate("d3").getTime()), jo.getTimestamp("d3")); + } + + @Test + public void testTime4() { + jo.put("d4", "1900-01-01"); + Assert.assertEquals(new Timestamp(jo.getDate("d4").getTime()), jo.getTimestamp("d4")); + } +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestEntity.java b/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestEntity.java new file mode 100644 index 0000000000..62a1bb011b --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestEntity.java @@ -0,0 +1,9 @@ +package com.alibaba.fastjson.serializer.issues3601; + +import lombok.Data; + +@Data +public class TestEntity { + private TestEnum testEnum; + private String testName; +} diff --git a/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestEnum.java b/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestEnum.java new file mode 100644 index 0000000000..f0792e9164 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestEnum.java @@ -0,0 +1,32 @@ +package com.alibaba.fastjson.serializer.issues3601; + +import com.alibaba.fastjson.annotation.JSONField; + +public enum TestEnum { + + @JSONField + test1("1"), +// @JSONField + test2("2"); + + private String title; + + TestEnum(String title) { + this.title = title; + } + +// @JSONField + public String getTitle() { + return title; + } + + private Integer i = 100; + + @JSONField + public Integer getI() { + return i; + } + +} + + diff --git a/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestIssue3601.java b/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestIssue3601.java new file mode 100644 index 0000000000..2618d78926 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/serializer/issues3601/TestIssue3601.java @@ -0,0 +1,19 @@ +package com.alibaba.fastjson.serializer.issues3601; + +import com.alibaba.fastjson.JSON; +import org.junit.Assert; +import org.junit.Test; + +public class TestIssue3601 { + + @Test + public void enumTest() { + TestEntity testEntity = new TestEntity(); + testEntity.setTestName("ganyu"); + testEntity.setTestEnum(TestEnum.test1); + String json = JSON.toJSONString(testEntity); + System.out.println(json); + Assert.assertEquals("{\"testEnum\":\"test1\",\"testName\":\"ganyu\"}", json); + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_0.java b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_0.java new file mode 100644 index 0000000000..cf3c40762e --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_0.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.validate; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONValidator; +import com.alibaba.json.test.benchmark.decode.EishayDecodeBytes; +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; + +public class JSONValidateTest_0 extends TestCase { + public void test_validate_benchmark() throws Exception { + String json = JSON.toJSONString(EishayDecodeBytes.instance.getContent()); + + for (int n = 0; n < 10; ++n) { + long start = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + JSONValidator validator = JSONValidator.from(json); + validator.validate(); // 518 + } + System.out.println("millis : " + (System.currentTimeMillis() - start)); + } + } + + + + + public void test_validate_utf8_benchmark() throws Exception { + byte[] json = JSON.toJSONBytes(EishayDecodeBytes.instance.getContent()); + + for (int n = 0; n < 5; ++n) { + long start = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + JSONValidator validator = JSONValidator.fromUtf8(json); + validator.validate(); + } + System.out.println("millis : " + (System.currentTimeMillis() - start)); + } + } +} diff --git a/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_T1 b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_T1 new file mode 100644 index 0000000000..97dc71a813 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_T1 @@ -0,0 +1,958 @@ +package com.alibaba.fastjson.validate; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +public class JSONValidateTest_T1 { + @Before + public void setUp() throws Exception { + + } + + @Test + public void testCap1Case1() { + try { + JSONValidator.from((String) null).validate(); + fail("Should not be able to validate a null object but it did"); + } catch (Exception e) { + + } + } + + @Test + public void testCap1Case2() { + try { + JSONValidator jsv = JSONValidator.from((String) null); + jsv.setSupportMultiValue(true); + jsv.validate(); + fail("Should not be able to validate a null object but it did"); + } catch (Exception e) { + + } + } + + @Test + public void testCap1Case3() { + JSONValidator jsv = JSONValidator.from("{\"a\" : \"b\"}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case4() { + JSONValidator jsv = JSONValidator.from("true"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case5() { + JSONValidator jsv = JSONValidator.from("{\"a\" : \"b\"}{\"a\" : \"b\"}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case6() { + JSONValidator jsv = JSONValidator.from("true true"); + jsv.setSupportMultiValue(true); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case7() { + JSONValidator jsv = JSONValidator.from("true true false"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case8() { + JSONValidator jsv = JSONValidator.from("true true false"); + jsv.setSupportMultiValue(true); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case9() { + JSONValidator jsv = JSONValidator.from(""); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case10() { + JSONValidator jsv = JSONValidator.from(""); + jsv.setSupportMultiValue(true); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case11() { + JSONValidator jsv = JSONValidator.from("ÏÇ◊ÎÏ◊Œ„´ˇÁ¨ˆØÏ◊ı˜"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case12() { + JSONValidator jsv = JSONValidator.from("ÏÇ◊ÎÏ◊Œ„´ˇÁ¨ˆØÏ◊ı˜"); + jsv.setSupportMultiValue(true); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case13() { + JSONValidator jsv = JSONValidator.from("ÏÇ◊ÎÏ◊Œ„´ ˇÁ¨ˆØÏ◊ı˜"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case14() { + JSONValidator jsv = JSONValidator.from("ÏÇ◊ÎÏ◊Œ„´ ˇÁ¨ˆØÏ◊ı˜"); + jsv.setSupportMultiValue(true); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case15() { + JSONValidator jsv = JSONValidator.from("ÏÇ◊ÎÏ◊Œ„´ ˇÁ¨ˆØÏ◊ı˜ ÏÇ◊ÎÏ◊Œ„´"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case16() { + JSONValidator jsv = JSONValidator.from("ÏÇ◊ÎÏ◊Œ„´ ˇÁ¨ˆØÏ◊ı˜ ÏÇ◊ÎÏ◊Œ„´"); + jsv.setSupportMultiValue(true); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case17() { + JSONValidator jsv = JSONValidator.from("{\"a\" : \"b\"},{\"a\" : \"b\"}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case18() { + JSONValidator jsv = JSONValidator.from("{\"a\" : \"b\"},{\"a\" : \"b\"},{\"a\" : \"b\"}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case19() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : \"c\"}}]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case20() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : \"c\"}}],[{\"a\" : {\"b\" : \"c\"}}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case21() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : \"c\"}}],[{\"a\" : {\"b\" : \"c\"}}],[{\"a\" : {\"b\" : \"c\"}}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case22() { + JSONValidator jsv = JSONValidator.from("true, true"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case23() { + JSONValidator jsv = JSONValidator.from("true, true, true"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case24() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : \"c\"}}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case25() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : \"c\"}},{\"a\" : {\"b\" : \"c\"}}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case26() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : \"c\"}},{\"a\" : {\"b\" : \"c\"}},{\"a\" : {\"b\" : \"c\"}}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case27() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : \"b\"}]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case28() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : \"b\"}],[{\"a\" : \"b\"}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case29() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : \"b\"}],[{\"a\" : \"b\"}],[{\"a\" : \"b\"}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case30() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : {\"c\" : \"d\"}}}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case31() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : {\"c\" : \"d\"}}},{\"a\" : {\"b\" : {\"c\" : \"d\"}}}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case32() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : {\"c\" : \"d\"}}},{\"a\" : {\"b\" : {\"c\" : \"d\"}}},{\"a\" : {\"b\" : {\"c\" : \"d\"}}}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case33() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : \"c\"}}]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case34() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : \"c\"}}],[{\"a\" : {\"b\" : \"c\"}}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case35() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : \"c\"}}],[{\"a\" : {\"b\" : \"c\"}}],[{\"a\" : {\"b\" : \"c\"}}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case36() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : {\"c\" : {\"d\" : \"e\"}}}}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case37() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : {\"c\" : {\"d\" : \"e\"}}}},{\"a\" : {\"b\" : {\"c\" : {\"d\" : \"e\"}}}}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case38() { + JSONValidator jsv = JSONValidator.from("{\"a\" : {\"b\" : {\"c\" : {\"d\" : \"e\"}}}},{\"a\" : {\"b\" : {\"c\" : {\"d\" : \"e\"}}}},{\"a\" : {\"b\" : {\"c\" : {\"d\" : \"e\"}}}}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case39() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : {\"c\" : \"d\"}}}]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case40() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : {\"c\" : \"d\"}}}],[{\"a\" : {\"b\" : {\"c\" : \"d\"}}}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case41() { + JSONValidator jsv = JSONValidator.from("[{\"a\" : {\"b\" : {\"c\" : \"d\"}}}],[{\"a\" : {\"b\" : {\"c\" : \"d\"}}}],[{\"a\" : {\"b\" : {\"c\" : \"d\"}}}]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case42() { + JSONValidator jsv = JSONValidator.from("1e4"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case43() { + JSONValidator jsv = JSONValidator.from("e10"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case44() { + JSONValidator jsv = JSONValidator.from("4e"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case46() { + JSONValidator jsv = JSONValidator.from("12.34"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case47() { + JSONValidator jsv = JSONValidator.from(".3"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case48() { + JSONValidator jsv = JSONValidator.from("13."); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case50() { + JSONValidator jsv = JSONValidator.from("-12"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case51() { + JSONValidator jsv = JSONValidator.from("+43"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case52() { + JSONValidator jsv = JSONValidator.from("-"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case53() { + JSONValidator jsv = JSONValidator.from("[\"a\",\"b\"]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case54() { + JSONValidator jsv = JSONValidator.from("1,2]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case55() { + JSONValidator jsv = JSONValidator.from("[{\"a\":\"b\"},123"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case56() { + JSONValidator jsv = JSONValidator.from("[1 {\"abc\":\"zxy\"}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case57() { + JSONValidator jsv = JSONValidator.from("{\"123\": [1,2,3]}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case58() { + JSONValidator jsv = JSONValidator.from("\"Zxy\":\"abc\",\"x\":\"y\"}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case59() { + JSONValidator jsv = JSONValidator.from("{\"h\":[12,23],\"a\":\"b\""); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case60() { + JSONValidator jsv = JSONValidator.from("{\"a\":\"z\" \"b\":\"y\""); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case61() { + JSONValidator jsv = JSONValidator.from("{\"123\"\"abc\", \"efg\":\"456\""); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case62() { + JSONValidator jsv = JSONValidator.from("\"abc\""); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case63() { + JSONValidator jsv = JSONValidator.from("abc\""); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case64() { + JSONValidator jsv = JSONValidator.from("\"abc"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case65() { + JSONValidator jsv = JSONValidator.from("null"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case66() { + JSONValidator jsv = JSONValidator.from("abc"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case67() { + JSONValidator jsv = JSONValidator.from("true"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case68() { + JSONValidator jsv = JSONValidator.from("true;"); + assertFalse(jsv.validate()); + assertNull(jsv.getType()); + } + + @Test + public void testCap1Case69() { + JSONValidator jsv = JSONValidator.from("true "); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case70() { + JSONValidator jsv = JSONValidator.from("true\t"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case71() { + JSONValidator jsv = JSONValidator.from("true\r"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case72() { + JSONValidator jsv = JSONValidator.from("true\n"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case73() { + JSONValidator jsv = JSONValidator.from("true\f"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case74() { + JSONValidator jsv = JSONValidator.from("true\b"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case75() { + JSONValidator jsv = JSONValidator.from("true,"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case76() { + JSONValidator jsv = JSONValidator.from("true]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case77() { + JSONValidator jsv = JSONValidator.from("true}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case78() { + JSONValidator jsv = JSONValidator.from("true\0"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case79() { + JSONValidator jsv = JSONValidator.from("{\"abc\":\"bcd\"}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case80() { + JSONValidator jsv = JSONValidator.from("{\"cat\":\"dog\"\"cat\":\"dog\"}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case81() { + JSONValidator jsv = JSONValidator.from("{}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case82() { + JSONValidator jsv = JSONValidator.from("{ }"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case83() { + JSONValidator jsv = JSONValidator.from("{abc:\"abc\"}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case84() { + JSONValidator jsv = JSONValidator.from("{\"xyz\" }"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case85() { + JSONValidator jsv = JSONValidator.from("{\"test\": test}"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case86() { + JSONValidator jsv = JSONValidator.from("{\"hello\":\"world\", \"x\":\"y\"}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case87() { + JSONValidator jsv = JSONValidator.from("[ 123 ]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case88() { + JSONValidator jsv = JSONValidator.from("[ \"ab\""); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case89() { + JSONValidator jsv = JSONValidator.from("[ true,\"g\" ]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case90() { + JSONValidator jsv = JSONValidator.from("[ tru ]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case91() { + JSONValidator jsv = JSONValidator.from("[ ]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case92() { + JSONValidator jsv = JSONValidator.from("4.3e-1"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case94() { + JSONValidator jsv = JSONValidator.from("[4.3e-1]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case193() { + JSONValidator jsv = JSONValidator.from("4.3e-13"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case95() { + JSONValidator jsv = JSONValidator.from("4.3e-:"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case96() { + JSONValidator jsv = JSONValidator.from("4.3e-."); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case97() { + JSONValidator jsv = JSONValidator.from("4.3e+13"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case98() { + JSONValidator jsv = JSONValidator.from("4.3e13"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case99() { + JSONValidator jsv = JSONValidator.from("4.3E-1"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case100() { + JSONValidator jsv = JSONValidator.from("4.3"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case101() { + JSONValidator jsv = JSONValidator.from("4.:"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case102() { + JSONValidator jsv = JSONValidator.from("4..:"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case103() { + JSONValidator jsv = JSONValidator.from("45.3"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case104() { + JSONValidator jsv = JSONValidator.from("+4.3"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case105() { + JSONValidator jsv = JSONValidator.from("+]"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case106() { + JSONValidator jsv = JSONValidator.from("+."); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case107() { + JSONValidator jsv = JSONValidator.from("-4.3"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case108() { + JSONValidator jsv = JSONValidator.from("9"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case109() { + JSONValidator jsv = JSONValidator.from("8"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case110() { + JSONValidator jsv = JSONValidator.from("7"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case111() { + JSONValidator jsv = JSONValidator.from("6"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case112() { + JSONValidator jsv = JSONValidator.from("5"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case114() { + JSONValidator jsv = JSONValidator.from("3"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case115() { + JSONValidator jsv = JSONValidator.from("2"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case116() { + JSONValidator jsv = JSONValidator.from("1"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case117() { + JSONValidator jsv = JSONValidator.from("0"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case118() { + JSONValidator jsv = JSONValidator.from("{\"abc\":\"\"}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case119() { + JSONValidator jsv = JSONValidator.from("[\"a\"]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case120() { + JSONValidator jsv = JSONValidator.from("\""); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case121() { + JSONValidator jsv = JSONValidator.from("[\"\\\n\"]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case122() { + JSONValidator jsv = JSONValidator.from("[\"\\\uffff\"]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case124() { + JSONValidator jsv = JSONValidator.from("{\"qwe\":true}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case125() { + JSONValidator jsv = JSONValidator.from("[true]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case126() { + JSONValidator jsv = JSONValidator.from("[true, false]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case123() { + JSONValidator jsv = JSONValidator.from("true"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case127() { + JSONValidator jsv = JSONValidator.from("truu"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case128() { + JSONValidator jsv = JSONValidator.from("trr"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case129() { + JSONValidator jsv = JSONValidator.from("tt"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case130() { + JSONValidator jsv = JSONValidator.from("{\"hi\":false}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case131() { + JSONValidator jsv = JSONValidator.from("[false]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case132() { + JSONValidator jsv = JSONValidator.from("{\"abc\":false, \"bcd\":\"a\"}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case133() { + JSONValidator jsv = JSONValidator.from("false"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case134() { + JSONValidator jsv = JSONValidator.from("falss"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case135() { + JSONValidator jsv = JSONValidator.from("fall"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case136() { + JSONValidator jsv = JSONValidator.from("faa"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case137() { + JSONValidator jsv = JSONValidator.from("fo"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case138() { + JSONValidator jsv = JSONValidator.from("null1"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case139() { + JSONValidator jsv = JSONValidator.from("{\"abc\":null}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case140() { + JSONValidator jsv = JSONValidator.from("[null]"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case141() { + JSONValidator jsv = JSONValidator.from("{\"test\":[null,null]}"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case142() { + JSONValidator jsv = JSONValidator.from("null"); + assertTrue(jsv.validate()); + } + + @Test + public void testCap1Case143() { + JSONValidator jsv = JSONValidator.from("nulo"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case144() { + JSONValidator jsv = JSONValidator.from("nui"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case145() { + JSONValidator jsv = JSONValidator.from("no"); + assertFalse(jsv.validate()); + } + + @Test + public void testCap1Case146() { + JSONValidator jsv = JSONValidator.from("[]"); + jsv.validate(); + assertEquals(JSONValidator.Type.Array, jsv.getType()); + } + + @Test + public void testCap1Case147() { + JSONValidator jsv = JSONValidator.from("[1]"); + jsv.validate(); + assertEquals(JSONValidator.Type.Array, jsv.getType()); + } + + @Test + public void testCap1Case148() { + JSONValidator jsv = JSONValidator.from("[1,2]"); + jsv.validate(); + assertEquals(JSONValidator.Type.Array, jsv.getType()); + } + + @Test + public void testCap1Case149() { + JSONValidator jsv = JSONValidator.from("{}"); + jsv.validate(); + assertEquals(JSONValidator.Type.Object, jsv.getType()); + } + + @Test + public void testCap1Case150() { + JSONValidator jsv = JSONValidator.from("{\"a\":\"b\"}"); + jsv.validate(); + assertEquals(JSONValidator.Type.Object, jsv.getType()); + } + + @Test + public void testCap1Case151() { + JSONValidator jsv = JSONValidator.from("{\"a\":\"b\",\"a\":\"b\"}"); + jsv.validate(); + assertEquals(JSONValidator.Type.Object, jsv.getType()); + } + + @Test + public void testCap1Case152() { + JSONValidator jsv = JSONValidator.from("\"\""); + jsv.validate(); + assertEquals(JSONValidator.Type.Value, jsv.getType()); + } + + @Test + public void testCap1Case153() { + JSONValidator jsv = JSONValidator.from("\"true\""); + jsv.validate(); + assertEquals(JSONValidator.Type.Value, jsv.getType()); + } + +} diff --git a/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_basic.java b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_basic.java new file mode 100644 index 0000000000..99882c7369 --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_basic.java @@ -0,0 +1,64 @@ +package com.alibaba.fastjson.validate; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +public class JSONValidateTest_basic extends TestCase +{ + public void test_for_bastic_true() throws Exception { + assertTrue(JSONValidator.from("{\"id\":true}").validate()); + assertTrue(JSONValidator.from("[true]").validate()); + assertTrue(JSONValidator.from("true").validate()); + } + + public void test_for_bastic_false() throws Exception { + assertTrue(JSONValidator.from("{\"id\":false}").validate()); + assertTrue(JSONValidator.from("[false]").validate()); + assertTrue(JSONValidator.from("false").validate()); + } + + public void test_for_bastic_null() throws Exception { + assertTrue(JSONValidator.from("{\"id\":null}").validate()); + assertTrue(JSONValidator.from("[null]").validate()); + assertTrue(JSONValidator.from("null").validate()); + + + } + + public void test_long2ip() { + long a = 1677734491111L; + long b = 2697245671L; + long longVal = a; + + int intVal = -1597721625; + long unsignedIntVal = intVal & 0xFFFFFFFFL; + boolean negative = (longVal & 0xFFFFFFFF00000000L) != 0; + + + + System.out.println(intVal & 0xFFFFFFFFL); + + System.out.println((int) b); + + byte[] bytes0 = new byte[8]; + byte[] bytes1 = new byte[8]; + byte[] bytes2 = new byte[8]; + + putLong(bytes0, 0, a); + putLong(bytes1, 0, b); + putLong(bytes2, 0, 0xFFFFFFFF00000000L); + System.out.println(""); + + } + + static void putLong(byte[] b, int off, long val) { + b[off + 7] = (byte) (val ); + b[off + 6] = (byte) (val >>> 8); + b[off + 5] = (byte) (val >>> 16); + b[off + 4] = (byte) (val >>> 24); + b[off + 3] = (byte) (val >>> 32); + b[off + 2] = (byte) (val >>> 40); + b[off + 1] = (byte) (val >>> 48); + b[off ] = (byte) (val >>> 56); + } +} diff --git a/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_file.java b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_file.java new file mode 100644 index 0000000000..fbcf71dfcb --- /dev/null +++ b/src/test/java/com/alibaba/fastjson/validate/JSONValidateTest_file.java @@ -0,0 +1,63 @@ +package com.alibaba.fastjson.validate; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; +import org.apache.commons.io.FileUtils; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +public class JSONValidateTest_file extends TestCase +{ + public void test_for_file() throws Exception { + for (int i = 0; i < 10; ++i) { + long start = System.currentTimeMillis(); + + File file = new File("/Users/wenshao/Downloads/000002_0.json"); + FileInputStream is = new FileInputStream(file); + JSONValidator validator = JSONValidator.fromUtf8(is); + assertTrue(validator.validate()); + validator.close(); + + // 642 335 796 + System.out.println("millis " + (System.currentTimeMillis() - start)); + } + } + + public void test_for_file2() throws Exception { + File file = new File("/Users/wenshao/Downloads/000002_0.json"); + byte[] bytes = FileUtils.readFileToByteArray(file); + + for (int i = 0; i < 10; ++i) { + long start = System.currentTimeMillis(); + + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + + JSONValidator validator = JSONValidator.fromUtf8(is); + assertTrue(validator.validate()); + validator.close(); + + // 642 335 796 + System.out.println("millis " + (System.currentTimeMillis() - start)); + } + } + + + public void test_for_fileReader() throws Exception { + for (int i = 0; i < 10; ++i) { + long start = System.currentTimeMillis(); + + File file = new File("/Users/wenshao/Downloads/000002_0.json"); + Reader is = new InputStreamReader(new FileInputStream(file), "UTF8"); + JSONValidator validator = JSONValidator.from(is); + assertTrue(validator.validate()); + validator.close(); + + // 642 335 796 + System.out.println("millis " + (System.currentTimeMillis() - start)); + } + } +} diff --git a/src/test/java/com/alibaba/json/ArrayRefTest2.java b/src/test/java/com/alibaba/json/ArrayRefTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/ByteArrayTest2.java b/src/test/java/com/alibaba/json/ByteArrayTest2.java new file mode 100644 index 0000000000..9699213c6c --- /dev/null +++ b/src/test/java/com/alibaba/json/ByteArrayTest2.java @@ -0,0 +1,53 @@ +package com.alibaba.json; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONWriter; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import junit.framework.TestCase; +import org.junit.Assert; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; +import java.nio.charset.Charset; + + +public class ByteArrayTest2 extends TestCase { + + public static class CertFile { + public String name; + public byte[] data; + } + + public void test_0() throws Exception { + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + + CertFile file = new CertFile(); + file.name = "testname"; + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 2048; i++) { + sb.append("1"); + } + file.data = sb.toString().getBytes(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + JSONWriter writer = new JSONWriter(new OutputStreamWriter(bos)); + writer.config(SerializerFeature.WriteClassName, true); + writer.writeObject(file); + writer.flush(); + + System.out.println(bos); + + byte[] data = bos.toByteArray(); + Charset charset = Charset.forName("UTF-8"); + CertFile convertFile = (CertFile)JSON.parse(data, 0, data.length, charset.newDecoder(), Feature.AllowArbitraryCommas, + Feature.IgnoreNotMatch, Feature.SortFeidFastMatch, Feature.DisableCircularReferenceDetect, + Feature.AutoCloseSource); + + Assert.assertEquals(file.name, convertFile.name); + Assert.assertArrayEquals(file.data, convertFile.data); + } +} diff --git a/src/test/java/com/alibaba/json/TestGC.java b/src/test/java/com/alibaba/json/TestGC.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/AnnotationTest.java b/src/test/java/com/alibaba/json/bvt/AnnotationTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/AnnotationTest2.java b/src/test/java/com/alibaba/json/bvt/AnnotationTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/AnnotationTest3.java b/src/test/java/com/alibaba/json/bvt/AnnotationTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/AppendableFieldTest.java b/src/test/java/com/alibaba/json/bvt/AppendableFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ArmoryTest.java b/src/test/java/com/alibaba/json/bvt/ArmoryTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ArrayListFieldTest.java b/src/test/java/com/alibaba/json/bvt/ArrayListFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ArrayListFloatFieldTest.java b/src/test/java/com/alibaba/json/bvt/ArrayListFloatFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ArrayRefTest.java b/src/test/java/com/alibaba/json/bvt/ArrayRefTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/Base64Test.java b/src/test/java/com/alibaba/json/bvt/Base64Test.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/BigDecimalFieldTest.java b/src/test/java/com/alibaba/json/bvt/BigDecimalFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/BigIntegerFieldTest.java b/src/test/java/com/alibaba/json/bvt/BigIntegerFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/BuilderTest.java b/src/test/java/com/alibaba/json/bvt/BuilderTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_1.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_2.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_3.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_4.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_5_base64.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_5_base64.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_6_gzip.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_6_gzip.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_7_gzip_hex.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_7_gzip_hex.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ByteFieldTest.java b/src/test/java/com/alibaba/json/bvt/ByteFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/CastTest.java b/src/test/java/com/alibaba/json/bvt/CastTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/CastTest2.java b/src/test/java/com/alibaba/json/bvt/CastTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/CharTypesTest.java b/src/test/java/com/alibaba/json/bvt/CharTypesTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/CharsetFieldTest.java b/src/test/java/com/alibaba/json/bvt/CharsetFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/CircularReferenceTest.java b/src/test/java/com/alibaba/json/bvt/CircularReferenceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ClassFieldTest.java b/src/test/java/com/alibaba/json/bvt/ClassFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/CurrencyTest5.java b/src/test/java/com/alibaba/json/bvt/CurrencyTest5.java index eeb70dbd7a..0f28b21202 100644 --- a/src/test/java/com/alibaba/json/bvt/CurrencyTest5.java +++ b/src/test/java/com/alibaba/json/bvt/CurrencyTest5.java @@ -22,9 +22,11 @@ public void test_0() throws Exception { String str1 = "{\"value\":{\"currencyCode\":\"CNY\",\"displayName\":\"Chinese Yuan\",\"symbol\":\"CNY\"}}"; String str2 = "{\"value\":{\"currencyCode\":\"CNY\",\"displayName\":\"人民币\",\"symbol\":\"¥\"}}"; String str3 = "{\"value\":{\"currencyCode\":\"CNY\",\"displayName\":\"Chinese Yuan\",\"numericCodeAsString\":\"156\",\"symbol\":\"CN¥\"}}"; + String str4 = "{\"value\":{\"currencyCode\":\"CNY\",\"displayName\":\"人民币\",\"numericCodeAsString\":\"156\",\"symbol\":\"¥\"}}"; assertTrue(text.equals(str1) || text.equals(str2) - || text.equals(str3)); + || text.equals(str3) + || text.equals(str4)); Currency currency = JSON.parseObject(text, VO.class).value; diff --git a/src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest.java b/src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/DoubleArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/DoubleArrayFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/DoubleFieldTest_A.java b/src/test/java/com/alibaba/json/bvt/DoubleFieldTest_A.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/EmptyObjectTest.java b/src/test/java/com/alibaba/json/bvt/EmptyObjectTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/EnumerationTest.java b/src/test/java/com/alibaba/json/bvt/EnumerationTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/FieldBasedTest.java b/src/test/java/com/alibaba/json/bvt/FieldBasedTest.java new file mode 100644 index 0000000000..a578a2d4c0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FieldBasedTest.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import junit.framework.TestCase; + +/** + * @author TimAndy + */ +public class FieldBasedTest extends TestCase { + public void test_filed_based_parse() { + Student student = new Student("123", "你好世界", 60); + String json = JSON.toJSONString(student, new SerializeConfig(true)); + Student result = JSON.parseObject(json, Student.class, new ParserConfig(true)); + + assertNotNull(result); + assertEquals("123", result.id); + assertEquals("你好世界", result.name); + assertEquals(60, result.score); + } + + static final class Student { + private String id; + private String name; + private int score; + + Student() { + } + + Student(String id, String name, int score) { + this.id = id; + this.name = name; + this.score = score; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/FileFieldTest.java b/src/test/java/com/alibaba/json/bvt/FileFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/FloatArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/FloatArrayFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/FloatFieldTest.java b/src/test/java/com/alibaba/json/bvt/FloatFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/FloatFieldTest_A.java b/src/test/java/com/alibaba/json/bvt/FloatFieldTest_A.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/GroovyTest.java b/src/test/java/com/alibaba/json/bvt/GroovyTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/InetAddressFieldTest.java b/src/test/java/com/alibaba/json/bvt/InetAddressFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/InetSocketAddressFieldTest.java b/src/test/java/com/alibaba/json/bvt/InetSocketAddressFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/IntArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/IntArrayFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/IntKeyMapTest.java b/src/test/java/com/alibaba/json/bvt/IntKeyMapTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/IntegerArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/IntegerArrayFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONArrayTest.java b/src/test/java/com/alibaba/json/bvt/JSONArrayTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONArrayTest2.java b/src/test/java/com/alibaba/json/bvt/JSONArrayTest2.java old mode 100755 new mode 100644 index 3eaaa5d0d7..2dc9082d7f --- a/src/test/java/com/alibaba/json/bvt/JSONArrayTest2.java +++ b/src/test/java/com/alibaba/json/bvt/JSONArrayTest2.java @@ -2,6 +2,7 @@ import java.math.BigInteger; +import com.alibaba.fastjson.JSON; import org.junit.Assert; import junit.framework.TestCase; @@ -36,5 +37,6 @@ public void test_0() throws Exception { Assert.assertEquals(new java.sql.Date(time), array2.getSqlDate(2)); Assert.assertEquals(new java.sql.Timestamp(time), array2.getTimestamp(2)); Assert.assertEquals(array2.size(), array2.size()); + } } diff --git a/src/test/java/com/alibaba/json/bvt/JSONArrayTest_hashCode.java b/src/test/java/com/alibaba/json/bvt/JSONArrayTest_hashCode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONExceptionTest.java b/src/test/java/com/alibaba/json/bvt/JSONExceptionTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONFeidDemo2.java b/src/test/java/com/alibaba/json/bvt/JSONFeidDemo2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONFieldDefaultValueTest.java b/src/test/java/com/alibaba/json/bvt/JSONFieldDefaultValueTest.java new file mode 100644 index 0000000000..a117ac88a5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONFieldDefaultValueTest.java @@ -0,0 +1,257 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class JSONFieldDefaultValueTest extends TestCase { + public void test_default_value() throws Exception { + Model m = new Model(); + String s = JSON.toJSONString(m); + System.out.println(s); + Model m2 = JSON.parseObject(s, Model.class); + assertEquals("string", m2.getString()); + assertEquals(false, m2.getaBoolean()); + assertEquals(true, m2.getaBoolean2().booleanValue()); + assertEquals(0, m2.getAnInt()); + assertEquals(888, m2.getInteger().intValue()); + assertEquals(0, m2.getaShort()); + assertEquals(88, m2.getaShort2().shortValue()); + assertEquals('\u0000', m2.getaChar()); + assertEquals('J', m2.getCharacter().charValue()); + assertEquals(0, m2.getaByte()); + assertEquals(8, m2.getaByte2().byteValue()); + assertEquals(0, m2.getaLong()); + assertEquals(8888, m2.getaLong2().longValue()); + assertEquals("0.0", "" + m2.getaFloat()); + assertEquals("8.8", "" + m2.getaFloat2()); + assertEquals("0.0", "" + m2.getaDouble()); + assertEquals("88.88", "" + m2.getaDouble2()); + } + + public void test_not_null() throws Exception { + Model m = new Model("test", true, 888, (short)88, 'J', (byte)8, 8888L, 8.8F, 88.88, false, 999, (short)99, 'C', (byte)9, 9999L, 9.9F, 99.99); + String s = JSON.toJSONString(m); + System.out.println(s); + Model m2 = JSON.parseObject(s, Model.class); + assertEquals("test", m2.getString()); + assertEquals(true, m2.getaBoolean()); + assertEquals(false, m2.getaBoolean2().booleanValue()); + assertEquals(888, m2.getAnInt()); + assertEquals(999, m2.getInteger().intValue()); + assertEquals(88, m2.getaShort()); + assertEquals(99, m2.getaShort2().shortValue()); + assertEquals('J', m2.getaChar()); + assertEquals('C', m2.getCharacter().charValue()); + assertEquals(8, m2.getaByte()); + assertEquals(9, m2.getaByte2().byteValue()); + assertEquals(8888, m2.getaLong()); + assertEquals(9999, m2.getaLong2().longValue()); + assertEquals("8.8", "" + m2.getaFloat()); + assertEquals("9.9", "" + m2.getaFloat2()); + assertEquals("88.88", "" + m2.getaDouble()); + assertEquals("99.99", "" + m2.getaDouble2()); + } + + public static class Model { + @JSONField(defaultValue = "string") + private String string; + + @JSONField(defaultValue = "true") //shouldn't work + private boolean aBoolean; + @JSONField(defaultValue = "888") //shouldn't work + private int anInt; + @JSONField(defaultValue = "88") //shouldn't work + private short aShort; + @JSONField(defaultValue = "J") //shouldn't work + private char aChar; + @JSONField(defaultValue = "8") //shouldn't work + private byte aByte; + @JSONField(defaultValue = "8888") //shouldn't work + private long aLong; + @JSONField(defaultValue = "8.8") //shouldn't work + private float aFloat; + @JSONField(defaultValue = "88.88") //shouldn't work + private double aDouble; + + @JSONField(defaultValue = "true") + private Boolean aBoolean2; + @JSONField(defaultValue = "888") + private Integer integer; + @JSONField(defaultValue = "88") + private Short aShort2; + @JSONField(defaultValue = "J") + private Character character; + @JSONField(defaultValue = "8") + private Byte aByte2; + @JSONField(defaultValue = "8888") + private Long aLong2; + @JSONField(defaultValue = "8.8") + private Float aFloat2; + @JSONField(defaultValue = "88.88") + private Double aDouble2; + + public Model(String string, boolean aBoolean, int anInt, short aShort, char aChar, + byte aByte, long aLong, float aFloat, double aDouble, + Boolean aBoolean2, Integer integer, Short aShort2, Character character, + Byte aByte2, Long aLong2, Float aFloat2, Double aDouble2) { + this.string = string; + this.aBoolean = aBoolean; + this.anInt = anInt; + this.aShort = aShort; + this.aChar = aChar; + this.aByte = aByte; + this.aLong = aLong; + this.aFloat = aFloat; + this.aDouble = aDouble; + this.aBoolean2 = aBoolean2; + this.integer = integer; + this.aShort2 = aShort2; + this.character = character; + this.aByte2 = aByte2; + this.aLong2 = aLong2; + this.aFloat2 = aFloat2; + this.aDouble2 = aDouble2; + } + + public Model() { + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + + public boolean getaBoolean() { + return aBoolean; + } + + public void setaBoolean(boolean aBoolean) { + this.aBoolean = aBoolean; + } + + public int getAnInt() { + return anInt; + } + + public void setAnInt(int anInt) { + this.anInt = anInt; + } + + public short getaShort() { + return aShort; + } + + public void setaShort(short aShort) { + this.aShort = aShort; + } + + public char getaChar() { + return aChar; + } + + public void setaChar(char aChar) { + this.aChar = aChar; + } + + public byte getaByte() { + return aByte; + } + + public void setaByte(byte aByte) { + this.aByte = aByte; + } + + public long getaLong() { + return aLong; + } + + public void setaLong(long aLong) { + this.aLong = aLong; + } + + public float getaFloat() { + return aFloat; + } + + public void setaFloat(float aFloat) { + this.aFloat = aFloat; + } + + public double getaDouble() { + return aDouble; + } + + public void setaDouble(double aDouble) { + this.aDouble = aDouble; + } + + public Boolean getaBoolean2() { + return aBoolean2; + } + + public void setaBoolean2(Boolean aBoolean2) { + this.aBoolean2 = aBoolean2; + } + + public Integer getInteger() { + return integer; + } + + public void setInteger(Integer integer) { + this.integer = integer; + } + + public Short getaShort2() { + return aShort2; + } + + public void setaShort2(Short aShort2) { + this.aShort2 = aShort2; + } + + public Character getCharacter() { + return character; + } + + public void setCharacter(Character character) { + this.character = character; + } + + public Byte getaByte2() { + return aByte2; + } + + public void setaByte2(Byte aByte2) { + this.aByte2 = aByte2; + } + + public Long getaLong2() { + return aLong2; + } + + public void setaLong2(Long aLong2) { + this.aLong2 = aLong2; + } + + public Float getaFloat2() { + return aFloat2; + } + + public void setaFloat2(Float aFloat2) { + this.aFloat2 = aFloat2; + } + + public Double getaDouble2() { + return aDouble2; + } + + public void setaDouble2(Double aDouble2) { + this.aDouble2 = aDouble2; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONFromObjectTest.java b/src/test/java/com/alibaba/json/bvt/JSONFromObjectTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest.java old mode 100755 new mode 100644 index 7c89f0755f..9768526d46 --- a/src/test/java/com/alibaba/json/bvt/JSONObjectTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest.java @@ -187,4 +187,13 @@ public void test_getObject_map() throws Exception { Assert.assertEquals(0, json.getJSONObject("obj").size()); } + + public void test_getObjectOrDefault() { + JSONObject json = new JSONObject(); + json.put("testKey", "testVal"); + json.put("testKey2", null); + + Assert.assertEquals("default", json.getOrDefault("testNonKet", "default")); + Assert.assertEquals("default", json.getOrDefault("testKey2", "default")); + } } diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest2.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest3.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest7.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest7.java new file mode 100644 index 0000000000..97d91c2125 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest7.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class JSONObjectTest7 extends TestCase { + + public void test() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"test\":null,\"a\":\"cc\"}"); + assertEquals(2, jsonObject.entrySet().size()); + assertTrue(jsonObject.containsKey("test")); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest_getObj.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest_getObj.java index 0363335e06..2d7a6889e7 100644 --- a/src/test/java/com/alibaba/json/bvt/JSONObjectTest_getObj.java +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest_getObj.java @@ -1,11 +1,16 @@ package com.alibaba.json.bvt; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; import org.junit.Assert; import com.alibaba.fastjson.JSONObject; import junit.framework.TestCase; +import java.util.HashMap; +import java.util.List; + public class JSONObjectTest_getObj extends TestCase { public void test_get_empty() throws Exception { @@ -21,6 +26,20 @@ public void test_get_null() throws Exception { Assert.assertEquals("null", obj.get("value")); Assert.assertNull(obj.getObject("value", Model.class)); } + + public void test_get_obj() throws Exception { + JSONObject obj = new JSONObject(); + obj.put("value", new HashMap()); + Assert.assertEquals(new JSONObject(), obj.getObject("value", JSONObject.class)); + } + + public void test_get_obj2() throws Exception { + List json = JSON.parseArray("[{\"values\":[{}]}]", JSONObject.class); + + for (JSONObject obj : json) { + Object values = obj.getObject("values", new TypeReference>() {}); + } + } public static class Model { diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest_hashCode.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest_hashCode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest_readObject.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest_readObject.java new file mode 100644 index 0000000000..9b7f618ee3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest_readObject.java @@ -0,0 +1,156 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +public class JSONObjectTest_readObject extends TestCase { + public void test_0() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("id", 123); + jsonObject.put("obj", new JSONObject()); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(jsonObject); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(JSONObject.class, obj.getClass()); + assertEquals(jsonObject, obj); + } + + public void test_2() throws Exception { + JSONObject jsonObject = JSON.parseObject("{123:345}"); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(jsonObject); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(JSONObject.class, obj.getClass()); + assertEquals(jsonObject, obj); + } + + public void test_3() throws Exception { + JSONObject jsonObject = JSON.parseObject("{123:345,\"items\":[1,2,3,4]}"); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(jsonObject); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(JSONObject.class, obj.getClass()); + assertEquals(jsonObject, obj); + } + + public void test_4() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("val", new Byte[]{}); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(jsonObject); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(JSONObject.class, obj.getClass()); + assertEquals(jsonObject.toJSONString(), JSON.toJSONString(obj)); + } + + public void test_5() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("val", new byte[]{}); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(jsonObject); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(JSONObject.class, obj.getClass()); + assertEquals(jsonObject.toJSONString(), JSON.toJSONString(obj)); + } + + public void test_6() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("val", new Character[]{}); + jsonObject.put("cls", java.lang.Number.class); + jsonObject.put("nums", new java.lang.Number[] {}); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(jsonObject); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(JSONObject.class, obj.getClass()); + assertEquals(jsonObject.toJSONString(), JSON.toJSONString(obj)); + } + + public void test_7() throws Exception { + ParserConfig.global.setSafeMode(true); + try { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("m", new java.util.HashMap()); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(jsonObject); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + } finally { + ParserConfig.global.setSafeMode(false); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONParseTest.java b/src/test/java/com/alibaba/json/bvt/JSONParseTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTest.java b/src/test/java/com/alibaba/json/bvt/JSONTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTest2.java b/src/test/java/com/alibaba/json/bvt/JSONTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTest_Bytes.java b/src/test/java/com/alibaba/json/bvt/JSONTest_Bytes.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTest_null.java b/src/test/java/com/alibaba/json/bvt/JSONTest_null.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTest_overflow.java b/src/test/java/com/alibaba/json/bvt/JSONTest_overflow.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTokenTest.java b/src/test/java/com/alibaba/json/bvt/JSONTokenTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java b/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTypeTest1.java b/src/test/java/com/alibaba/json/bvt/JSONTypeTest1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSONTypeTest_orders_arrayMapping.java b/src/test/java/com/alibaba/json/bvt/JSONTypeTest_orders_arrayMapping.java old mode 100755 new mode 100644 index 5beed8c21e..594b89b3b8 --- a/src/test/java/com/alibaba/json/bvt/JSONTypeTest_orders_arrayMapping.java +++ b/src/test/java/com/alibaba/json/bvt/JSONTypeTest_orders_arrayMapping.java @@ -23,6 +23,11 @@ public void test_1() throws Exception { JSON.parseObject(json2, Model[].class, Feature.SupportArrayToBean); } + public void test_2() throws Exception { + String json = "[1001,\"xx\"]"; + JSON.parseObject(json, Model.class, Feature.SupportArrayToBean); + } + @JSONType(orders = { "id", "name", "age" }) public static class Model { private int id; diff --git a/src/test/java/com/alibaba/json/bvt/JSONTypeTest_orders_arrayMapping_2.java b/src/test/java/com/alibaba/json/bvt/JSONTypeTest_orders_arrayMapping_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSON_isValid_0.java b/src/test/java/com/alibaba/json/bvt/JSON_isValid_0.java new file mode 100644 index 0000000000..1a93738b6b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSON_isValid_0.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class JSON_isValid_0 extends TestCase { + public void test_for_isValid_0() throws Exception { + assertFalse(JSON.isValid(null)); + assertFalse(JSON.isValid("")); + } + + public void test_for_isValid_value() throws Exception { + assertTrue(JSON.isValid("null")); + assertTrue(JSON.isValid("123")); + assertTrue(JSON.isValid("12.34")); + assertTrue(JSON.isValid("true")); + assertTrue(JSON.isValid("false")); + assertTrue(JSON.isValid("\"abc\"")); + } + + + public void test_for_isValid_obj() throws Exception { + assertTrue(JSON.isValid("{}")); + assertTrue(JSON.isValid("{\"id\":123}")); + assertTrue(JSON.isValid("{\"id\":\"123\"}")); + assertTrue(JSON.isValid("{\"id\":true}")); + assertTrue(JSON.isValid("{\"id\":{}}")); + } + + public void test_for_isValid_obj_1() throws Exception { + assertTrue(JSON.isValidObject("{}")); + assertTrue(JSON.isValidObject("{\"id\":123}")); + assertTrue(JSON.isValidObject("{\"id\":\"123\"}")); + assertTrue(JSON.isValidObject("{\"id\":true}")); + assertTrue(JSON.isValidObject("{\"id\":{}}")); + } + + public void test_for_isValid_array() throws Exception { + assertTrue(JSON.isValid("[]")); + assertTrue(JSON.isValid("[[],[]]")); + assertTrue(JSON.isValid("[{\"id\":123}]")); + assertTrue(JSON.isValid("[{\"id\":\"123\"}]")); + assertTrue(JSON.isValid("[{\"id\":true}]")); + assertTrue(JSON.isValid("[{\"id\":{}}]")); + } + + public void test_for_isValid_array_1() throws Exception { + assertTrue(JSON.isValidArray("[]")); + assertTrue(JSON.isValidArray("[[],[]]")); + assertTrue(JSON.isValidArray("[{\"id\":123}]")); + assertTrue(JSON.isValidArray("[{\"id\":\"123\"}]")); + assertTrue(JSON.isValidArray("[{\"id\":true}]")); + assertTrue(JSON.isValidArray("[{\"id\":{}}]")); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/JSON_isValid_1_error.java b/src/test/java/com/alibaba/json/bvt/JSON_isValid_1_error.java new file mode 100644 index 0000000000..380d6470c0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSON_isValid_1_error.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class JSON_isValid_1_error extends TestCase { + public void test_for_isValid_0() throws Exception { + assertFalse(JSON.isValid(null)); + assertFalse(JSON.isValid("")); + } + + public void test_for_isValid_value() throws Exception { + assertFalse(JSON.isValid("nul")); + assertFalse(JSON.isValid("null,null")); + assertFalse(JSON.isValid("123,")); + assertFalse(JSON.isValid("123,123")); + assertFalse(JSON.isValid("12.34,true")); + assertFalse(JSON.isValid("12.34,123")); + assertFalse(JSON.isValid("tru")); + assertFalse(JSON.isValid("true,123")); + assertFalse(JSON.isValid("fals")); + assertFalse(JSON.isValid("false,123")); + assertFalse(JSON.isValid("\"abc")); + assertFalse(JSON.isValid("\"abc\",123")); + } + + + public void test_for_isValid_obj() throws Exception { + assertFalse(JSON.isValid("{")); + assertFalse(JSON.isValid("{\"id\":123,}}")); + assertFalse(JSON.isValid("{\"id\":\"123}")); + assertFalse(JSON.isValid("{\"id\":{]}")); + assertFalse(JSON.isValid("{\"id\":{")); + } + + public void test_for_isValid_obj_1() throws Exception { + assertFalse(JSON.isValidObject("{")); + assertFalse(JSON.isValidObject("{\"id\":123,}}")); + assertFalse(JSON.isValidObject("{\"id\":\"123}")); + assertFalse(JSON.isValidObject("{\"id\":{]}")); + assertFalse(JSON.isValidObject("{\"id\":{")); + } + + public void test_for_isValid_array() throws Exception { + assertFalse(JSON.isValid("[")); + assertFalse(JSON.isValid("[[,[]]")); + assertFalse(JSON.isValid("[{\"id\":123]")); + assertFalse(JSON.isValid("[{\"id\":\"123\"}")); + assertFalse(JSON.isValid("[{\"id\":true]")); + assertFalse(JSON.isValid("[{\"id\":{}]")); + } + + public void test_for_isValid_array_1() throws Exception { + assertFalse(JSON.isValidArray("[")); + assertFalse(JSON.isValidArray("[[,[]]")); + assertFalse(JSON.isValidArray("[{\"id\":123]")); + assertFalse(JSON.isValidArray("[{\"id\":\"123\"}")); + assertFalse(JSON.isValidArray("[{\"id\":true]")); + assertFalse(JSON.isValidArray("[{\"id\":{}]")); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/JSON_toJSONStringTest.java b/src/test/java/com/alibaba/json/bvt/JSON_toJSONStringTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JSON_toJavaObject_test.java b/src/test/java/com/alibaba/json/bvt/JSON_toJavaObject_test.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JavaBeanMappingTest.java b/src/test/java/com/alibaba/json/bvt/JavaBeanMappingTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JavaBeanTest.java b/src/test/java/com/alibaba/json/bvt/JavaBeanTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/JsonValueTest.java b/src/test/java/com/alibaba/json/bvt/JsonValueTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/LexerTest.java b/src/test/java/com/alibaba/json/bvt/LexerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/LinkedListFieldTest.java b/src/test/java/com/alibaba/json/bvt/LinkedListFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ListFieldTest.java b/src/test/java/com/alibaba/json/bvt/ListFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ListFieldTest2.java b/src/test/java/com/alibaba/json/bvt/ListFieldTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ListFloatFieldTest.java b/src/test/java/com/alibaba/json/bvt/ListFloatFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/LocaleFieldTest.java b/src/test/java/com/alibaba/json/bvt/LocaleFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/LongFieldTest.java b/src/test/java/com/alibaba/json/bvt/LongFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/LongFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/LongFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest.java b/src/test/java/com/alibaba/json/bvt/MapRefTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest1.java b/src/test/java/com/alibaba/json/bvt/MapRefTest1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest2.java b/src/test/java/com/alibaba/json/bvt/MapRefTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest3.java b/src/test/java/com/alibaba/json/bvt/MapRefTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MapTest.java b/src/test/java/com/alibaba/json/bvt/MapTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MapTest2.java b/src/test/java/com/alibaba/json/bvt/MapTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest.java b/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest2.java b/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ModuleTest.java b/src/test/java/com/alibaba/json/bvt/ModuleTest.java new file mode 100644 index 0000000000..d4b3b98cd7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ModuleTest.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.MiscCodec; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.spi.Module; +import junit.framework.TestCase; + +public class ModuleTest extends TestCase { + public void test_for_module() throws Exception { + ParserConfig config = new ParserConfig(); + config.register(new MyModuel2()); + config.register(new MyModuel()); + + assertSame(MiscCodec.instance, config.getDeserializer(A.class)); + } + + public void test_for_module_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.register(new MyModuel2()); + config.register(new MyModuel()); + + assertSame(MiscCodec.instance, config.getObjectWriter(A.class)); + } + + public static class A { + + } + + public static class MyModuel implements Module { + + @Override + public ObjectDeserializer createDeserializer(ParserConfig config, Class type) { + return MiscCodec.instance; + } + + @Override + public ObjectSerializer createSerializer(SerializeConfig config, Class type) { + return MiscCodec.instance; + } + } + + public static class MyModuel2 implements Module { + + @Override + public ObjectDeserializer createDeserializer(ParserConfig config, Class type) { + return null; + } + + @Override + public ObjectSerializer createSerializer(SerializeConfig config, Class type) { + return null; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/NotWriteRootClassNameTest.java b/src/test/java/com/alibaba/json/bvt/NotWriteRootClassNameTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/NumberFieldTest.java b/src/test/java/com/alibaba/json/bvt/NumberFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/OOMTest.java b/src/test/java/com/alibaba/json/bvt/OOMTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ObjectArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/ObjectArrayFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ObjectFieldTest.java b/src/test/java/com/alibaba/json/bvt/ObjectFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ParseArrayTest.java b/src/test/java/com/alibaba/json/bvt/ParseArrayTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/PatternFieldTest.java b/src/test/java/com/alibaba/json/bvt/PatternFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/PointTest.java b/src/test/java/com/alibaba/json/bvt/PointTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/PointTest2.java b/src/test/java/com/alibaba/json/bvt/PointTest2.java old mode 100755 new mode 100644 index b6568ba669..cfc3e8ffcd --- a/src/test/java/com/alibaba/json/bvt/PointTest2.java +++ b/src/test/java/com/alibaba/json/bvt/PointTest2.java @@ -2,6 +2,8 @@ import java.awt.Point; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; import org.junit.Assert; import junit.framework.TestCase; @@ -20,7 +22,7 @@ public void test_point() throws Exception { String text = JSON.toJSONString(point, SerializerFeature.WriteClassName); System.out.println(text); - Object obj = JSON.parse(text); + Object obj = JSON.parse(text, Feature.SupportAutoType); Point point2 = (Point) obj; Assert.assertEquals(point, point2); diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldDoubleTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldDoubleTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldFloatTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldFloatTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldLongTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldLongTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldStringTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldStringTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/RectangleTest.java b/src/test/java/com/alibaba/json/bvt/RectangleTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/SerializeWriterTest.java b/src/test/java/com/alibaba/json/bvt/SerializeWriterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ShortArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/ShortArrayFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/SlashTest.java b/src/test/java/com/alibaba/json/bvt/SlashTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/SpecialKeyTest.java b/src/test/java/com/alibaba/json/bvt/SpecialKeyTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/SqlDateTest1.java b/src/test/java/com/alibaba/json/bvt/SqlDateTest1.java index cf7a42a486..3d36255410 100644 --- a/src/test/java/com/alibaba/json/bvt/SqlDateTest1.java +++ b/src/test/java/com/alibaba/json/bvt/SqlDateTest1.java @@ -1,6 +1,7 @@ package com.alibaba.json.bvt; import java.sql.Date; +import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; @@ -33,4 +34,20 @@ public void test_date() throws Exception { JSON.toJSONStringWithDateFormat(date, "yyyy-MM-dd HH:mm:ss.SSS", SerializerFeature.UseSingleQuotes)); } +// +// public void test_date2() throws Exception { +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// java.util.Date d = sdf.parse("2019-09-12 16:00:00"); +// java.sql.Date ds = new java.sql.Date(d.getTime()); +//// System.out.println("Java Obj: " + sdf.format(ds)); +// +// String jvs = JSON.toJSONString(ds); +//// System.out.println("JSON Str: " + jvs); +// +// java.sql.Date d2s = JSON.parseObject(jvs, java.sql.Date.class); +//// System.out.println("Java Obj: " + sdf.format(d2s)); +//// System.out.println("LONG: " + d2s.getTime()); +// +// assertEquals(d.getTime(), d2s.getTime()); +// } } diff --git a/src/test/java/com/alibaba/json/bvt/SqlTimestampTest.java b/src/test/java/com/alibaba/json/bvt/SqlTimestampTest.java new file mode 100644 index 0000000000..5aad3f1f9d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/SqlTimestampTest.java @@ -0,0 +1,202 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.sql.Timestamp; +import java.util.Locale; +import java.util.TimeZone; + +public class SqlTimestampTest + extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getDefault(); + JSON.defaultLocale = Locale.getDefault(); + } + + public void test_date() throws Exception { + Timestamp ts = new Timestamp( + 97, + 2, + 17, + 15, + 53, + 01, + 12345678 + ); + + System.out.println('"' + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println(json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + } + + public void test_date_1() throws Exception { + // 2020-04-11 03:10:19.516 + Timestamp ts = new Timestamp( + 97, + 2, + 17, + 15, + 53, + 01, + 516000000 + ); + + System.out.println('"' + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println(json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + } + + // 1997-03-17 15:53:01.01 + public void test_date_2() throws Exception { + // 2020-04-11 03:10:19.516 + Timestamp ts = new Timestamp( + 97, + 3, + 17, + 15, + 53, + 01, + 10000000 + ); + + System.out.println('"' + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println(json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + } + + public void test_date_999999999() throws Exception { + // 2020-04-11 03:10:19.516 + Timestamp ts = new Timestamp( + 97, + 2, + 17, + 15, + 53, + 01, + 999999999 + ); + + System.out.println('"' + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println(json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + } + + public void test_date_x1() throws Exception { + // 2020-04-11 03:10:19.516 + Timestamp ts = new Timestamp( + 97, + 2, + 17, + 15, + 53, + 01, + 5 + ); + + System.out.println('"' + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + System.out.println(json); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println(json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + } + + public void test_date_x2() throws Exception { + // 2020-04-11 03:10:19.516 + Timestamp ts = new Timestamp( + 97, + 2, + 17, + 15, + 53, + 01, + 50 + ); + + System.out.println('"' + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + System.out.println(json); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println(json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + } + + public void test_date_x() throws Exception { + // 2020-04-11 03:10:19.516 + int nanos = 1; + for (int i = 0; i < 8; i++) { + nanos = nanos * 10; + Timestamp ts = new Timestamp( + 97, + 2, + 17, + 15, + 53, + 01, + nanos + ); + + System.out.println("_ts_: \"" + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + System.out.println("json: " + json); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println("json: " + json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + System.out.println(); + } + } + + public void test_date_xx() throws Exception { + // 2020-04-11 03:10:19.516 + int nanos = 0; + for (int i = 0; i < 9; i++) { + nanos = nanos * 10 + (i + 1); + Timestamp ts = new Timestamp( + 97, + 2, + 17, + 15, + 53, + 01, + nanos + ); + + System.out.println('"' + ts.toString() + '"'); + + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + Timestamp ts2 = JSON.parseObject(json, Timestamp.class); + String json2 = JSON.toJSONString(ts2, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + System.out.println(json2); + assertEquals('"' + ts.toString() + '"', '"' + ts2.toString() + '"'); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/StringFieldTest.java b/src/test/java/com/alibaba/json/bvt/StringFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/SymbolTableTest.java b/src/test/java/com/alibaba/json/bvt/SymbolTableTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TabCharTest.java b/src/test/java/com/alibaba/json/bvt/TabCharTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestDeprecate.java b/src/test/java/com/alibaba/json/bvt/TestDeprecate.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal.java b/src/test/java/com/alibaba/json/bvt/TestExternal.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal2.java b/src/test/java/com/alibaba/json/bvt/TestExternal2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal3.java b/src/test/java/com/alibaba/json/bvt/TestExternal3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal4.java b/src/test/java/com/alibaba/json/bvt/TestExternal4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal5.java b/src/test/java/com/alibaba/json/bvt/TestExternal5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal6.java b/src/test/java/com/alibaba/json/bvt/TestExternal6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestForEmoji.java b/src/test/java/com/alibaba/json/bvt/TestForEmoji.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestForPascalStyle.java b/src/test/java/com/alibaba/json/bvt/TestForPascalStyle.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass.java b/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass2.java b/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestNullKeyMap.java b/src/test/java/com/alibaba/json/bvt/TestNullKeyMap.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestSerializable.java b/src/test/java/com/alibaba/json/bvt/TestSerializable.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TestTimeUnit.java b/src/test/java/com/alibaba/json/bvt/TestTimeUnit.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TimeZoneFieldTest.java b/src/test/java/com/alibaba/json/bvt/TimeZoneFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TimestampTest.java b/src/test/java/com/alibaba/json/bvt/TimestampTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/TypeUtilstTest.java b/src/test/java/com/alibaba/json/bvt/TypeUtilstTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/URIFieldTest.java b/src/test/java/com/alibaba/json/bvt/URIFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/URLFieldTest.java b/src/test/java/com/alibaba/json/bvt/URLFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/UUIDFieldTest.java b/src/test/java/com/alibaba/json/bvt/UUIDFieldTest.java old mode 100755 new mode 100644 index 5b1628bc94..fd6644ed0a --- a/src/test/java/com/alibaba/json/bvt/UUIDFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/UUIDFieldTest.java @@ -23,6 +23,14 @@ public void test_codec() throws Exception { Assert.assertEquals(user1.getValue(), user.getValue()); } + public void test_codec_upper_case() throws Exception { + User user = new User(); + + String text ="{\"value\":\"79104776-6CA7-4E41-948F-4D2ECD06502A\"}"; + user = JSON.parseObject(text, User.class); + + Assert.assertEquals("79104776-6CA7-4E41-948F-4D2ECD06502A", user.getValue().toString().toUpperCase()); + } public void test_codec_null() throws Exception { User user = new User(); diff --git a/src/test/java/com/alibaba/json/bvt/WriteClassNameTest.java b/src/test/java/com/alibaba/json/bvt/WriteClassNameTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/WriteClassNameTest2.java b/src/test/java/com/alibaba/json/bvt/WriteClassNameTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/annotation/DeserializeUsingTest.java b/src/test/java/com/alibaba/json/bvt/annotation/DeserializeUsingTest.java index f3140843e3..30546ca38c 100644 --- a/src/test/java/com/alibaba/json/bvt/annotation/DeserializeUsingTest.java +++ b/src/test/java/com/alibaba/json/bvt/annotation/DeserializeUsingTest.java @@ -22,6 +22,14 @@ public void test_deserializeUsing() throws Exception { assertEquals(SubjectEnum.MATH.ordinal(), teacher.getSubjectList().get(1).intValue()); } + public void test_deserializeUsing2() throws Exception { + String jsonStr = "{'subjectList':['CHINESE','MATH']}"; + + Teacher teacher = JSON.parseObject(jsonStr).toJavaObject(Teacher.class); + assertEquals(SubjectEnum.CHINESE.ordinal(), teacher.getSubjectList().get(0).intValue()); + assertEquals(SubjectEnum.MATH.ordinal(), teacher.getSubjectList().get(1).intValue()); + } + public static class Teacher { @JSONField(deserializeUsing = SubjectListDeserializer.class) diff --git a/src/test/java/com/alibaba/json/bvt/annotation/JSONTypeAutoTypeCheckHandlerTest.java b/src/test/java/com/alibaba/json/bvt/annotation/JSONTypeAutoTypeCheckHandlerTest.java new file mode 100644 index 0000000000..1733f43a9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/annotation/JSONTypeAutoTypeCheckHandlerTest.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.annotation; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class JSONTypeAutoTypeCheckHandlerTest extends TestCase { + public void test_for_checkAutoType() throws Exception { + Cat cat = (Cat) JSON.parseObject("{\"@type\":\"Cat\",\"catId\":123}", Animal.class); + assertEquals(123, cat.catId); + } + + @JSONType(autoTypeCheckHandler = MyAutoTypeCheckHandler.class) + public static class Animal { + + } + + public static class Cat extends Animal { + public int catId; + } + + public static class Mouse extends Animal { + + } + + public static class MyAutoTypeCheckHandler implements ParserConfig.AutoTypeCheckHandler { + + public Class handler(String typeName, Class expectClass, int features) { + if ("Cat".equals(typeName)) { + return Cat.class; + } + + if ("Mouse".equals(typeName)) { + return Mouse.class; + } + + return null; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/annotation/JSONTypejsonType_alphabetic_Test.java b/src/test/java/com/alibaba/json/bvt/annotation/JSONTypejsonType_alphabetic_Test.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest.java b/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest2.java b/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/ASMUtilsTest.java b/src/test/java/com/alibaba/json/bvt/asm/ASMUtilsTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/Case0.java b/src/test/java/com/alibaba/json/bvt/asm/Case0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/Case_Eishay.java b/src/test/java/com/alibaba/json/bvt/asm/Case_Eishay.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/ClassReaderTest.java b/src/test/java/com/alibaba/json/bvt/asm/ClassReaderTest.java new file mode 100644 index 0000000000..56d954e70e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/asm/ClassReaderTest.java @@ -0,0 +1,9 @@ +package com.alibaba.json.bvt.asm; + +import junit.framework.TestCase; + +public class ClassReaderTest extends TestCase { + public void test_read() throws Exception { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/asm/Huge_200_ClassTest.java b/src/test/java/com/alibaba/json/bvt/asm/Huge_200_ClassTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/Huge_300_ClassTest.java b/src/test/java/com/alibaba/json/bvt/asm/Huge_300_ClassTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/JSONASMUtilTest.java b/src/test/java/com/alibaba/json/bvt/asm/JSONASMUtilTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/LoopTest.java b/src/test/java/com/alibaba/json/bvt/asm/LoopTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/SortFieldTest.java b/src/test/java/com/alibaba/json/bvt/asm/SortFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/TestList.java b/src/test/java/com/alibaba/json/bvt/asm/TestList.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/TestNonASM.java b/src/test/java/com/alibaba/json/bvt/asm/TestNonASM.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/asm/TestType.java b/src/test/java/com/alibaba/json/bvt/asm/TestType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/atomic/AtomicIntegerArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/atomic/AtomicIntegerArrayFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/atomic/AtomicLongArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/atomic/AtomicLongArrayFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/awt/ColorTest.java b/src/test/java/com/alibaba/json/bvt/awt/ColorTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/awt/ColorTest2.java b/src/test/java/com/alibaba/json/bvt/awt/ColorTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/awt/FontTest.java b/src/test/java/com/alibaba/json/bvt/awt/FontTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/awt/FontTest2.java b/src/test/java/com/alibaba/json/bvt/awt/FontTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_BrowserCompatible.java b/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_BrowserCompatible.java new file mode 100644 index 0000000000..23b1a2d70f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_BrowserCompatible.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.basicType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.LinkedHashMap; +import java.util.Map; + +public class BigDecimal_BrowserCompatible extends TestCase { + public void test_for_issue() throws Exception { + Map map = new LinkedHashMap(); + map.put("id1", new BigDecimal("-9223370018640066466")); + map.put("id2", new BigDecimal("9223370018640066466")); + map.put("id3", new BigDecimal("100")); + assertEquals("{\"id1\":\"-9223370018640066466\",\"id2\":\"9223370018640066466\",\"id3\":100}", + JSON.toJSONString(map, SerializerFeature.BrowserCompatible) + ); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_field.java b/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_field.java new file mode 100644 index 0000000000..e7f1565a74 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_field.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.basicType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import static com.alibaba.fastjson.serializer.SerializerFeature.BrowserCompatible; + +public class BigDecimal_field extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("{\"value\":\"9007199254741992\"}" + , JSON.toJSONString( + new Model(9007199254741992L))); + + assertEquals("{\"value\":\"-9007199254741992\"}" + , JSON.toJSONString( + new Model(-9007199254741992L))); + + assertEquals("{\"value\":9007199254740990}" + , JSON.toJSONString( + new Model(9007199254740990L))); + + assertEquals("{\"value\":-9007199254740990}" + , JSON.toJSONString( + new Model(-9007199254740990L))); + + assertEquals("{\"value\":100}" + , JSON.toJSONString( + new Model(100))); + + assertEquals("{\"value\":-100}" + , JSON.toJSONString( + new Model(-100))); + } + + + + + public static class Model { + @JSONField(serialzeFeatures = BrowserCompatible) + public BigDecimal value; + + public Model() { + + } + + public Model(long value) { + this.value = BigDecimal.valueOf(value); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_type.java b/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_type.java new file mode 100644 index 0000000000..4cf5375cc2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/basicType/BigDecimal_type.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.basicType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import static com.alibaba.fastjson.serializer.SerializerFeature.BrowserCompatible; + +public class BigDecimal_type extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("{\"value\":\"9007199254741992\"}" + , JSON.toJSONString( + new Model(9007199254741992L))); + + assertEquals("{\"value\":\"-9007199254741992\"}" + , JSON.toJSONString( + new Model(-9007199254741992L))); + + assertEquals("{\"value\":9007199254740990}" + , JSON.toJSONString( + new Model(9007199254740990L))); + + assertEquals("{\"value\":-9007199254740990}" + , JSON.toJSONString( + new Model(-9007199254740990L))); + + assertEquals("{\"value\":100}" + , JSON.toJSONString( + new Model(100))); + + assertEquals("{\"value\":-100}" + , JSON.toJSONString( + new Model(-100))); + } + + + + @JSONType(serialzeFeatures = BrowserCompatible) + public static class Model { + public BigDecimal value; + + public Model() { + + } + + public Model(long value) { + this.value = BigDecimal.valueOf(value); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/basicType/BigInteger_BrowserCompatible.java b/src/test/java/com/alibaba/json/bvt/basicType/BigInteger_BrowserCompatible.java new file mode 100644 index 0000000000..7cf5fc02da --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/basicType/BigInteger_BrowserCompatible.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.basicType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.math.BigInteger; +import java.util.LinkedHashMap; +import java.util.Map; + +public class BigInteger_BrowserCompatible extends TestCase { + public void test_for_issue() throws Exception { + Map map = new LinkedHashMap(); + map.put("id1", 9223370018640066466L); + map.put("id2", new BigInteger("9223370018640066466")); + assertEquals("{\"id1\":\"9223370018640066466\",\"id2\":\"9223370018640066466\"}", + JSON.toJSONString(map, SerializerFeature.BrowserCompatible) + ); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/basicType/DoubleTest3_random.java b/src/test/java/com/alibaba/json/bvt/basicType/DoubleTest3_random.java new file mode 100644 index 0000000000..53c878b727 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/basicType/DoubleTest3_random.java @@ -0,0 +1,78 @@ +package com.alibaba.json.bvt.basicType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Random; + +public class DoubleTest3_random extends TestCase { + public void test_ran() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + double val = rand.nextDouble(); + + String str = JSON.toJSONString(new Model(val)); + Model m = JSON.parseObject(str, Model.class); + + assertEquals(val, m.value); + } + } + + public void test_ran_2() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + double val = rand.nextDouble(); + + String str = JSON.toJSONString(new Model(val), SerializerFeature.BeanToArray); + Model m = JSON.parseObject(str, Model.class, Feature.SupportArrayToBean); + + assertEquals(val, m.value); + } + } + + public void test_ran_3() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + double val = rand.nextDouble(); + + String str = JSON.toJSONString(Collections.singletonMap("val", val)); + double val2 = JSON.parseObject(str).getDoubleValue("val"); + + assertEquals(val, val2); + } + } + + public void test_ran_4() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + double val = rand.nextDouble(); + + HashMap map = new HashMap(); + map.put("val", val); + String str = JSON.toJSONString(map); + double val2 = JSON.parseObject(str).getDoubleValue("val"); + + assertEquals(val, val2); + } + } + + public static class Model { + public double value; + + public Model() { + + } + + public Model(double value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/basicType/FloatTest3_array_random.java b/src/test/java/com/alibaba/json/bvt/basicType/FloatTest3_array_random.java new file mode 100644 index 0000000000..10741c06bb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/basicType/FloatTest3_array_random.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.basicType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Random; + +public class FloatTest3_array_random extends TestCase { + public void test_ran() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + float val = rand.nextFloat(); + + String str = JSON.toJSONString(new Model(new float[]{val})); + Model m = JSON.parseObject(str, Model.class); + + assertEquals(val, m.value[0]); + } + } + + public void test_ran_2() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 10; ++i) { + float val = rand.nextFloat(); + + String str = JSON.toJSONString(new Model(new float[]{val}), SerializerFeature.BeanToArray); + Model m = JSON.parseObject(str, Model.class, Feature.SupportArrayToBean); + + assertEquals(val, m.value[0]); + } + } + + public static class Model { + public float[] value; + + public Model() { + + } + + public Model(float[] value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/basicType/FloatTest3_random.java b/src/test/java/com/alibaba/json/bvt/basicType/FloatTest3_random.java new file mode 100644 index 0000000000..8eff86f37a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/basicType/FloatTest3_random.java @@ -0,0 +1,78 @@ +package com.alibaba.json.bvt.basicType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Random; + +public class FloatTest3_random extends TestCase { + public void test_ran() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + float val = rand.nextFloat(); + + String str = JSON.toJSONString(new Model(val)); + Model m = JSON.parseObject(str, Model.class); + + assertEquals(val, m.value); + } + } + + public void test_ran_2() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + float val = rand.nextFloat(); + + String str = JSON.toJSONString(new Model(val), SerializerFeature.BeanToArray); + Model m = JSON.parseObject(str, Model.class, Feature.SupportArrayToBean); + + assertEquals(val, m.value); + } + } + + public void test_ran_3() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + float val = rand.nextFloat(); + + String str = JSON.toJSONString(Collections.singletonMap("val", val)); + float val2 = JSON.parseObject(str).getFloatValue("val"); + + assertEquals(val, val2); + } + } + + public void test_ran_4() throws Exception { + Random rand = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1; ++i) { + float val = rand.nextFloat(); + + HashMap map = new HashMap(); + map.put("val", val); + String str = JSON.toJSONString(map); + float val2 = JSON.parseObject(str).getFloatValue("val"); + + assertEquals(val, val2); + } + } + + public static class Model { + public float value; + + public Model() { + + } + + public Model(float value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug11.java b/src/test/java/com/alibaba/json/bvt/bug/Bug11.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug13.java b/src/test/java/com/alibaba/json/bvt/bug/Bug13.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug14.java b/src/test/java/com/alibaba/json/bvt/bug/Bug14.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_10.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_10.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_102_for_rongganlin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_102_for_rongganlin.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_105_for_SpitFire.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_105_for_SpitFire.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_7.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_7.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_8.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_KimShen.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_KimShen.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_80108116.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_80108116.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ArrayMember.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ArrayMember.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Double2Tag.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Double2Tag.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Exception.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Exception.java old mode 100755 new mode 100644 index a062ca8be6..39c0379a28 --- a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Exception.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Exception.java @@ -4,12 +4,18 @@ import com.alibaba.fastjson.JSON; +import java.util.Map; + public class Bug_for_Exception extends TestCase { public void test_exception() throws Exception { RuntimeException ex = new RuntimeException("e1"); String text = JSON.toJSONString(ex); System.out.println(text); - - RuntimeException ex2 = (RuntimeException) JSON.parse(text); + + + Object obj = JSON.parse(text); + assertTrue(obj instanceof Map); + + RuntimeException ex2 = (RuntimeException) JSON.parseObject(text, Throwable.class); } } diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JSONObject.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JSONObject.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Johnny.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Johnny.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_NonStringKeyMap.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_NonStringKeyMap.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_O_I_See_you.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_O_I_See_you.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_4.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_5.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_alibank.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_alibank.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_array.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_array.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ascii_0_31.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ascii_0_31.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_bbl.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_bbl.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cduym.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cduym.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao_1.java new file mode 100644 index 0000000000..c9549fdaff --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao_1.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class Bug_for_chengchao_1 extends TestCase { + public void test_0() throws Exception { + ParserConfig config = new ParserConfig(); + config.setAutoTypeSupport(true); + String str = "{\"@type\":\"test.MapDone\",\"data\":{\"@type\":\"test.HiluxDataByOpsmeta\",\"attends\":{\"@type\":\"java.util.HashMap\",\"center.na61\":2},\"datasByOpsmeta\":{\"@type\":\"java.util.HashMap\",{\"@type\":\"test.AppInst\",\"app\":\"wdkhummer\",\"appGroup\":\"wdkhummerhost\",\"env\":\"PUBLISH\",\"hostname\":\"wdkhummer011009059229.na61\",\"idc\":\"na61\",\"ip\":\"11.9.59.229\",\"online\":true}:{\"@type\":\"test.MiddlewareDimData\",\"attends\":{\"@type\":\"java.util.HashMap\"},\"expectAttends\":{\"@type\":\"java.util.HashMap\"},\"logLineCount\":0,\"values\":{}}}}}"; + JSON.parse(str, config, JSON.DEFAULT_PARSER_FEATURE); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengyi.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengyi.java new file mode 100644 index 0000000000..567417dd49 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengyi.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.annotation.JSONCreator; +import junit.framework.TestCase; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +public class Bug_for_chengyi extends TestCase { + public void test_0() throws Exception { + List> pairList = new ArrayList(); + Pair pair = Pair.of("cy", 1); + pairList.add(pair); + + final String s = JSON.toJSONString(pairList); + final List pairs = JSONArray.parseArray(s, Pair.class); + System.out.println(); + } + + public static class Pair implements Serializable { + + private static final long serialVersionUID = -2140946024027818984L; + + public final A fst; + public final B snd; + + public Pair() { + fst = null; + snd = null; + } + + @JSONCreator + public Pair(A fst, B snd) { + this.fst = fst; + this.snd = snd; + } + + @Override + public String toString() { + return "[" + fst + "," + snd + "]"; + } + + private boolean equals(Object x, Object y) { + return (x == null && y == null) || (x != null && x.equals(y)); + } + + @SuppressWarnings("rawtypes") + @Override + public boolean equals(Object other) { + return other instanceof Pair && equals(fst, ((Pair) other).fst) + && equals(snd, ((Pair) other).snd); + } + + /** + * 覆盖hashCode方法 + * + * @return hashCode + */ + @Override + public int hashCode() { + if (fst == null) { + return (snd == null) ? 0 : snd.hashCode() + 1; + } else if (snd == null) { + return fst.hashCode() + 2; + } else { + return fst.hashCode() * 17 + snd.hashCode(); + } + } + + public static Pair of(A a, B b) { + return new Pair(a, b); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cnhans.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cnhans.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dargoner.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dargoner.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_divde_zero.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_divde_zero.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo_long.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo_long.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_field.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_field.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_franklee77.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_franklee77.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_hmy8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_hmy8.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huangchun.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huangchun.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huling.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huling.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jared1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jared1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_javaeye_litterJava.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_javaeye_litterJava.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jial10802.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jial10802.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinghui70.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinghui70.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinguwei.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinguwei.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_km.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_km.java new file mode 100644 index 0000000000..10a2021b81 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_km.java @@ -0,0 +1,129 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.concurrent.TimeUnit; + +public class Bug_for_km + extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\n" + + "\t\"bizSubmitInfos\": [{\n" + + "\t\t\"bizType\": \"ISSUE\",\n" + + "\t\t\"privacyInfo\": \"{\\\"bcAnchorMid\\\":\\\"101CITI000000001000\\\",\\\"bcMid\\\":\\\"102BABA000000000001\\\",\\\"bcSubmitMid\\\":\\\"102BABA000000000001\\\",\\\"bizId\\\":\\\"transfer_autoTest_pri_weiweitestt_8857136636875877184\\\",\\\"bizType\\\":\\\"ISSUE\\\",\\\"currency\\\":\\\"USD\\\",\\\"exchangeRate\\\":{\\\"encryptedExchangeRate\\\":\\\"123\\\",\\\"envelopeKeyInfos\\\":{}},\\\"pcAmount\\\":{\\\"envelopeKeyInfos\\\":{},\\\"proof\\\":\\\"proff\\\"}}\",\n" + + "\t\t\"submitInfoList\": [{\n" + + "\t\t\t\"checkPrivacyResult\": {\n" + + "\t\t\t\t\"checkResult\": \"{\\\"checkResultStatus\\\":\\\"ACCEPT\\\",\\\"hashOfPrivacyPreservingInfo\\\":\\\"NfYRZwG/Yki8LU01vsyWINGaXv94+gYoPBFVMFEKyTM=\\\",\\\"memberId\\\":\\\"101CITI000000001000\\\"}\",\n" + + "\t\t\t\t\"signature\": \"testing_signature\"\n" + + "\t\t\t},\n" + + "\t\t\t\"pid\": \"101CITI000000001000\"\n" + + "\t\t}]\n" + + "\t}],\n" + + "\t\"resultInfo\": {\n" + + "\t\t\"resultCode\": \"SUCCESS\",\n" + + "\t\t\"resultCodeId\": \"00000000\",\n" + + "\t\t\"resultMsg\": \"success\",\n" + + "\t\t\"resultStatus\": \"S\"\n" + + "\t}\n" + + "}"; + + WhaleGeneratePrivacyResponseBody resp = JSON.parseObject(str, WhaleGeneratePrivacyResponseBody.class); + System.out.println(resp.resultInfo.resultStatus); + +// System.out.println(str); + } + + + public static class WhaleGeneratePrivacyResponseBody { + public ResultInfo resultInfo; + } + + /** + * @author freud.wy + * @version $Id: ResultInfo.java, v 0.1 2019-05-28 上午11:02 freud.wy Exp $$ + */ + public static class ResultInfo { + private String resultStatus; + private String resultCodeId; + private String resultCode; + private String resultMsg; + + /** + * Getter method for property resultStatus. + * + * @return property value of resultStatus + */ + public String getResultStatus() { + return resultStatus; + } + + /** + * Setter method for property resultStatus. + * + * @param resultStatus value to be assigned to property resultStatus + */ + public void setResultStatus(String resultStatus) { + this.resultStatus = resultStatus; + } + + /** + * Getter method for property resultCodeId. + * + * @return property value of resultCodeId + */ + public String getResultCodeId() { + return resultCodeId; + } + + /** + * Setter method for property resultCodeId. + * + * @param resultCodeId value to be assigned to property resultCodeId + */ + public void setResultCodeId(String resultCodeId) { + this.resultCodeId = resultCodeId; + } + + /** + * Getter method for property resultCode. + * + * @return property value of resultCode + */ + public String getResultCode() { + return resultCode; + } + + /** + * Setter method for property resultCode. + * + * @param resultCode value to be assigned to property resultCode + */ + public void setResultCode(String resultCode) { + this.resultCode = resultCode; + } + + /** + * Getter method for property resultMsg. + * + * @return property value of resultMsg + */ + public String getResultMsg() { + return resultMsg; + } + + /** + * Setter method for property resultMsg. + * + * @param resultMsg value to be assigned to property resultMsg + */ + public void setResultMsg(String resultMsg) { + this.resultMsg = resultMsg; + } + + @Override + public String toString() { + return String.format("resultStatus[%s],resultCodeId[%s],resultCode[%s],resultMsg[%s]",resultStatus,resultCodeId,resultCode,resultMsg); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_10.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_10.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_11.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_11.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_4.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_5.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_5.java old mode 100755 new mode 100644 index a99b3317f1..5bc4c5bbb3 --- a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_5.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_5.java @@ -1,29 +1,27 @@ package com.alibaba.json.bvt.bug; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; -import junit.framework.TestCase; - import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + public class Bug_for_lenolix_5 extends TestCase { - public void test_for_objectKey() throws Exception { - Map obj = new HashMap(); - Object obja = new Object(); - Object objb = new Object(); - obj.put(obja, objb); + public void test_for_objectKey() throws Exception { + final Map obj = new HashMap(); + final Object obja = new Object(); + final Object objb = new Object(); + obj.put(obja, objb); - String newJsonString = JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, - SerializerFeature.WriteClassName); - System.out.println(newJsonString); + final String newJsonString = JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, + SerializerFeature.WriteClassName); + System.out.println(newJsonString); - Object newObject = JSON.parse(newJsonString); + final Object newObject = JSON.parse(newJsonString); - System.out.println(newObject); - } + System.out.println(newObject); + } } diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_7.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_7.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_8.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_9.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_9.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_liqing.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_liqing.java new file mode 100644 index 0000000000..d5a4397969 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_liqing.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class Bug_for_liqing extends TestCase { + public void test_for_issue() throws Exception { + ParserConfig config = new ParserConfig(); + config.setAutoTypeSupport(true); + String json = "{\"@type\":\"java.util.HashMap\",\"wcChangeAttr\":{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_liqing.TpFeedBackDO\",\"attributes\":{\"@type\":\"java.util.concurrent.ConcurrentHashMap\"},\"wcStatus\":102B}}"; + JSON.parse(json, config); + } + + public static class TpFeedBackDO { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_liuwanzhen_ren.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_liuwanzhen_ren.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_maiksagill.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_maiksagill.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_melin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_melin.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qianbi.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qianbi.java new file mode 100644 index 0000000000..f9f6b40a42 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qianbi.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Bug_for_qianbi extends TestCase { + public void test_for_bug() throws Exception { + String json = "\n" + + "[{\"a\":\"1A18810QBYZN5T3M3CH6K3\",\"r\":[\"44304\",\"103467\"]},{\"a\":\"1A188104CTUW5TXFGCJPDW\",\"r\":[\"24391\",\"56132\",\"44304\",\"15567\"]},{\"a\":\"1A18812GJ9P37TOGKPT8BQ\",\"r\":[\"24539\",\"44304\",\"56259\"]} ,{\"a\":\"1A188104CTUW5TXFGCJPDW\",\"r\":[\"24391\",\"44304\",\"15567\"]}]"; + + JSON.parse(json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qqdwll2012.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qqdwll2012.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rd.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rd.java new file mode 100644 index 0000000000..27a5b89cd9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rd.java @@ -0,0 +1,94 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.concurrent.TimeUnit; + +public class Bug_for_rd extends TestCase { + public void test_for_issue() throws Exception { + String json = "{ \"sitePayId\": \"2019071889031100000152604119889\", \"extendInfo\": \"{\\\"saveAsset\\\":\\\"false\\\",\\\"acquirementId\\\":\\\"20190718194010800100177150204979354\\\",\\\"orderTerminalType\\\":\\\"WEB\\\",\\\"acqSiteUserId\\\":\\\"2177220032166157\\\",\\\"siteReqBizId\\\":\\\"111023437\\\",\\\"msisdn\\\":\\\"01966114400\\\",\\\"originalMerchantOrderId\\\":\\\"602109378031994\\\"}\", \"netPayId\": \"2019071819039101720000454701\", \"resultInfo\": { \"resultCode\": \"SUCCESS\", \"resultCodeId\": \"00000000\", \"resultMsg\": \"Success\", \"resultStatus\": \"S\" } }"; + PayResponse object = JSON.parseObject(json, PayResponse.class); + String extendInfo = object.getExtendInfo(); + + assertEquals(object.getExtendInfo(), JSON.parseObject(json).get("extendInfo")); + } + + public void test_for_issue_1() throws Exception { + String json = "{\"unit\": \"MINUTES\"}"; + V1 v = JSON.parseObject(json, V1.class); + assertEquals(TimeUnit.MINUTES, v.unit); + } + + public void test_for_issue_2() throws Exception { + String json = "{\"sitePayId\": \"MINUTES\"}"; + V1 v = JSON.parseObject(json, V1.class); + assertEquals("MINUTES", v.sitePayId); + } + + public void test_for_issue_3() throws Exception { + String json = "{\"sitePayId\": \"MINUTES\\\"A\"}"; + V1 v = JSON.parseObject(json, V1.class); + assertEquals("MINUTES\"A", v.sitePayId); + } + + public void test_for_issue_4() throws Exception { + String json = "{ \"sitePayId\": \"MINUTES\\\"A\"}"; + V1 v = JSON.parseObject(json, V1.class); + assertEquals("MINUTES\"A", v.sitePayId); + } + + public void test_for_issue_5() throws Exception { + String json = "{ \"sitePayId\": \"\\\"A\"}"; + V1 v = JSON.parseObject(json, V1.class); + assertEquals("\"A", v.sitePayId); + } + + public void test_for_issue_6() throws Exception { + String json = "{ \"sitePayId\": \"S\"}"; + V1 v = JSON.parseObject(json, V1.class); + assertEquals("S", v.sitePayId); + } + + public static class PayResponse { + private String sitePayId; + private String extendInfo; + private String netPayId; + + public String getSitePayId() + { + return sitePayId; + } + + public void setSitePayId(String sitePayId) + { + this.sitePayId = sitePayId; + } + + public String getExtendInfo() + { + return extendInfo; + } + + public void setExtendInfo(String extendInfo) + { + this.extendInfo = extendInfo; + } + + public String getNetPayId() + { + return netPayId; + } + + public void setNetPayId(String netPayId) + { + this.netPayId = netPayId; + } + } + + public static class V1 { + public String sitePayId; + public TimeUnit unit; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rendong.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rendong.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_set.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_set.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat4.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat5.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat6.java old mode 100755 new mode 100644 index 4ecc92d25b..3adbf208da --- a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat6.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat6.java @@ -1,6 +1,6 @@ package com.alibaba.json.bvt.bug; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.junit.Assert; @@ -12,7 +12,7 @@ public class Bug_for_smoothrat6 extends TestCase { public void test_set() throws Exception { - Set set = new HashSet(); + Set set = new LinkedHashSet(); set.add(3L); set.add(4L); diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat7.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat7.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat8.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat9.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat9.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_stv_liu.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_stv_liu.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_taolei0628.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_taolei0628.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_typeReference.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_typeReference.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_uin57.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_uin57.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_vikingschow.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_vikingschow.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wtusmchen.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wtusmchen.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuyexiong.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuyexiong.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuzhengmao.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuzhengmao.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiayucai2012.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiayucai2012.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiedun.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiedun.java new file mode 100644 index 0000000000..3ef0bc2fab --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiedun.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; + +public class Bug_for_xiedun extends TestCase { + public void test_for_issue() throws Exception { +// File file = new File("/Users/wenshao/Downloads/json.txt"); +// +// BufferedReader reader = new BufferedReader(new FileReader(file)); +// char[] buf = new char[20480]; +// int readed = reader.read(buf); +// String content = new String(buf); +// +// JSON.parse(content); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yangzhou.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yangzhou.java new file mode 100644 index 0000000000..8389e1cd0f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yangzhou.java @@ -0,0 +1,1143 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class Bug_for_yangzhou extends TestCase { + public void test_for_issue() throws Exception { + String test = "{\"distinct\":false,\"oredCriteria\":[{\"allCriteria\":[{\"betweenValue\":false,\"condition\":\"area_id =\",\"listValue\":false,\"noValue\":false,\"singleValue\":true,\"value\":917477670000000000},{\"betweenValue\":false,\"condition\":\"cabinet_id =\",\"listValue\":false,\"noValue\":false,\"singleValue\":true,\"value\":500036},{\"betweenValue\":false,\"condition\":\"status =\",\"listValue\":false,\"noValue\":false,\"singleValue\":true,\"value\":0}],\"criteria\":[{\"$ref\":\"$.oredCriteria[0].allCriteria[0]\"},{\"$ref\":\"$.oredCriteria[0].allCriteria[1]\"},{\"$ref\":\"$.oredCriteria[0].allCriteria[2]\"}],\"valid\":true}],\"page\":true,\"pageIndex\":0,\"pageSize\":1,\"pageStart\":1}"; + + System.out.println(test); + CabinetAuthCodeParam cabinetAuthCodeParam = JSONObject.toJavaObject(JSON.parseObject(test), CabinetAuthCodeParam.class); + System.out.println(JSON.toJSONString(cabinetAuthCodeParam)); + final String jsonString = JSON.toJSONString(cabinetAuthCodeParam); + assertEquals("{\"distinct\":false,\"oredCriteria\":[{\"allCriteria\":[{\"listValue\":false,\"noValue\":false,\"condition\":\"area_id =\",\"betweenValue\":false,\"singleValue\":true,\"value\":917477670000000000},{\"listValue\":false,\"noValue\":false,\"condition\":\"cabinet_id =\",\"betweenValue\":false,\"singleValue\":true,\"value\":500036},{\"listValue\":false,\"noValue\":false,\"condition\":\"status =\",\"betweenValue\":false,\"singleValue\":true,\"value\":0}],\"criteria\":[{\"$ref\":\"$.oredCriteria[0].allCriteria[0]\"},{\"$ref\":\"$.oredCriteria[0].allCriteria[1]\"},{\"$ref\":\"$.oredCriteria[0].allCriteria[2]\"}],\"valid\":true}],\"page\":true,\"pageIndex\":0,\"pageSize\":1,\"pageStart\":1}", jsonString); +// CabinetAuthCodeRecordParam cabinetAuthCodeRecordParam = JSONObject.toJavaObject(JSON.parseObject(jsonString), CabinetAuthCodeRecordParam.class); +// System.out.println(JSON.toJSONString(cabinetAuthCodeRecordParam)); + } + + public static class CabinetAuthCodeParam { + protected String orderByClause; + + protected boolean distinct; + + protected boolean page; + + protected int pageIndex; + + protected int pageSize; + + protected int pageStart; + + protected List oredCriteria; + + public CabinetAuthCodeParam() { + oredCriteria = new ArrayList(); + } + + public CabinetAuthCodeParam appendOrderByClause(OrderCondition orderCondition, SortType sortType) { + if (null != orderByClause) { + orderByClause = orderByClause + ", " + orderCondition.getColumnName() + " " + sortType.getValue(); + } else { + orderByClause = orderCondition.getColumnName() + " " + sortType.getValue(); + } + return this; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public void setPage(boolean page) { + this.page = page; + } + + public boolean isPage() { + return page; + } + + public int getPageIndex() { + return pageIndex; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize < 1 ? 10 : pageSize; + this.pageIndex = pageStart < 1 ? 0 : (pageStart - 1) * this.pageSize; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageStart(int pageStart) { + this.pageStart = pageStart < 1 ? 1 : pageStart; + this.pageIndex = (this.pageStart - 1) * this.pageSize; + } + + public int getPageStart() { + return pageStart; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andIdIsNull() { + addCriterion("id is null"); + return (Criteria) this; + } + + public Criteria andIdIsNotNull() { + addCriterion("id is not null"); + return (Criteria) this; + } + + public Criteria andIdEqualTo(Long value) { + addCriterion("id =", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotEqualTo(Long value) { + addCriterion("id <>", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThan(Long value) { + addCriterion("id >", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThanOrEqualTo(Long value) { + addCriterion("id >=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThan(Long value) { + addCriterion("id <", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThanOrEqualTo(Long value) { + addCriterion("id <=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdIn(List values) { + addCriterion("id in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdNotIn(List values) { + addCriterion("id not in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdBetween(Long value1, Long value2) { + addCriterion("id between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andIdNotBetween(Long value1, Long value2) { + addCriterion("id not between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andGmtCreateIsNull() { + addCriterion("gmt_create is null"); + return (Criteria) this; + } + + public Criteria andGmtCreateIsNotNull() { + addCriterion("gmt_create is not null"); + return (Criteria) this; + } + + public Criteria andGmtCreateEqualTo(Date value) { + addCriterion("gmt_create =", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateNotEqualTo(Date value) { + addCriterion("gmt_create <>", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateGreaterThan(Date value) { + addCriterion("gmt_create >", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateGreaterThanOrEqualTo(Date value) { + addCriterion("gmt_create >=", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateLessThan(Date value) { + addCriterion("gmt_create <", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateLessThanOrEqualTo(Date value) { + addCriterion("gmt_create <=", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateIn(List values) { + addCriterion("gmt_create in", values, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateNotIn(List values) { + addCriterion("gmt_create not in", values, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateBetween(Date value1, Date value2) { + addCriterion("gmt_create between", value1, value2, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateNotBetween(Date value1, Date value2) { + addCriterion("gmt_create not between", value1, value2, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtModifiedIsNull() { + addCriterion("gmt_modified is null"); + return (Criteria) this; + } + + public Criteria andGmtModifiedIsNotNull() { + addCriterion("gmt_modified is not null"); + return (Criteria) this; + } + + public Criteria andGmtModifiedEqualTo(Date value) { + addCriterion("gmt_modified =", value, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedNotEqualTo(Date value) { + addCriterion("gmt_modified <>", value, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedGreaterThan(Date value) { + addCriterion("gmt_modified >", value, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedGreaterThanOrEqualTo(Date value) { + addCriterion("gmt_modified >=", value, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedLessThan(Date value) { + addCriterion("gmt_modified <", value, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedLessThanOrEqualTo(Date value) { + addCriterion("gmt_modified <=", value, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedIn(List values) { + addCriterion("gmt_modified in", values, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedNotIn(List values) { + addCriterion("gmt_modified not in", values, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedBetween(Date value1, Date value2) { + addCriterion("gmt_modified between", value1, value2, "gmtModified"); + return (Criteria) this; + } + + public Criteria andGmtModifiedNotBetween(Date value1, Date value2) { + addCriterion("gmt_modified not between", value1, value2, "gmtModified"); + return (Criteria) this; + } + + public Criteria andAreaIdIsNull() { + addCriterion("area_id is null"); + return (Criteria) this; + } + + public Criteria andAreaIdIsNotNull() { + addCriterion("area_id is not null"); + return (Criteria) this; + } + + public Criteria andAreaIdEqualTo(Long value) { + addCriterion("area_id =", value, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdNotEqualTo(Long value) { + addCriterion("area_id <>", value, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdGreaterThan(Long value) { + addCriterion("area_id >", value, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdGreaterThanOrEqualTo(Long value) { + addCriterion("area_id >=", value, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdLessThan(Long value) { + addCriterion("area_id <", value, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdLessThanOrEqualTo(Long value) { + addCriterion("area_id <=", value, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdIn(List values) { + addCriterion("area_id in", values, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdNotIn(List values) { + addCriterion("area_id not in", values, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdBetween(Long value1, Long value2) { + addCriterion("area_id between", value1, value2, "areaId"); + return (Criteria) this; + } + + public Criteria andAreaIdNotBetween(Long value1, Long value2) { + addCriterion("area_id not between", value1, value2, "areaId"); + return (Criteria) this; + } + + public Criteria andAuthCodeIsNull() { + addCriterion("auth_code is null"); + return (Criteria) this; + } + + public Criteria andAuthCodeIsNotNull() { + addCriterion("auth_code is not null"); + return (Criteria) this; + } + + public Criteria andAuthCodeEqualTo(String value) { + addCriterion("auth_code =", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeNotEqualTo(String value) { + addCriterion("auth_code <>", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeGreaterThan(String value) { + addCriterion("auth_code >", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeGreaterThanOrEqualTo(String value) { + addCriterion("auth_code >=", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeLessThan(String value) { + addCriterion("auth_code <", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeLessThanOrEqualTo(String value) { + addCriterion("auth_code <=", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeLike(String value) { + addCriterion("auth_code like", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeNotLike(String value) { + addCriterion("auth_code not like", value, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeIn(List values) { + addCriterion("auth_code in", values, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeNotIn(List values) { + addCriterion("auth_code not in", values, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeBetween(String value1, String value2) { + addCriterion("auth_code between", value1, value2, "authCode"); + return (Criteria) this; + } + + public Criteria andAuthCodeNotBetween(String value1, String value2) { + addCriterion("auth_code not between", value1, value2, "authCode"); + return (Criteria) this; + } + + public Criteria andCabinetIdIsNull() { + addCriterion("cabinet_id is null"); + return (Criteria) this; + } + + public Criteria andCabinetIdIsNotNull() { + addCriterion("cabinet_id is not null"); + return (Criteria) this; + } + + public Criteria andCabinetIdEqualTo(Long value) { + addCriterion("cabinet_id =", value, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdNotEqualTo(Long value) { + addCriterion("cabinet_id <>", value, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdGreaterThan(Long value) { + addCriterion("cabinet_id >", value, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdGreaterThanOrEqualTo(Long value) { + addCriterion("cabinet_id >=", value, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdLessThan(Long value) { + addCriterion("cabinet_id <", value, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdLessThanOrEqualTo(Long value) { + addCriterion("cabinet_id <=", value, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdIn(List values) { + addCriterion("cabinet_id in", values, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdNotIn(List values) { + addCriterion("cabinet_id not in", values, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdBetween(Long value1, Long value2) { + addCriterion("cabinet_id between", value1, value2, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetIdNotBetween(Long value1, Long value2) { + addCriterion("cabinet_id not between", value1, value2, "cabinetId"); + return (Criteria) this; + } + + public Criteria andCabinetNoIsNull() { + addCriterion("cabinet_no is null"); + return (Criteria) this; + } + + public Criteria andCabinetNoIsNotNull() { + addCriterion("cabinet_no is not null"); + return (Criteria) this; + } + + public Criteria andCabinetNoEqualTo(String value) { + addCriterion("cabinet_no =", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoNotEqualTo(String value) { + addCriterion("cabinet_no <>", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoGreaterThan(String value) { + addCriterion("cabinet_no >", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoGreaterThanOrEqualTo(String value) { + addCriterion("cabinet_no >=", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoLessThan(String value) { + addCriterion("cabinet_no <", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoLessThanOrEqualTo(String value) { + addCriterion("cabinet_no <=", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoLike(String value) { + addCriterion("cabinet_no like", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoNotLike(String value) { + addCriterion("cabinet_no not like", value, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoIn(List values) { + addCriterion("cabinet_no in", values, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoNotIn(List values) { + addCriterion("cabinet_no not in", values, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoBetween(String value1, String value2) { + addCriterion("cabinet_no between", value1, value2, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andCabinetNoNotBetween(String value1, String value2) { + addCriterion("cabinet_no not between", value1, value2, "cabinetNo"); + return (Criteria) this; + } + + public Criteria andStatusIsNull() { + addCriterion("status is null"); + return (Criteria) this; + } + + public Criteria andStatusIsNotNull() { + addCriterion("status is not null"); + return (Criteria) this; + } + + public Criteria andStatusEqualTo(Short value) { + addCriterion("status =", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotEqualTo(Short value) { + addCriterion("status <>", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusGreaterThan(Short value) { + addCriterion("status >", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusGreaterThanOrEqualTo(Short value) { + addCriterion("status >=", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusLessThan(Short value) { + addCriterion("status <", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusLessThanOrEqualTo(Short value) { + addCriterion("status <=", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusIn(List values) { + addCriterion("status in", values, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotIn(List values) { + addCriterion("status not in", values, "status"); + return (Criteria) this; + } + + public Criteria andStatusBetween(Short value1, Short value2) { + addCriterion("status between", value1, value2, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotBetween(Short value1, Short value2) { + addCriterion("status not between", value1, value2, "status"); + return (Criteria) this; + } + + public Criteria andAssignTimeIsNull() { + addCriterion("assign_time is null"); + return (Criteria) this; + } + + public Criteria andAssignTimeIsNotNull() { + addCriterion("assign_time is not null"); + return (Criteria) this; + } + + public Criteria andAssignTimeEqualTo(Date value) { + addCriterion("assign_time =", value, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeNotEqualTo(Date value) { + addCriterion("assign_time <>", value, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeGreaterThan(Date value) { + addCriterion("assign_time >", value, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeGreaterThanOrEqualTo(Date value) { + addCriterion("assign_time >=", value, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeLessThan(Date value) { + addCriterion("assign_time <", value, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeLessThanOrEqualTo(Date value) { + addCriterion("assign_time <=", value, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeIn(List values) { + addCriterion("assign_time in", values, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeNotIn(List values) { + addCriterion("assign_time not in", values, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeBetween(Date value1, Date value2) { + addCriterion("assign_time between", value1, value2, "assignTime"); + return (Criteria) this; + } + + public Criteria andAssignTimeNotBetween(Date value1, Date value2) { + addCriterion("assign_time not between", value1, value2, "assignTime"); + return (Criteria) this; + } + + public Criteria andUseTimeIsNull() { + addCriterion("use_time is null"); + return (Criteria) this; + } + + public Criteria andUseTimeIsNotNull() { + addCriterion("use_time is not null"); + return (Criteria) this; + } + + public Criteria andUseTimeEqualTo(Date value) { + addCriterion("use_time =", value, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeNotEqualTo(Date value) { + addCriterion("use_time <>", value, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeGreaterThan(Date value) { + addCriterion("use_time >", value, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeGreaterThanOrEqualTo(Date value) { + addCriterion("use_time >=", value, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeLessThan(Date value) { + addCriterion("use_time <", value, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeLessThanOrEqualTo(Date value) { + addCriterion("use_time <=", value, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeIn(List values) { + addCriterion("use_time in", values, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeNotIn(List values) { + addCriterion("use_time not in", values, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeBetween(Date value1, Date value2) { + addCriterion("use_time between", value1, value2, "useTime"); + return (Criteria) this; + } + + public Criteria andUseTimeNotBetween(Date value1, Date value2) { + addCriterion("use_time not between", value1, value2, "useTime"); + return (Criteria) this; + } + + public Criteria andBizTypeIsNull() { + addCriterion("biz_type is null"); + return (Criteria) this; + } + + public Criteria andBizTypeIsNotNull() { + addCriterion("biz_type is not null"); + return (Criteria) this; + } + + public Criteria andBizTypeEqualTo(Short value) { + addCriterion("biz_type =", value, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeNotEqualTo(Short value) { + addCriterion("biz_type <>", value, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeGreaterThan(Short value) { + addCriterion("biz_type >", value, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeGreaterThanOrEqualTo(Short value) { + addCriterion("biz_type >=", value, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeLessThan(Short value) { + addCriterion("biz_type <", value, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeLessThanOrEqualTo(Short value) { + addCriterion("biz_type <=", value, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeIn(List values) { + addCriterion("biz_type in", values, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeNotIn(List values) { + addCriterion("biz_type not in", values, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeBetween(Short value1, Short value2) { + addCriterion("biz_type between", value1, value2, "bizType"); + return (Criteria) this; + } + + public Criteria andBizTypeNotBetween(Short value1, Short value2) { + addCriterion("biz_type not between", value1, value2, "bizType"); + return (Criteria) this; + } + + public Criteria andBizOutIdIsNull() { + addCriterion("biz_out_id is null"); + return (Criteria) this; + } + + public Criteria andBizOutIdIsNotNull() { + addCriterion("biz_out_id is not null"); + return (Criteria) this; + } + + public Criteria andBizOutIdEqualTo(Long value) { + addCriterion("biz_out_id =", value, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdNotEqualTo(Long value) { + addCriterion("biz_out_id <>", value, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdGreaterThan(Long value) { + addCriterion("biz_out_id >", value, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdGreaterThanOrEqualTo(Long value) { + addCriterion("biz_out_id >=", value, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdLessThan(Long value) { + addCriterion("biz_out_id <", value, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdLessThanOrEqualTo(Long value) { + addCriterion("biz_out_id <=", value, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdIn(List values) { + addCriterion("biz_out_id in", values, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdNotIn(List values) { + addCriterion("biz_out_id not in", values, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdBetween(Long value1, Long value2) { + addCriterion("biz_out_id between", value1, value2, "bizOutId"); + return (Criteria) this; + } + + public Criteria andBizOutIdNotBetween(Long value1, Long value2) { + addCriterion("biz_out_id not between", value1, value2, "bizOutId"); + return (Criteria) this; + } + + public Criteria andFeatureIsNull() { + addCriterion("feature is null"); + return (Criteria) this; + } + + public Criteria andFeatureIsNotNull() { + addCriterion("feature is not null"); + return (Criteria) this; + } + + public Criteria andFeatureEqualTo(String value) { + addCriterion("feature =", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureNotEqualTo(String value) { + addCriterion("feature <>", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureGreaterThan(String value) { + addCriterion("feature >", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureGreaterThanOrEqualTo(String value) { + addCriterion("feature >=", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureLessThan(String value) { + addCriterion("feature <", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureLessThanOrEqualTo(String value) { + addCriterion("feature <=", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureLike(String value) { + addCriterion("feature like", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureNotLike(String value) { + addCriterion("feature not like", value, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureIn(List values) { + addCriterion("feature in", values, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureNotIn(List values) { + addCriterion("feature not in", values, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureBetween(String value1, String value2) { + addCriterion("feature between", value1, value2, "feature"); + return (Criteria) this; + } + + public Criteria andFeatureNotBetween(String value1, String value2) { + addCriterion("feature not between", value1, value2, "feature"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } + + public enum OrderCondition { + ID("id"), + GMTCREATE("gmt_create"), + GMTMODIFIED("gmt_modified"), + AREAID("area_id"), + AUTHCODE("auth_code"), + CABINETID("cabinet_id"), + CABINETNO("cabinet_no"), + STATUS("status"), + ASSIGNTIME("assign_time"), + USETIME("use_time"), + BIZTYPE("biz_type"), + BIZOUTID("biz_out_id"), + FEATURE("feature"); + + private String columnName; + + OrderCondition(String columnName) { + this.columnName = columnName; + } + + public String getColumnName() { + return columnName; + } + + public static OrderCondition getEnumByName(String name) { + OrderCondition[] orderConditions = OrderCondition.values(); + for (OrderCondition orderCondition : orderConditions) { + if (orderCondition.name().equalsIgnoreCase(name)) { + return orderCondition; + } + } + throw new RuntimeException("OrderCondition of " + name + " enum not exist"); + } + + @Override + public String toString() { + return columnName; + } + } + + public enum SortType { + ASC("asc"), + DESC("desc"); + + private String value; + + SortType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static SortType getEnumByName(String name) { + SortType[] sortTypes = SortType.values(); + for (SortType sortType : sortTypes) { + if (sortType.name().equalsIgnoreCase(name)) { + return sortType; + } + } + throw new RuntimeException("SortType of " + name + " enum not exist"); + } + + @Override + public String toString() { + return value; + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yannywang.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yannywang.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yunban.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yunban.java new file mode 100644 index 0000000000..3af9cb7a20 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yunban.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class Bug_for_yunban extends TestCase { + public void test_for_issue() throws Exception { + List relationItemList = new LinkedList(); + + Map ext = new HashMap(); + ext.put("a", "b"); + ext.put("c", "d"); + + + RelationItem relationItem = new RelationItem(); + relationItem.setExt(ext); + relationItem.setSourceId("12"); + relationItemList.add(relationItem); + + relationItem = new RelationItem(); + relationItem.setExt(ext); + relationItem.setSourceId("55"); + relationItemList.add(relationItem); + + //ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + //String a = JSON.toJSONString(relationItemList, SerializerFeature.WriteClassName); + String a1 = JSON.toJSONString(relationItemList); + System.out.println(a1); + + + //ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + List relationItemList1 = JSON.parseObject(a1, new com.alibaba.fastjson.TypeReference>(){}); + + System.out.print("fdafda"); + } + + public static class RelationItem { + private String sourceId; + private Map ext; + + public String getSourceId() { + return sourceId; + } + + public void setSourceId(String sourceId) { + this.sourceId = sourceId; + } + + public Map getExt() { + return ext; + } + + public void setExt(Map ext) { + this.ext = ext; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhaoyao.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhaoyao.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuangzaowen.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuangzaowen.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuel.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuel.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue248_orderedField.java b/src/test/java/com/alibaba/json/bvt/bug/Issue248_orderedField.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue569_1.java b/src/test/java/com/alibaba/json/bvt/bug/Issue569_1.java new file mode 100644 index 0000000000..5c7fa0bd65 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue569_1.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import junit.framework.TestCase; + +public class Issue569_1 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\"result\":{}}"; + InterfaceResult result = JSON.parseObject(json, new TypeReference>() {}); + assertNotNull(result.getResult()); + assertEquals(Value.class, result.getResult().getClass()); + } + + public static class BaseInterfaceResult { + + } + + public static class InterfaceResult extends BaseInterfaceResult + { + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } + + private T result; + } + + public static class Value { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue978.java b/src/test/java/com/alibaba/json/bvt/bug/Issue978.java index bd1750eddc..5b1420190c 100644 --- a/src/test/java/com/alibaba/json/bvt/bug/Issue978.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue978.java @@ -6,14 +6,29 @@ import junit.framework.TestCase; import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; /** * Created by wenshao on 10/01/2017. */ public class Issue978 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + public void test_for_issue() throws Exception { Model model = new Model(); - model.date = new Date(1483413683714L); + model.date = new java.util.Date(1483413683714L); + + JSONObject obj = (JSONObject) JSON.toJSON(model); + assertEquals("{\"date\":\"2017-01-03 11:21:23\"}", obj.toJSONString()); + } + + public void test_for_issue2() throws Exception { + Model model = new Model(); + model.date = new java.sql.Date(1483413683714L); JSONObject obj = (JSONObject) JSON.toJSON(model); assertEquals("{\"date\":\"2017-01-03 11:21:23\"}", obj.toJSONString()); diff --git a/src/test/java/com/alibaba/json/bvt/bug/JSONTest.java b/src/test/java/com/alibaba/json/bvt/bug/JSONTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/SerDeserTest.java b/src/test/java/com/alibaba/json/bvt/bug/SerDeserTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest.java b/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest2.java b/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/TestDouble.java b/src/test/java/com/alibaba/json/bvt/bug/TestDouble.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/TestJSONMap.java b/src/test/java/com/alibaba/json/bvt/bug/TestJSONMap.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug201806/Bug_for_weiqiang.java b/src/test/java/com/alibaba/json/bvt/bug/bug201806/Bug_for_weiqiang.java new file mode 100644 index 0000000000..7072931e85 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/bug201806/Bug_for_weiqiang.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.bug.bug201806; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Bug_for_weiqiang extends TestCase { + public void test_for_bug() throws Exception { + SerializeWriter sw = new SerializeWriter(); + sw.config(SerializerFeature.WriteNullStringAsEmpty, Boolean.TRUE); + JSONSerializer js = new JSONSerializer(sw); + js.write(JSON.parseObject("{'operator':null, 'status':1}")); + System.out.println(js); + + String json2 = JSON.toJSONString(JSON.parseObject("{'operator':null, 'status':1}"), SerializerFeature.WriteNullStringAsEmpty); + System.out.println(json2); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug201810/LatLngTest.java b/src/test/java/com/alibaba/json/bvt/bug/bug201810/LatLngTest.java new file mode 100644 index 0000000000..0a0a542a6d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/bug201810/LatLngTest.java @@ -0,0 +1,87 @@ +package com.alibaba.json.bvt.bug.bug201810; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +public class LatLngTest extends TestCase { + public void test_latlng() throws Exception { + LatLng v = new LatLng(); + JSON.toJSONString(v); + } + + public static class LatLng implements Serializable { + /** + * serialVersionUID + */ + private static final long serialVersionUID = -9176496417369601807L; + + public LatLng() {} + + public LatLng(Double lat, Double lng) { + this.lat = lat; + this.lng = lng; + } + + /** + * 纬度 + */ + @Min(-90) + @Max(90) + @NotNull + private Double lat; + /** + * 经度 + */ + @Min(-180) + @Max(180) + @NotNull + private Double lng; + + /** + * Getter method for property lat. + * + * @return property value of lat + */ + public Double getLat() { + return lat; + } + + /** + * Setter method for property lat. + * + * @param lat value to be assigned to property lat + */ + public void setLat(Double lat) { + this.lat = lat; + } + + /** + * Getter method for property lng. + * + * @return property value of lng + */ + public Double getLng() { + return lng; + } + + /** + * Setter method for property lng. + * + * @param lng value to be assigned to property lng + */ + public void setLng(Double lng) { + this.lng = lng; + } + + @Override + public String toString() { + return lat + " " + lng; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug2019/Bug20190729_01.java b/src/test/java/com/alibaba/json/bvt/bug/bug2019/Bug20190729_01.java new file mode 100644 index 0000000000..999e5e2983 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/bug2019/Bug20190729_01.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.bug.bug2019; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Bug20190729_01 extends TestCase +{ + public void test_for_issue() throws Exception { + JSONObject object = new JSONObject(); + object.put("bucketId", 123); + + JSON.toJavaObject(object, BucketInfo.class); + } + + public static class BucketInfo { + private Integer bucketId; + + public Integer getBucketId() { + return bucketId; + } + + public void setBucketId(int bucketId) { + this.bucketId = bucketId; + } + } +} + diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug2020/Bug_for_emptyList.java b/src/test/java/com/alibaba/json/bvt/bug/bug2020/Bug_for_emptyList.java new file mode 100644 index 0000000000..340d63fba4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/bug2020/Bug_for_emptyList.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.bug.bug2020; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class Bug_for_emptyList extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"values\":[1,2,3],\"map\":{\"a\":1},\"keys\":[1,2,3],}"; + VO vo = JSON.parseObject(str, VO.class); + assertEquals(3, vo.values.size()); + assertEquals(1, vo.map.size()); + assertEquals(3, vo.keys.size()); + } + + public static class VO { + private java.util.List values = kotlin.collections.CollectionsKt.emptyList(); + private java.util.Set keys = kotlin.collections.SetsKt.emptySet(); + private java.util.Map map = kotlin.collections.MapsKt.emptyMap(); + + public List getValues() + { + return values; + } + + public Map getMap() { + return map; + } + + public Set getKeys() { + return keys; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug2020/Bug_for_money.java b/src/test/java/com/alibaba/json/bvt/bug/bug2020/Bug_for_money.java new file mode 100644 index 0000000000..e9757a316c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/bug2020/Bug_for_money.java @@ -0,0 +1,127 @@ +package com.alibaba.json.bvt.bug.bug2020; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Currency; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Bug_for_money extends TestCase { + public void test_for_issue() throws Exception { + JSONObject obj = JSON.parseObject( + "{\"productMaxPriceAmt\":{\"amount\":4.99,\"centFactor\":100,\"cent\":499,\"currency\":\"USD\"," + + "\"currencyCode\":\"USD\"}}"); + Money money = obj.getObject("productMaxPriceAmt", Money.class); + assertEquals("USD", money.getCurrencyCode()); + assertEquals(new BigDecimal("4.99"), money.getAmount()); + } + + public static class Money implements Serializable, Comparable { + + private static final long serialVersionUID = 6009335074727417445L; + + public static final String DEFAULT_CURRENCY_CODE = "CNY"; + + public static final int DEFAULT_ROUNDING_MODE = BigDecimal.ROUND_HALF_EVEN; + + private static final int[] centFactors = new int[] { 1, 10, 100, 1000 }; + + private long cent; + + private Currency currency; + + private String currencyCode; + + public Money() { + this(0); + } + + private Money(double amount) { + this(amount, Currency.getInstance(DEFAULT_CURRENCY_CODE)); + } + + + public Money(double amount, Currency currency) { + this.currency = currency; + this.cent = Math.round(amount * getCentFactor()); + } + + public BigDecimal getAmount() { + return BigDecimal.valueOf(cent, currency.getDefaultFractionDigits()); + } + + + public long getCent() { + return cent; + } + + + public Currency getCurrency() { + return currency; + } + + + public int getCentFactor() { + return centFactors[currency.getDefaultFractionDigits()]; + } + + + public boolean equals(Object other) { + return (other instanceof Money) && equals((Money) other); + } + + public boolean equals(Money other) { + return currency.equals(other.currency) && (cent == other.cent); + } + + public int hashCode() { + return (int) (cent ^ (cent >>> 32)); + } + + public int compareTo(Object other) { + return compareTo((Money) other); + } + + public int compareTo(Money other) { + assertSameCurrencyAs(other); + + if (cent < other.cent) { + return -1; + } else if (cent == other.cent) { + return 0; + } else { + return 1; + } + } + + public String toString() { + return getAmount().toString(); + } + + protected void assertSameCurrencyAs(Money other) { + if (!currency.equals(other.currency)) { + throw new IllegalArgumentException("Money math currency mismatch."); + } + } + + public void setCent(long l) { + cent = l; + } + + public void setCurrencyCode(String currencyCode) { + if (currencyCode != null && !currencyCode.isEmpty()) { + this.currencyCode = currencyCode; + currency = Currency.getInstance(currencyCode); + } + } + + public String getCurrencyCode() { + currencyCode = currency.getCurrencyCode(); + return currencyCode; + } + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug_for_caoyaojun1988.java b/src/test/java/com/alibaba/json/bvt/bug/bug_for_caoyaojun1988.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/builder/BuilderTest2.java b/src/test/java/com/alibaba/json/bvt/builder/BuilderTest2.java index 61b2804e3a..b9b09898bf 100644 --- a/src/test/java/com/alibaba/json/bvt/builder/BuilderTest2.java +++ b/src/test/java/com/alibaba/json/bvt/builder/BuilderTest2.java @@ -21,7 +21,15 @@ public void test_create() throws Exception { public static class VO { private int id; private String name; - + + public void setId(int id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + public int getId() { return id; } diff --git a/src/test/java/com/alibaba/json/bvt/cglib/TestCglib.java b/src/test/java/com/alibaba/json/bvt/cglib/TestCglib.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/compatible/ThreadLocalCacheTest.java b/src/test/java/com/alibaba/json/bvt/compatible/ThreadLocalCacheTest.java index deb7db82e9..0ce179a42e 100644 --- a/src/test/java/com/alibaba/json/bvt/compatible/ThreadLocalCacheTest.java +++ b/src/test/java/com/alibaba/json/bvt/compatible/ThreadLocalCacheTest.java @@ -9,5 +9,6 @@ public class ThreadLocalCacheTest extends TestCase{ public void test_threadCache() throws Exception { ThreadLocalCache.getBytes(10); + ThreadLocalCache.clearBytes(); } } diff --git a/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest0.java b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest0.java old mode 100755 new mode 100644 index a3a26f0b64..79621a30ce --- a/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest0.java +++ b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest0.java @@ -52,19 +52,22 @@ public void test_4() throws Exception { public void test_5() throws Exception { V2 vo = new V2(); - vo.setF2('中'); + vo.setF1(0.2f); + vo.setF2(33.3); assertEquals(toCompatibleJSONString(vo), toJSONLibString(vo)); } public void test_6() throws Exception { V2 vo = new V2(); vo.setF1(0.1f); + vo.setF2(33.3); assertEquals(toCompatibleJSONString(vo), toJSONLibString(vo)); } public void test_7() throws Exception { V2 vo = new V2(); vo.setF2(0.1D); + vo.setF1(33.3f); assertEquals(toCompatibleJSONString(vo), toJSONLibString(vo)); } diff --git a/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest_noasm.java b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest_noasm.java old mode 100755 new mode 100644 index e4c0b72ff4..82b1e54995 --- a/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest_noasm.java +++ b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest_noasm.java @@ -52,18 +52,22 @@ public void test_4() throws Exception { public void test_5() throws Exception { V2 vo = new V2(); - vo.setF2('中'); + vo.setF1(1.1f); + vo.setF2(2.2); assertEquals(toCompatibleJSONString(vo), toJSONLibString(vo)); } public void test_6() throws Exception { V2 vo = new V2(); + vo.setF1(0.1f); + vo.setF2(3.3); assertEquals(toCompatibleJSONString(vo), toJSONLibString(vo)); } public void test_7() throws Exception { V2 vo = new V2(); + vo.setF1(1.1f); vo.setF2(0.1D); assertEquals(toCompatibleJSONString(vo), toJSONLibString(vo)); } diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldFormatTest.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldFormatTest.java index 6a3a3b1194..1ac61c08a9 100644 --- a/src/test/java/com/alibaba/json/bvt/date/DateFieldFormatTest.java +++ b/src/test/java/com/alibaba/json/bvt/date/DateFieldFormatTest.java @@ -40,12 +40,20 @@ public void test_format_() throws Exception { String t2 = df2.format(now); String t3 = df3.format(now); - Assert.assertEquals("{\"publishTime\":\""+t2+"\",\"serverTime\":\""+t1+"\",\"startDate\":\""+t3+"\"}",text); + assertEquals("{\"publishTime\":\""+t2+"\",\"serverTime\":\""+t1+"\",\"startDate\":\""+t3+"\"}",text); Model model2 = JSON.parseObject(text, Model.class); - Assert.assertEquals(t2,new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.CHINA).format(model2.publishTime)); - Assert.assertEquals(t1,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(model2.serverTime)); - Assert.assertEquals(t3,new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA).format(model2.getStartDate())); + SimpleDateFormat df4 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.CHINA); + SimpleDateFormat df5 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); + SimpleDateFormat df6 = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA); + + df4.setTimeZone(JSON.defaultTimeZone); + df5.setTimeZone(JSON.defaultTimeZone); + df6.setTimeZone(JSON.defaultTimeZone); + + assertEquals(t2, df4.format(model2.publishTime)); + assertEquals(t1, df5.format(model2.serverTime)); + assertEquals(t3, df6.format(model2.getStartDate())); } diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest10.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest10.java index 1590726b20..6dfb4ebeb8 100644 --- a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest10.java +++ b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest10.java @@ -1,6 +1,7 @@ package com.alibaba.json.bvt.date; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; import junit.framework.TestCase; import java.text.SimpleDateFormat; @@ -57,6 +58,26 @@ public void test_4() throws Exception { // assertEquals(object, model.date); } + public void test_5() throws Exception { + String text = "{\"date\":\"2018-05-21T14:39:44.907+08:00\"}"; + Model model = JSON.parseObject(text, Model.class); + String str = JSON.toJSONString(model, SerializerFeature.UseISO8601DateFormat); + assertEquals("{\"date\":\"2018-05-21T14:39:44.907+08:00\"}", str); + +// SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); +// Date object = format.parse("2018-05-21T14:39:44.9077913+08:00"); +// assertEquals(object.getTime(), model.date.getTime()); + } + + public void test_6() throws Exception { + String text = "{\"date\":\"4567-08-16T04:29\"}"; + Model model = JSON.parseObject(text, Model.class); + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + Object object = format.parse("2017-08-16 04:29"); +// assertEquals(object, model.date); + } + public static class Model { public Date date; } diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest12_t.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest12_t.java new file mode 100644 index 0000000000..b9f2055d19 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest12_t.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.date; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class DateFieldTest12_t extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + + public void test_1() throws Exception { + Entity object = new Entity(); + object.setValue(new Date()); + String text = JSON.toJSONString(object); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", JSON.defaultLocale); + format.setTimeZone(JSON.defaultTimeZone); + Assert.assertEquals("{\"value\":\"" + format.format(object.getValue()) + "\"}", + text); + + Entity object2 = JSON.parseObject(text, Entity.class); + } + + public static class Entity { + + @JSONField(format = "yyyy-MM-ddTHH:mm:ssZ") + private Date value; + + public Date getValue() { + return value; + } + + public void setValue(Date value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest2.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest3.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest4.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest5.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest6.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFieldTest7.java b/src/test/java/com/alibaba/json/bvt/date/DateFieldTest7.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/date/DateFormatPriorityTest.java b/src/test/java/com/alibaba/json/bvt/date/DateFormatPriorityTest.java new file mode 100644 index 0000000000..bba8346aef --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/date/DateFormatPriorityTest.java @@ -0,0 +1,187 @@ +package com.alibaba.json.bvt.date; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import junit.framework.TestCase; +import org.junit.Assert; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + + +public class DateFormatPriorityTest extends TestCase { + Calendar calendar; + + protected void setUp() { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + + calendar = Calendar.getInstance(JSON.defaultTimeZone); + calendar.set(1995, Calendar.OCTOBER, 26); + } + + public void test_for_fastJsonConfig() throws IOException { + FastJsonConfig config = new FastJsonConfig(); + config.setDateFormat("yyyy-MM.dd"); + + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + converter.setFastJsonConfig(config); + + converter.canRead(VO.class, MediaType.APPLICATION_JSON_UTF8); + converter.canWrite(VO.class, MediaType.APPLICATION_JSON_UTF8); + + final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + HttpOutputMessage out = new HttpOutputMessage() { + public HttpHeaders getHeaders() { + return new HttpHeaders() { + private static final long serialVersionUID = 1L; + + @Override + public MediaType getContentType() { + return MediaType.APPLICATION_JSON; + } + }; + } + + public OutputStream getBody() throws IOException { + return byteOut; + } + }; + + VO vo = new VO(); + vo.setDate(calendar.getTime()); + converter.write(vo, VO.class, MediaType.APPLICATION_JSON_UTF8, out); + + byte[] bytes = byteOut.toByteArray(); + String jsonString = new String(bytes, "UTF-8"); + + Assert.assertEquals("{\"date\":\"1995-10.26\"}", jsonString); + } + + public void test_for_toJSONStringWithDateFormat() { + VO vo = new VO(); + vo.setDate(calendar.getTime()); + + String jsonString = JSON.toJSONStringWithDateFormat(vo, "yyyy.MM.dd"); + + assertEquals("{\"date\":\"1995.10.26\"}", jsonString); + } + + public void test_for_Annotation() { + VO2 vo2 = new VO2(); + vo2.setDate(calendar.getTime()); + + String jsonString = JSON.toJSONString(vo2); + + assertEquals("{\"date\":\"1995.10-26\"}", jsonString); + } + + public void test_for_DEFFAULT_DATE_FORMAT() { + String defaultDateFormat = JSON.DEFFAULT_DATE_FORMAT; + + JSON.DEFFAULT_DATE_FORMAT = "MM-dd"; + VO vo = new VO(); + vo.setDate(calendar.getTime()); + + String jsonString = JSON.toJSONString(vo, SerializerFeature.WriteDateUseDateFormat); + JSON.DEFFAULT_DATE_FORMAT = defaultDateFormat; + + assertEquals("{\"date\":\"10-26\"}", jsonString); + } + + //Annotation + FastJsonConfig (Annotation优先) + public void test_priority_01() throws Exception { + //FastJsonConfig + FastJsonConfig config = new FastJsonConfig(); + config.setDateFormat("yyyy-MM.dd"); + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + converter.setFastJsonConfig(config); + converter.canRead(VO.class, MediaType.APPLICATION_JSON_UTF8); + converter.canWrite(VO.class, MediaType.APPLICATION_JSON_UTF8); + final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + HttpOutputMessage out = new HttpOutputMessage() { + public HttpHeaders getHeaders() { + return new HttpHeaders() { + private static final long serialVersionUID = 1L; + + @Override + public MediaType getContentType() { + return MediaType.APPLICATION_JSON; + } + }; + } + public OutputStream getBody() throws IOException { + return byteOut; + } + }; + + VO2 vo = new VO2(); + vo.setDate(calendar.getTime()); + converter.write(vo, VO.class, MediaType.APPLICATION_JSON_UTF8, out); + + byte[] bytes = byteOut.toByteArray(); + String jsonString = new String(bytes, "UTF-8"); + + assertEquals("{\"date\":\"1995.10-26\"}", jsonString); + } + + //toJSONStringWithDateFormat + Annotation (toJSONStringWithDateFormat优先) + public void test_priority_02() throws Exception { + VO2 vo = new VO2(); + vo.setDate(calendar.getTime()); + + String jsonString = JSON.toJSONStringWithDateFormat(vo, "yyyy.MM.dd"); + + assertEquals("{\"date\":\"1995.10.26\"}", jsonString); + } + + //Annotation + DEFFAULT_DATE_FORMAT (Annotation优先) + public void test_priority_03() throws Exception { + String defaultDateFormat = JSON.DEFFAULT_DATE_FORMAT; + + JSON.DEFFAULT_DATE_FORMAT = "MM-dd"; + VO2 vo = new VO2(); + vo.setDate(calendar.getTime()); + + String jsonString = JSON.toJSONString(vo, SerializerFeature.WriteDateUseDateFormat); + JSON.DEFFAULT_DATE_FORMAT = defaultDateFormat; + + assertEquals("{\"date\":\"1995.10-26\"}", jsonString); + } + + public static class VO { + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + } + + public static class VO2 { + @JSONField(format = "yyyy.MM-dd") + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/date/DateTest.java b/src/test/java/com/alibaba/json/bvt/date/DateTest.java old mode 100755 new mode 100644 index 46999d219a..bb953c7069 --- a/src/test/java/com/alibaba/json/bvt/date/DateTest.java +++ b/src/test/java/com/alibaba/json/bvt/date/DateTest.java @@ -1,6 +1,8 @@ package com.alibaba.json.bvt.date; import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; import junit.framework.TestCase; @@ -10,6 +12,10 @@ import com.alibaba.fastjson.serializer.SerializerFeature; public class DateTest extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } public void test_date() throws Exception { long millis = 1324138987429L; @@ -26,4 +32,9 @@ public void test_date() throws Exception { JSON.toJSONStringWithDateFormat(date, "yyyy-MM-dd HH:mm:ss.SSS", SerializerFeature.UseSingleQuotes)); } + + public void test_parse() throws Exception { + Date date = JSON.parseObject("\"2018-10-12 09:48:22 +0800\"", Date.class); + assertEquals(1539308902000L, date.getTime()); + } } diff --git a/src/test/java/com/alibaba/json/bvt/date/DateTest2.java b/src/test/java/com/alibaba/json/bvt/date/DateTest2.java new file mode 100644 index 0000000000..f726e53e3b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/date/DateTest2.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.date; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Date; +import java.util.TimeZone; + +public class DateTest2 extends TestCase { + private TimeZone timeZone; + protected void setUp() throws Exception { + timeZone = JSON.defaultTimeZone; + } + + protected void tearDown() throws Exception { + JSON.defaultTimeZone = timeZone; + } + + public void test_date() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("America/Chicago"); + Date date = new Date(1531928656055L); + TestBean bean = new TestBean(); + bean.setDate(date); + + String iso = JSON.toJSONString(bean, SerializerFeature.UseISO8601DateFormat); + assertEquals("{\"date\":\"2018-07-18T10:44:16.055-05:00\"}", iso); + } + + public static class TestBean { + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/date/DateTest_tz.java b/src/test/java/com/alibaba/json/bvt/date/DateTest_tz.java index 2a1b026d9f..1e8f827083 100644 --- a/src/test/java/com/alibaba/json/bvt/date/DateTest_tz.java +++ b/src/test/java/com/alibaba/json/bvt/date/DateTest_tz.java @@ -8,15 +8,16 @@ import org.junit.Assert; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONReader; import junit.framework.TestCase; public class DateTest_tz extends TestCase { -// protected void setUp() throws Exception { -// JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); -// JSON.defaultLocale = Locale.CHINA; -// } + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } public void test_codec() throws Exception { JSONReader reader = new JSONReader(new StringReader("{\"value\":\"2016-04-29\"}")); diff --git a/src/test/java/com/alibaba/json/bvt/dubbo/TestForDubbo.java b/src/test/java/com/alibaba/json/bvt/dubbo/TestForDubbo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest2.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest3.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest4.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest5.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest5_1.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest5_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest6.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest7.java b/src/test/java/com/alibaba/json/bvt/feature/FeaturesTest7.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/fullSer/LongTest.java b/src/test/java/com/alibaba/json/bvt/fullSer/LongTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/geo/FeatureCollectionTest.java b/src/test/java/com/alibaba/json/bvt/geo/FeatureCollectionTest.java new file mode 100644 index 0000000000..269846cd27 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/FeatureCollectionTest.java @@ -0,0 +1,69 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.FeatureCollection; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.Point; +import junit.framework.TestCase; + +public class FeatureCollectionTest + extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"FeatureCollection\",\n" + + " \"features\": [{\n" + + " \"type\": \"Feature\",\n" + + " \"geometry\": {\n" + + " \"type\": \"Point\",\n" + + " \"coordinates\": [102.0, 0.5]\n" + + " },\n" + + " \"properties\": {\n" + + " \"prop0\": \"value0\"\n" + + " }\n" + + " }, {\n" + + " \"type\": \"Feature\",\n" + + " \"geometry\": {\n" + + " \"type\": \"LineString\",\n" + + " \"coordinates\": [\n" + + " [102.0, 0.0],\n" + + " [103.0, 1.0],\n" + + " [104.0, 0.0],\n" + + " [105.0, 1.0]\n" + + " ]\n" + + " },\n" + + " \"properties\": {\n" + + " \"prop0\": \"value0\",\n" + + " \"prop1\": 0.0\n" + + " }\n" + + " }, {\n" + + " \"type\": \"Feature\",\n" + + " \"geometry\": {\n" + + " \"type\": \"Polygon\",\n" + + " \"coordinates\": [\n" + + " [\n" + + " [100.0, 0.0],\n" + + " [101.0, 0.0],\n" + + " [101.0, 1.0],\n" + + " [100.0, 1.0],\n" + + " [100.0, 0.0]\n" + + " ]\n" + + " ]\n" + + " },\n" + + " \"properties\": {\n" + + " \"prop0\": \"value0\",\n" + + " \"prop1\": {\n" + + " \"this\": \"that\"\n" + + " }\n" + + " }\n" + + " }]\n" + + "}\n"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(FeatureCollection.class, geometry.getClass()); + + assertEquals("{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"prop0\":\"value0\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[102.0,0.5]}},{\"type\":\"Feature\",\"properties\":{\"prop1\":\"0.0\",\"prop0\":\"value0\"},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[102.0,0.0],[103.0,1.0],[104.0,0.0],[105.0,1.0]]}},{\"type\":\"Feature\",\"properties\":{\"prop1\":\"{\\\"this\\\":\\\"that\\\"}\",\"prop0\":\"value0\"},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]]]}}]}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/FeatureTest.java b/src/test/java/com/alibaba/json/bvt/geo/FeatureTest.java new file mode 100644 index 0000000000..9383bc16c6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/FeatureTest.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Feature; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.Point; +import junit.framework.TestCase; + +public class FeatureTest + extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"Feature\",\n" + + " \"bbox\": [-10.0, -10.0, 10.0, 10.0],\n" + + " \"geometry\": {\n" + + " \"type\": \"Polygon\",\n" + + " \"coordinates\": [\n" + + " [\n" + + " [-10.0, -10.0],\n" + + " [10.0, -10.0],\n" + + " [10.0, 10.0],\n" + + " [-10.0, -10.0]\n" + + " ]\n" + + " ]\n" + + " }\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(Feature.class, geometry.getClass()); + + assertEquals("{\"type\":\"Feature\",\"bbox\":[-10.0,-10.0,10.0,10.0],\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-10.0,-10.0],[10.0,-10.0],[10.0,10.0],[-10.0,-10.0]]]}}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } + + public void test_geo_1() throws Exception { + String str = "{\n" + + " \"type\": \"Feature\",\n" + + " \"id\": \"f2\",\n" + + " \"geometry\": {\n" + + " \"type\": \"Polygon\",\n" + + " \"coordinates\": [\n" + + " [\n" + + " [-10.0, -10.0],\n" + + " [10.0, -10.0],\n" + + " [10.0, 10.0],\n" + + " [-10.0, -10.0]\n" + + " ]\n" + + " ]\n" + + " }\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(Feature.class, geometry.getClass()); + + assertEquals("{\"type\":\"Feature\",\"id\":\"f2\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-10.0,-10.0],[10.0,-10.0],[10.0,10.0],[-10.0,-10.0]]]}}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/GeometryCollectionTest.java b/src/test/java/com/alibaba/json/bvt/geo/GeometryCollectionTest.java new file mode 100644 index 0000000000..d0db8b99cb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/GeometryCollectionTest.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.GeometryCollection; +import com.alibaba.fastjson.support.geo.LineString; +import junit.framework.TestCase; + +public class GeometryCollectionTest + extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"GeometryCollection\",\n" + + " \"geometries\": [{\n" + + " \"type\": \"Point\",\n" + + " \"coordinates\": [100.0, 0.0]\n" + + " }, {\n" + + " \"type\": \"LineString\",\n" + + " \"coordinates\": [\n" + + " [101.0, 0.0],\n" + + " [102.0, 1.0]\n" + + " ]\n" + + " }]\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(GeometryCollection.class, geometry.getClass()); + + assertEquals( + "{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Point\",\"coordinates\":[100.0,0.0]},{\"type\":\"LineString\",\"coordinates\":[[101.0,0.0],[102.0,1.0]]}]}" + , JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/LineStringTest.java b/src/test/java/com/alibaba/json/bvt/geo/LineStringTest.java new file mode 100644 index 0000000000..7b6050fe6e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/LineStringTest.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.LineString; +import junit.framework.TestCase; + +public class LineStringTest extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"LineString\",\n" + + " \"coordinates\": [\n" + + " [100.0, 0.0],\n" + + " [101.0, 1.0]\n" + + " ]\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(LineString.class, geometry.getClass()); + + assertEquals("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/MultiLineStringTest.java b/src/test/java/com/alibaba/json/bvt/geo/MultiLineStringTest.java new file mode 100644 index 0000000000..4e1b251021 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/MultiLineStringTest.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.MultiLineString; +import com.alibaba.fastjson.support.geo.MultiPoint; +import junit.framework.TestCase; + +public class MultiLineStringTest + extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"MultiLineString\",\n" + + " \"coordinates\": [\n" + + " [\n" + + " [100.0, 0.0],\n" + + " [101.0, 1.0]\n" + + " ],\n" + + " [\n" + + " [102.0, 2.0],\n" + + " [103.0, 3.0]\n" + + " ]\n" + + " ]\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(MultiLineString.class, geometry.getClass()); + + assertEquals("{\"type\":\"MultiLineString\",\"coordinates\":[[[100.0,0.0],[101.0,1.0]],[[102.0,2.0],[103.0,3.0]]]}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/MultiPointTest.java b/src/test/java/com/alibaba/json/bvt/geo/MultiPointTest.java new file mode 100644 index 0000000000..2ac541a50b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/MultiPointTest.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.MultiPoint; +import com.alibaba.fastjson.support.geo.Point; +import junit.framework.TestCase; + +public class MultiPointTest extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"MultiPoint\",\n" + + " \"coordinates\": [\n" + + " [100.0, 0.0],\n" + + " [101.0, 1.0]\n" + + " ]\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(MultiPoint.class, geometry.getClass()); + + assertEquals("{\"type\":\"MultiPoint\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/MultiPolygonTest.java b/src/test/java/com/alibaba/json/bvt/geo/MultiPolygonTest.java new file mode 100644 index 0000000000..63e1318e4d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/MultiPolygonTest.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.MultiPoint; +import com.alibaba.fastjson.support.geo.MultiPolygon; +import junit.framework.TestCase; + +public class MultiPolygonTest + extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"MultiPolygon\",\n" + + " \"coordinates\": [\n" + + " [\n" + + " [\n" + + " [102.0, 2.0],\n" + + " [103.0, 2.0],\n" + + " [103.0, 3.0],\n" + + " [102.0, 3.0],\n" + + " [102.0, 2.0]\n" + + " ]\n" + + " ],\n" + + " [\n" + + " [\n" + + " [100.0, 0.0],\n" + + " [101.0, 0.0],\n" + + " [101.0, 1.0],\n" + + " [100.0, 1.0],\n" + + " [100.0, 0.0]\n" + + " ],\n" + + " [\n" + + " [100.2, 0.2],\n" + + " [100.2, 0.8],\n" + + " [100.8, 0.8],\n" + + " [100.8, 0.2],\n" + + " [100.2, 0.2]\n" + + " ]\n" + + " ]\n" + + " ]\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(MultiPolygon.class, geometry.getClass()); + + assertEquals( + "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[102.0,2.0],[103.0,2.0],[103.0,3.0],[102.0,3.0],[102.0,2.0]]],[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],[[100.2,0.2],[100.2,0.8],[100.8,0.8],[100.8,0.2],[100.2,0.2]]]]}" + , JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/PointTest.java b/src/test/java/com/alibaba/json/bvt/geo/PointTest.java new file mode 100644 index 0000000000..4fb7d73ede --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/PointTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.LineString; +import com.alibaba.fastjson.support.geo.Point; +import junit.framework.TestCase; + +public class PointTest + extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"Point\",\n" + + " \"coordinates\": [100.0, 0.0]\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(Point.class, geometry.getClass()); + + assertEquals("{\"type\":\"Point\",\"coordinates\":[100.0,0.0]}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/geo/PolygonTest.java b/src/test/java/com/alibaba/json/bvt/geo/PolygonTest.java new file mode 100644 index 0000000000..e714221053 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/geo/PolygonTest.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.geo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.geo.Geometry; +import com.alibaba.fastjson.support.geo.Point; +import com.alibaba.fastjson.support.geo.Polygon; +import junit.framework.TestCase; + +public class PolygonTest + extends TestCase { + public void test_geo() throws Exception { + String str = "{\n" + + " \"type\": \"Polygon\",\n" + + " \"coordinates\": [\n" + + " [\n" + + " [100.0, 0.0],\n" + + " [101.0, 0.0],\n" + + " [101.0, 1.0],\n" + + " [100.0, 1.0],\n" + + " [100.0, 0.0]\n" + + " ],\n" + + " [\n" + + " [100.8, 0.8],\n" + + " [100.8, 0.2],\n" + + " [100.2, 0.2],\n" + + " [100.2, 0.8],\n" + + " [100.8, 0.8]\n" + + " ]\n" + + " ]\n" + + "}"; + + Geometry geometry = JSON.parseObject(str, Geometry.class); + assertEquals(Polygon.class, geometry.getClass()); + + assertEquals("{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],[[100.8,0.8],[100.8,0.2],[100.2,0.2],[100.2,0.8],[100.8,0.8]]]}", JSON.toJSONString(geometry)); + + String str2 = JSON.toJSONString(geometry); + assertEquals(str2, JSON.toJSONString(JSON.parseObject(str2, Geometry.class))); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/guava/ArrayListMultimapTest.java b/src/test/java/com/alibaba/json/bvt/guava/ArrayListMultimapTest.java index 1459cb4fb3..e96b9b836b 100644 --- a/src/test/java/com/alibaba/json/bvt/guava/ArrayListMultimapTest.java +++ b/src/test/java/com/alibaba/json/bvt/guava/ArrayListMultimapTest.java @@ -1,9 +1,8 @@ package com.alibaba.json.bvt.guava; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimaps; import com.google.common.collect.TreeMultimap; import com.google.common.primitives.Ints; import junit.framework.TestCase; @@ -18,8 +17,7 @@ public void test_for_multimap() throws Exception { multimap.putAll("a", Ints.asList(4, 2, 1)); multimap.putAll("c", Ints.asList(2, 5, 3)); - - String json = JSON.toJSONString(multimap); + String json = JSON.toJSONString(multimap, SerializerFeature.MapSortField); assertEquals("{\"a\":[4,2,1],\"b\":[2,4,6],\"c\":[2,5,3]}", json); TreeMultimap treeMultimap = TreeMultimap.create(multimap); diff --git a/src/test/java/com/alibaba/json/bvt/guava/HashMultimapTest.java b/src/test/java/com/alibaba/json/bvt/guava/HashMultimapTest.java index bdd8872636..20f68be82a 100644 --- a/src/test/java/com/alibaba/json/bvt/guava/HashMultimapTest.java +++ b/src/test/java/com/alibaba/json/bvt/guava/HashMultimapTest.java @@ -16,6 +16,6 @@ public void test_for_multimap() throws Exception { map.put("name", "b"); String json = JSON.toJSONString(map); - assertEquals("{\"name\":[\"a\",\"b\"]}", json); + assertTrue(json.equals("{\"name\":[\"a\",\"b\"]}") || json.equals("{\"name\":[\"b\",\"a\"]}")); } } diff --git a/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1152.java b/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1152.java index 4cf1bccb0a..3601451213 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1152.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1152.java @@ -18,7 +18,7 @@ public void test_for_issue() throws Exception { public void test_for_issue_2() throws Exception { TestBean tb = JSONObject.parseObject("{shijian:\"0001-01-01T00:00:00+08:00\"}",TestBean.class); - assertNull(tb.getShijian()); + assertNotNull(tb.getShijian()); } public static class TestBean { diff --git a/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1177_2.java b/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1177_2.java index 0bc28fe3b9..264762bb9e 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1177_2.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1177_2.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson.TypeReference; import junit.framework.TestCase; +import java.util.LinkedHashMap; import java.util.Map; /** @@ -14,7 +15,7 @@ public class Issue1177_2 extends TestCase { public void test_for_issue() throws Exception { String text = "{\"a\":{\"x\":\"y\"},\"b\":{\"x\":\"y\"}}"; - Map jsonObject = JSONObject.parseObject(text, new TypeReference>(){}); + Map jsonObject = JSONObject.parseObject(text, new TypeReference>(){}); System.out.println(JSON.toJSONString(jsonObject)); String jsonpath = "$..x"; String value="y2"; diff --git a/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1254.java b/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1254.java index 71edbf71fe..c63ef35f7c 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1254.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1254.java @@ -2,11 +2,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; -import com.alibaba.json.bvt.bug.Bug_101_for_rongganlin_case2; import junit.framework.TestCase; -import org.apache.commons.beanutils.BeanUtils; - -import java.util.Map; /** * Created by kimmking on 09/06/2017. diff --git a/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1272.java b/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1272.java index 7b801d4314..7cfdf5b0ed 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1272.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1272.java @@ -17,7 +17,7 @@ public void test_for_issue() throws Exception { exception = ex; } assertNotNull(exception); - assertEquals(NullPointerException.class, exception.getCause().getCause().getClass()); + assertEquals(NullPointerException.class, exception.getCause().getClass()); } public static class Point { diff --git a/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1298.java b/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1298.java index 94a32f7f53..2983432c57 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1298.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1200/Issue1298.java @@ -6,11 +6,18 @@ import junit.framework.TestCase; import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; /** * Created by wenshao on 30/06/2017. */ public class Issue1298 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.US; + } + public void test_for_issue() throws Exception { JSONObject object = new JSONObject(); diff --git a/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1480.java b/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1480.java index 45edb90168..4d3b2b55a0 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1480.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1480.java @@ -7,12 +7,13 @@ import org.junit.Assert; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; public class Issue1480 extends TestCase { public void test_for_issue() throws Exception { - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put(1,10); map.put(2,4); map.put(3,5); diff --git a/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1493.java b/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1493.java index 161d2998e4..b1c6ab3347 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1493.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1400/Issue1493.java @@ -20,18 +20,18 @@ protected void setUp() throws Exception { public void test_for_issue() throws Exception { TestBean test = new TestBean(); - String stime2 = "2017-09-22 15:08:56"; + String stime2 = "2017-09-22T15:08:56"; LocalDateTime time1 = LocalDateTime.now(); time1 = time1.minusNanos(10L); System.out.println(time1.getNano()); - LocalDateTime time2 = LocalDateTime.parse(stime2, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA)); + LocalDateTime time2 = LocalDateTime.parse(stime2); test.setTime1(time1); test.setTime2(time2); - String t1 = time1.toString(); + String t1 = JSON.toJSONString(time1, SerializerFeature.WriteDateUseDateFormat); String json = JSON.toJSONString(test, SerializerFeature.WriteDateUseDateFormat); - Assert.assertEquals("{\"time1\":\""+t1+"\",\"time2\":\""+stime2+"\"}",json); + Assert.assertEquals("{\"time1\":"+t1+",\"time2\":\"2017-09-22 15:08:56\"}",json); //String default_format = JSON.DEFFAULT_LOCAL_DATE_TIME_FORMAT; @@ -39,13 +39,13 @@ public void test_for_issue() throws Exception { //String stime1 = DateTimeFormatter.ofPattern(JSON.DEFFAULT_LOCAL_DATE_TIME_FORMAT, Locale.CHINA).format(time1); json = JSON.toJSONString(test, SerializerFeature.WriteDateUseDateFormat); - Assert.assertEquals("{\"time1\":\""+time1+"\",\"time2\":\""+stime2+"\"}",json); + Assert.assertEquals("{\"time1\":"+ JSON.toJSONString(time1, SerializerFeature.WriteDateUseDateFormat) +",\"time2\":\"2017-09-22 15:08:56\"}",json); - String pattern = "yyyy-MM-dd HH:mm:ss"; + String pattern = "yyyy-MM-dd'T'HH:mm:ss"; String stime1 = DateTimeFormatter.ofPattern(pattern, Locale.CHINA).format(time1); - json = JSON.toJSONStringWithDateFormat(test, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat); + json = JSON.toJSONStringWithDateFormat(test, "yyyy-MM-dd'T'HH:mm:ss", SerializerFeature.WriteDateUseDateFormat); Assert.assertEquals("{\"time1\":\""+stime1+"\",\"time2\":\""+stime2+"\"}",json); //JSON.DEFFAULT_LOCAL_DATE_TIME_FORMAT = default_format; diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1510.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1510.java new file mode 100644 index 0000000000..ede6dce899 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1510.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.issue_1500; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue1510 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + Model model = JSON.parseObject("{\"startTime\":\"2017-11-04\",\"endTime\":\"2017-11-14\"}", Model.class); + String text = JSON.toJSONString(model); + assertEquals("{\"endTime\":\"2017-11-14\",\"startTime\":\"2017-11-04\"}", text); + } + + public static class Model { + @JSONField(format = "yyyy-MM-dd") + private Date startTime; + + @JSONField(format = "yyyy-MM-dd") + private Date endTime; + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1555.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1555.java index d6fadb4ce3..7935826e3f 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1555.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1555.java @@ -10,7 +10,7 @@ public class Issue1555 extends TestCase { public void test_for_issue() throws Exception { Model model = new Model(); model.userId = 1001; - model.userName="test"; + model.userName = "test"; String text = JSON.toJSONString(model); assertEquals("{\"userName\":\"test\",\"user_id\":1001}", text); @@ -20,6 +20,23 @@ public void test_for_issue() throws Exception { assertEquals("test", model2.userName); } + /** + * 当某个字段有JSONField注解,JSONField中name属性不存在,json属性名也要用类上的属性名转换策略 + * @throws Exception + */ + public void test_when_JSONField_have_not_name_attr() throws Exception { + ModelTwo modelTwo = new ModelTwo(); + modelTwo.userId = 1001; + modelTwo.userName = "test"; + String text = JSON.toJSONString(modelTwo); + assertEquals("{\"userName\":\"test\",\"user_id\":\"1001\"}", text); + + Model model2 = JSON.parseObject(text, Model.class); + + assertEquals(1001, model2.userId); + assertEquals("test", model2.userName); + } + @JSONType(naming = PropertyNamingStrategy.SnakeCase) public static class Model { private int userId; @@ -42,4 +59,31 @@ public void setUserName(String userName) { this.userName = userName; } } + + @JSONType(naming = PropertyNamingStrategy.SnakeCase) + public static class ModelTwo { + /** + * 此字段准备序列化为字符串类型 + */ + @JSONField(serializeUsing = StringSerializer.class) + private int userId; + @JSONField(name = "userName") + private String userName; + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + } } diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1556.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1556.java index 45605cabb1..5404d617c2 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1556.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1556.java @@ -26,11 +26,12 @@ public void test_for_issue() throws Exception { classForData.setSecond(secondSubClass); ApiResult apiResult = ApiResult.valueOfSuccess(classForData); - ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + ParserConfig config = new ParserConfig(); + config.setAutoTypeSupport(true); String jsonString = JSON.toJSONString(apiResult, SerializerFeature.WriteClassName);//这里加上SerializerFeature.DisableCircularReferenceDetect System.out.println(jsonString); - Object obj = JSON.parse(jsonString);//这里加上Feature.DisableCircularReferenceDetect 这样的话 是可以避免空值的 ,但是$ref 还有啥意思呢 + Object obj = JSON.parse(jsonString, config);//这里加上Feature.DisableCircularReferenceDetect 这样的话 是可以避免空值的 ,但是$ref 还有啥意思呢 System.out.println(JSON.toJSONString(obj)); } diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1580.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1580.java new file mode 100644 index 0000000000..50f9293824 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1580.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.issue_1500; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeFilter; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.serializer.SimplePropertyPreFilter; +import junit.framework.TestCase; + +public class Issue1580 extends TestCase { + public void test_for_issue() throws Exception { + SimplePropertyPreFilter classAFilter = new SimplePropertyPreFilter(Model.class, "code"); + SerializeFilter[] filters =new SerializeFilter[]{classAFilter}; + + Model model = new Model(); + model.code = 1001; + model.name = "N1"; + + String json = JSON.toJSONString(model, filters, SerializerFeature.BeanToArray ); + assertEquals("[1001,null]", json); + } + + public static class Model { + private int code; + private String name; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1580_private.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1580_private.java new file mode 100644 index 0000000000..d5f5aa34b8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1580_private.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.issue_1500; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeFilter; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.serializer.SimplePropertyPreFilter; +import junit.framework.TestCase; + +public class Issue1580_private extends TestCase { + public void test_for_issue() throws Exception { + SimplePropertyPreFilter classAFilter = new SimplePropertyPreFilter(Model.class, "code"); + SerializeFilter[] filters =new SerializeFilter[]{classAFilter}; + + Model model = new Model(); + model.code = 1001; + model.name = "N1"; + + String json = JSON.toJSONString(model, filters, SerializerFeature.BeanToArray ); + assertEquals("[1001,null]", json); + } + + private static class Model { + private int code; + private String name; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1582.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1582.java index a962ca5356..901ad33b98 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1582.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1582.java @@ -1,6 +1,7 @@ package com.alibaba.json.bvt.issue_1500; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import junit.framework.TestCase; @@ -14,6 +15,16 @@ public void test_for_issue() throws Exception { assertSame(Size.Small, JSON.parseObject("\"Little\"", Size.class)); } + public void test_for_issue_1() throws Exception { + JSONObject object = JSON.parseObject("{\"size\":\"Little\"}"); + Model model = object.toJavaObject(Model.class); + assertSame(Size.Small, model.size); + } + + public static class Model { + public Size size; + } + public static enum Size { Big, diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1584.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1584.java index e474a15308..618c5bbf87 100644 --- a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1584.java +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1584.java @@ -20,8 +20,14 @@ public void test_for_issue() throws Exception { { Map.Entry entry = JSON.parseObject(json, Map.Entry.class, config); - assertEquals("v", entry.getKey()); - assertEquals("A", entry.getValue()); + Object key = entry.getKey(); + Object value = entry.getValue(); + assertTrue(key.equals("v") || key.equals("k")); + if (key.equals("v")) { + assertEquals("A", value); + } else { + assertEquals(1, value); + } } config.putDeserializer(Map.Entry.class, new ObjectDeserializer() { diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1588.java b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1588.java new file mode 100644 index 0000000000..6f1cf8848b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/Issue1588.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_1500; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Issue1588 extends TestCase { + public void test_for_issue() throws Exception { + String dateString = "2017-11-17 00:00:00"; + Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateString); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("test", date); + System.out.println(jsonObject.toJSONString(jsonObject, SerializerFeature.UseISO8601DateFormat)); + System.out.println(JSONObject.toJSONStringWithDateFormat(jsonObject, "yyyy-MM-dd'T'HH:mm:ssXXX")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1500/StringSerializer.java b/src/test/java/com/alibaba/json/bvt/issue_1500/StringSerializer.java new file mode 100644 index 0000000000..43f2972ff5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1500/StringSerializer.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.issue_1500; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; + +import java.io.IOException; +import java.lang.reflect.Type; + +public class StringSerializer implements ObjectSerializer { + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + serializer.write(String.valueOf(object)); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_field.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_field.java new file mode 100644 index 0000000000..b722d75206 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_field.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +public class Issue1603_field extends TestCase { + public void test_emptySet() throws Exception { + Model_1 m = JSON.parseObject("{\"values\":[\"a\"]}", Model_1.class); + assertEquals(0, m.values.size()); + } + + public void test_emptyList() throws Exception { + Model_2 m = JSON.parseObject("{\"values\":[\"a\"]}", Model_2.class); + assertEquals(0, m.values.size()); + } + + public void test_unmodifier() throws Exception { + Model_3 m = JSON.parseObject("{\"values\":[\"a\"]}", Model_3.class); + assertEquals(0, m.values.size()); + } + + public static class Model_1 { + public final Collection values = Collections.emptySet(); + } + + public static class Model_2 { + public final Collection values = Collections.emptyList(); + } + + public static class Model_3 { + public final Collection values = Collections.unmodifiableList(new ArrayList()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_getter.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_getter.java new file mode 100644 index 0000000000..10ba59e223 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_getter.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +public class Issue1603_getter extends TestCase { + public void test_emptySet() throws Exception { + Model_1 m = JSON.parseObject("{\"values\":[\"a\"]}", Model_1.class); + assertEquals(0, m.values.size()); + } + + public void test_emptyList() throws Exception { + Model_2 m = JSON.parseObject("{\"values\":[\"a\"]}", Model_2.class); + assertEquals(0, m.values.size()); + } + + public void test_unmodifier() throws Exception { + Model_3 m = JSON.parseObject("{\"values\":[\"a\"]}", Model_3.class); + assertEquals(0, m.values.size()); + } + + public static class Model_1 { + private final Collection values = Collections.emptySet(); + + public Collection getValues() { + return values; + } + } + + public static class Model_2 { + private final Collection values = Collections.emptyList(); + + public Collection getValues() { + return values; + } + } + + public static class Model_3 { + private final Collection values = Collections.unmodifiableList(new ArrayList()); + + public Collection getValues() { + return values; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_map.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_map.java new file mode 100644 index 0000000000..f5f179e54b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_map.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.*; + +public class Issue1603_map extends TestCase { + public void test_emptyMap() throws Exception { + Model_1 m = JSON.parseObject("{\"values\":{\"a\":1001}}", Model_1.class); + assertEquals(0, m.values.size()); + } + + public void test_unmodifiableMap() throws Exception { + Model_2 m = JSON.parseObject("{\"values\":{\"a\":1001}}", Model_2.class); + assertEquals(0, m.values.size()); + } + + public static class Model_1 { + public final Map values = Collections.emptyMap(); + } + + public static class Model_2 { + public final Map values = Collections.unmodifiableMap(new HashMap()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_map_getter.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_map_getter.java new file mode 100644 index 0000000000..ad6ea2fd20 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1603_map_getter.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class Issue1603_map_getter extends TestCase { + public void test_emptyMap() throws Exception { + Model_1 m = JSON.parseObject("{\"values\":{\"a\":1001}}", Model_1.class); + assertEquals(0, m.values.size()); + } + + public void test_unmodifiableMap() throws Exception { + Model_2 m = JSON.parseObject("{\"values\":{\"a\":1001}}", Model_2.class); + assertEquals(0, m.values.size()); + } + + public static class Model_1 { + private final Map values = Collections.emptyMap(); + + public Map getValues() { + return values; + } + } + + public static class Model_2 { + private final Map values = Collections.unmodifiableMap(new HashMap()); + + public Map getValues() { + return values; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1611.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1611.java new file mode 100644 index 0000000000..5969c9f306 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1611.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Issue1611 extends TestCase { + public void test_for_issue() throws Exception { + String pristineJson = "{\"data\":{\"lists\":[{\"Name\":\"Mark\"}]}}"; + JSONArray list = JSON.parseObject(pristineJson).getJSONObject("data").getJSONArray("lists"); + assertEquals(1, list.size()); + for (int i = 0; i < list.size(); i++) { + JSONObject sss = list.getJSONObject(i); + Model model = sss.toJavaObject(Model.class); + assertEquals("Mark", model.name); + } + + } + + public static class Model { + private String name; + + public Model(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1612.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1612.java new file mode 100644 index 0000000000..9bdfed5360 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1612.java @@ -0,0 +1,110 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import org.junit.Test; + +/** + *

Title: Issue1612

+ *

Description:

+ * + * @author Victor + * @version 1.0 + * @since 2017/11/27 + */ +public class Issue1612 { + + @Test + public void test() { + + RegResponse userRegResponse = testFastJson(User.class); + + User user = userRegResponse.getResult(); + System.out.println(user); + + } + + public static RegResponse testFastJson(Class clasz) { + + //把body解析成一个对象 + String body = "{\"retCode\":\"200\", \"result\":{\"name\":\"Zhangsan\",\"password\":\"123\"}}"; + + return JSON.parseObject(body, new TypeReference>(clasz) {}); + } +} + +class RegResponse { + + private String retCode; + private String retDesc; + private T result; + + public String getRetCode() { + return retCode; + } + + public void setRetCode(String retCode) { + this.retCode = retCode; + } + + public String getRetDesc() { + return retDesc; + } + + public void setRetDesc(String retDesc) { + this.retDesc = retDesc; + } + + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } + + @Override + public String toString() { + return "RegResponse{" + + "retCode='" + retCode + '\'' + + ", retDesc='" + retDesc + '\'' + + ", result=" + result + + '}'; + } +} + +class User { + + public User(){} + public User(String username, String password) { + this.username = username; + this.password = password; + } + + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + return "User{" + + "username='" + username + '\'' + + ", password='" + password + '\'' + + '}'; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1627.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1627.java new file mode 100644 index 0000000000..6b8c0eb6e0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1627.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue1627 extends TestCase { + public void test_for_issue() throws Exception { + String a = "{\"101a0.test-b\":\"tt\"}"; + Object o = JSON.parse(a); + String s = "101a0.test-b"; + assertTrue(JSONPath.contains(o, "$." + escapeString(s))); + } + + public static String escapeString(String s) { + StringBuilder buf = new StringBuilder(); + + for(int i = 0; i < s.length(); ++i) { + char c = s.charAt(i); + if((c < 48 || c > 57) && (c < 65 || c > 90) && (c < 97 || c > 122)) { + buf.append("\\" + c); + } else { + buf.append(c); + } + } + + return buf.toString(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1628.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1628.java new file mode 100644 index 0000000000..31904fb4ce --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1628.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeFilter; +import com.alibaba.fastjson.serializer.SimplePropertyPreFilter; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; + +public class Issue1628 extends TestCase { + public void test_toJSONBytes() throws Exception { + Map map = new HashMap(); + map.put("a", 1001); + map.put("b", 2002); + byte[] bytes = JSON.toJSONBytes(map, new SimplePropertyPreFilter("a")); + assertEquals("{\"a\":1001}", new String(bytes)); + } + + public void test_toJSONBytes_1() throws Exception { + Map map = new HashMap(); + map.put("a", 1001); + map.put("b", 2002); + byte[] bytes = JSON.toJSONBytes(map, new SerializeFilter[] {new SimplePropertyPreFilter("a")}); + assertEquals("{\"a\":1001}", new String(bytes)); + } + + public void test_toJSONBytes_2() throws Exception { + Map map = new HashMap(); + map.put("a", 1001); + map.put("b", 2002); + byte[] bytes = JSON.toJSONBytes(map, SerializeConfig.globalInstance, new SimplePropertyPreFilter("a")); + assertEquals("{\"a\":1001}", new String(bytes)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1633.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1633.java new file mode 100644 index 0000000000..7b94869338 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1633.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue1633 extends TestCase { + public void test_for_issue_int() throws Exception { + String text = "{123:\"abc\"}"; + JSONObject obj = JSON.parseObject(text, Feature.NonStringKeyAsString); + assertEquals("abc", obj.getString("123")); + } + + public void test_for_issue_bool() throws Exception { + String text = "{false:\"abc\"}"; + JSONObject obj = JSON.parseObject(text, Feature.NonStringKeyAsString); + assertEquals("abc", obj.getString("false")); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1635.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1635.java new file mode 100644 index 0000000000..8f563ba5e8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1635.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.PascalNameFilter; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue1635 extends TestCase { + public static class Foo { + public String name; + public Integer BarCount; + public Boolean flag; + public List list; + + public Foo(String name, Integer barCount) { + this.name = name; + BarCount = barCount; + } + } + + public void test_issue() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + Foo foo = new Foo(null, null); + String json = JSON.toJSONString(foo + , config, new PascalNameFilter() + , SerializerFeature.WriteNullBooleanAsFalse + , SerializerFeature.WriteNullNumberAsZero + , SerializerFeature.WriteNullStringAsEmpty + , SerializerFeature.WriteNullListAsEmpty + ); + assertEquals("{\"BarCount\":0,\"Flag\":false,\"List\":[],\"Name\":\"\"}", json); + } + + public void test_issue_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + Foo foo = new Foo(null, null); + String json = JSON.toJSONString(foo + , config, new PascalNameFilter() + , SerializerFeature.WriteNullBooleanAsFalse + , SerializerFeature.WriteNullNumberAsZero + , SerializerFeature.WriteNullStringAsEmpty + , SerializerFeature.WriteNullListAsEmpty + , SerializerFeature.BeanToArray + ); + assertEquals("[0,false,[],\"\"]", json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1636.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1636.java new file mode 100644 index 0000000000..7761ecd974 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1636.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue1636 extends TestCase { + public void test_for_issue_1() throws Exception { + Item1 item = JSON.parseObject("{\"modelId\":1001}", Item1.class); + assertEquals(1001, item.modelId); + } + + public void test_for_issue_2() throws Exception { + Item2 item = JSON.parseObject("{\"modelId\":1001}", Item2.class); + assertEquals(1001, item.modelId); + } + + public static class Item1 { + @JSONField + private int modelId; + + @JSONCreator + public Item1(@JSONField int modelId){ + // 这里为零 + this.modelId=modelId; + } + } + + public static class Item2 { + private int modelId; + + @JSONCreator + public Item2(int modelId){ + // 这里为零 + this.modelId=modelId; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1644.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1644.java new file mode 100644 index 0000000000..caa9319bd6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1644.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.sql.Time; + +public class Issue1644 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("time", 1324138987429L); + + Time time = jsonObject.getObject("time", java.sql.Time.class); + assertEquals(1324138987429L, time.getTime()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1645.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1645.java new file mode 100644 index 0000000000..30ac710b4e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1645.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.time.LocalDateTime; + +public class Issue1645 extends TestCase { + public void test_for_issue() throws Exception { + String test = "{\"name\":\"test\",\"testDateTime\":\"2017-12-08 14:55:16\"}"; + JSON.toJSONString(JSON.parseObject(test).toJavaObject(TestDateClass.class), SerializerFeature.PrettyFormat); + } + + public static class TestDateClass{ + public String name; + public LocalDateTime testDateTime; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1647.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1647.java new file mode 100644 index 0000000000..c21dc0be0f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1647.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.PropertyNamingStrategy; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +public class Issue1647 extends TestCase { + public void test_for_issue() throws Exception { + Params params = new Params() + .setVerificationIds(Arrays.asList(new String[]{"a", "b"})) + .setWithFields(true); + + String json = JSON.toJSONString(params); + System.out.println(json); + params = JSON.parseObject(json, Params.class); + assertEquals("{\"verification_ids\":[\"a\",\"b\"],\"with_fields\":true}", JSON.toJSONString(params)); + } + + @JSONType(naming = PropertyNamingStrategy.SnakeCase) + public static class Params { + + private boolean withFields; + + private List verificationIds; + + public boolean isWithFields() { + return withFields; + } + + public Params setWithFields(boolean withFields) { + this.withFields = withFields; + return this; + } + + public List getVerificationIds() { + return verificationIds; + } + + public Params setVerificationIds(List verificationIds) { + this.verificationIds = verificationIds; + return this; + } + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1649.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1649.java new file mode 100644 index 0000000000..f1615f0e4e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1649.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue1649 extends TestCase { + public void test_for_issue() throws Exception { + Apple apple = new Apple(); + String json = JSON.toJSONString(apple); + assertEquals("{\"color\":\"\",\"productCity\":\"\",\"size\":0}", json); + } + + @JSONType(serialzeFeatures = {SerializerFeature.WriteNullStringAsEmpty,SerializerFeature.WriteMapNullValue}) + public static class Apple { + + // @JSONField(serialzeFeatures = {SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue}) + private String color; + private String productCity; + private int size; + + public String getColor() { + return color; + } + + public Apple setColor(String color) { + this.color = color; + return this; + } + + public int getSize() { + return size; + } + + public Apple setSize(int size) { + this.size = size; + return this; + } + + public String getProductCity() { + return productCity; + } + + public Apple setProductCity(String productCity) { + this.productCity = productCity; + return this; + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + + public static void main(String[] args) { + System.out.println(JSON.toJSONString(new Apple())); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1649_private.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1649_private.java new file mode 100644 index 0000000000..4b74d0c008 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1649_private.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue1649_private extends TestCase { + public void test_for_issue() throws Exception { + Apple apple = new Apple(); + String json = JSON.toJSONString(apple); + assertEquals("{\"color\":\"\",\"productCity\":\"\",\"size\":0}", json); + } + + @JSONType(serialzeFeatures = {SerializerFeature.WriteNullStringAsEmpty,SerializerFeature.WriteMapNullValue}) + private static class Apple { + + // @JSONField(serialzeFeatures = {SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue}) + private String color; + private String productCity; + private int size; + + public String getColor() { + return color; + } + + public Apple setColor(String color) { + this.color = color; + return this; + } + + public int getSize() { + return size; + } + + public Apple setSize(int size) { + this.size = size; + return this; + } + + public String getProductCity() { + return productCity; + } + + public Apple setProductCity(String productCity) { + this.productCity = productCity; + return this; + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + + public static void main(String[] args) { + System.out.println(JSON.toJSONString(new Apple())); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1653.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1653.java new file mode 100644 index 0000000000..cf599dc551 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1653.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.MapDeserializer; +import junit.framework.TestCase; +import org.apache.commons.collections4.map.*; + +import java.lang.reflect.Type; +import java.util.Map; + +public class Issue1653 extends TestCase { + public void test_for_issue() throws Exception { +ParserConfig config = new ParserConfig(); +MapDeserializer deserializer = new MapDeserializer() { + public Map createMap(Type type) { + return new CaseInsensitiveMap(); + } +}; +config.putDeserializer(Map.class, deserializer); + +CaseInsensitiveMap root = (CaseInsensitiveMap) JSON.parseObject("{\"val\":{}}", Map.class, config, Feature.CustomMapDeserializer); +CaseInsensitiveMap subMap = (CaseInsensitiveMap) root.get("val"); +assertEquals(0, subMap.size()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1657.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1657.java new file mode 100644 index 0000000000..a0865d37ed --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1657.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.HashMap; + +public class Issue1657 extends TestCase { + public void test_for_issue() throws Exception { + HashMap map = JSON.parseObject("\"\"", HashMap.class); + assertEquals(0, map.size()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1660.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1660.java new file mode 100644 index 0000000000..25214bbc2e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1660.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.*; + +public class Issue1660 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + Model model = new Model(); + model.values.add(new Date(1513755213202L)); + + String json = JSON.toJSONString(model); + assertEquals("{\"values\":[\"2017-12-20\"]}", json); + } + + public static class Model { + @JSONField(format = "yyyy-MM-dd") + private List values = new ArrayList(); + + public List getValues() { + return values; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1662.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1662.java new file mode 100644 index 0000000000..dabf710fce --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1662.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import junit.framework.TestCase; + +import java.io.IOException; +import java.lang.reflect.Type; + +public class Issue1662 extends TestCase { + public void test_for_issue() throws Exception { + + ParserConfig.getGlobalInstance().putDeserializer(Model.class, new ModelValueDeserializer()); + String json = "{\"value\":123}"; + Model model = JSON.parseObject(json, Model.class); + assertEquals("{\"value\":\"12300元\"}",JSON.toJSONString(model)); + + } + + public static class Model { + @JSONField(serializeUsing = ModelValueSerializer.class, deserializeUsing = ModelValueDeserializer.class) + public int value; + } + + public static class ModelValueSerializer implements ObjectSerializer { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, + int features) throws IOException { + Integer value = (Integer) object; + String text = value + "元"; + serializer.write(text); + } + } + + public static class ModelValueDeserializer implements ObjectDeserializer { + + public Model deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONObject obj = (JSONObject)parser.parse(); + Model model = new Model(); + model.value = obj.getInteger("value") * 100; + return model; + } + + public int getFastMatchToken() { + return 0; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1662_1.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1662_1.java new file mode 100644 index 0000000000..71c78bd46d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1662_1.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import junit.framework.TestCase; + +import java.io.IOException; +import java.lang.reflect.Type; + +public class Issue1662_1 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\"value\":123}"; + Model model = JSON.parseObject(json, Model.class); + assertEquals("{\"value\":\"12300元\"}",JSON.toJSONString(model)); + + } + + public static class Model { + @JSONField(serializeUsing = ModelValueSerializer.class, deserializeUsing = ModelValueDeserializer.class) + public int value; + } + + public static class ModelValueSerializer implements ObjectSerializer { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, + int features) throws IOException { + Integer value = (Integer) object; + String text = value + "元"; + serializer.write(text); + } + } + + public static class ModelValueDeserializer implements ObjectDeserializer { + + public Integer deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + Object val = parser.parse(); + return ((Integer) val).intValue() * 100; + } + + public int getFastMatchToken() { + return 0; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1665.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1665.java new file mode 100644 index 0000000000..499e89dea8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1665.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; + +import java.util.Collection; + +public class Issue1665 extends TestCase { + public void test_for_issue() throws Exception { + TypeReference> typeReference = new TypeReference>() {}; + + + Collection collection = TypeUtils.cast(JSON.parse("[{\"id\":101}]"), typeReference.getType(), ParserConfig.getGlobalInstance()); + assertEquals(1, collection.size()); + Model model = collection.iterator().next(); + assertEquals(101, model.id); + } + + public static class Model { + public int id; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1679.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1679.java new file mode 100644 index 0000000000..d538d38825 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1679.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue1679 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + String json = "{\"create\":\"2018-01-10 08:30:00\"}"; + User user = JSON.parseObject(json, User.class); + assertEquals("\"2018-01-10T08:30:00+08:00\"", JSON.toJSONString(user.create, SerializerFeature.UseISO8601DateFormat)); + } + + public static class User{ + public Date create; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1683.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1683.java new file mode 100644 index 0000000000..483aa2d1f2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue1683.java @@ -0,0 +1,64 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue1683 extends TestCase { + public void test_for_issue() throws Exception { + String line = "[2, \"浪漫奇侠\", \"雨天不打伞\", 4536]"; + BookDO book = JSON.parseObject(line, BookDO.class, Feature.SupportArrayToBean); + assertEquals(2L, book.bookId.longValue()); + assertEquals("浪漫奇侠", book.bookName); + assertEquals("雨天不打伞", book.authorName); + assertEquals(4536, book.wordCount.intValue()); + } + + @JSONType(orders = {"bookId", "bookName", "authorName", "wordCount"}) + public static class BookDO { + + private Long bookId; + + private String bookName; + + private String authorName; + + private Integer wordCount; + + + public Long getBookId() { + return bookId; + } + + public void setBookId(Long bookId) { + this.bookId = bookId; + } + + public String getBookName() { + return bookName; + } + + public void setBookName(String bookName) { + this.bookName = bookName; + } + + public String getAuthorName() { + return authorName; + } + + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + public Integer getWordCount() { + return wordCount; + } + + public void setWordCount(Integer wordCount) { + this.wordCount = wordCount; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/Issue_for_gaorui.java b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue_for_gaorui.java new file mode 100644 index 0000000000..0d2c375521 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/Issue_for_gaorui.java @@ -0,0 +1,130 @@ +package com.alibaba.json.bvt.issue_1600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue_for_gaorui extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\"@type\":\"java.util.HashMap\",\"COUPON\":[{\"@type\":\"com.alibaba.json.bvt.issue_1600.Issue_for_gaorui.PromotionTermDetail\",\"activityId\":\"1584034\",\"choose\":true,\"couponId\":1251068987,\"couponType\":\"limitp\",\"match\":true,\"realPrice\":{\"amount\":0.6,\"currency\":\"USD\"}}],\"grayTrade\":\"true\"}"; + + JSON.parseObject(json, Object.class, Feature.SupportAutoType); + } + + public static class PromotionTermDetail { + /** + * 卡券Id + */ + private Long couponId; + /** + * 营销Id + */ + private String promotionId; + /** + * 实际单价 + */ + private Money realPrice; + /** + * 活动Id + */ + private String activityId; + + /** + * 卡券类型 + */ + private String couponType; + + /** + * 是否能够获取到该优惠 + */ + private boolean isMatch = false; + /** + * 是否选择了该优惠 + */ + private boolean isChoose = false; + /** + * 未获取到优惠的原因 + */ + private String reasonForLose; + /** + * 未获取优惠的标识码 + */ + private String codeForLose; + + public Long getCouponId() { + return couponId; + } + + public void setCouponId(Long couponId) { + this.couponId = couponId; + } + + public String getPromotionId() { + return promotionId; + } + + public void setPromotionId(String promotionId) { + this.promotionId = promotionId; + } + + public Money getRealPrice() { + return realPrice; + } + + public void setRealPrice(Money realPrice) { + this.realPrice = realPrice; + } + + public String getActivityId() { + return activityId; + } + + public void setActivityId(String activityId) { + this.activityId = activityId; + } + + public String getCouponType() { + return couponType; + } + + public void setCouponType(String couponType) { + this.couponType = couponType; + } + + public boolean isMatch() { + return isMatch; + } + + public void setMatch(boolean match) { + isMatch = match; + } + + public boolean isChoose() { + return isChoose; + } + + public void setChoose(boolean choose) { + isChoose = choose; + } + + public String getReasonForLose() { + return reasonForLose; + } + + public void setReasonForLose(String reasonForLose) { + this.reasonForLose = reasonForLose; + } + + public String getCodeForLose() { + return codeForLose; + } + + public void setCodeForLose(String codeForLose) { + this.codeForLose = codeForLose; + } + } + + public static class Money { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/TestJson.java b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/TestJson.java new file mode 100644 index 0000000000..e221a6debb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/TestJson.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_1600.issue_1699; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +import java.io.Serializable; + +public class TestJson extends TestCase { + + public void test_for_issue() { + ParserConfig config = new ParserConfig(); + config.setAutoTypeSupport(true); + + System.out.println(JSON.VERSION); + + String event1 = "{\"@type\":\"com.alibaba.json.bvt.issue_1600.issue_1699.obj.RatingDetailBO\",\"amount\":285.600000,\"billId\":3945,\"bizId\":\"6000007==201712==USER_ID==2049884395&&CONTRACT_NO==\\\"no1513922344271\\\"\",\"bizTime\":\"2017-12-31 00:00:00\",\"bizType\":\"6000007\",\"currency\":\"CNY\",\"dealTime\":\"2017-12-23 14:11:03\",\"detailType\":\"CYCLE_CHARGING\",\"extendInfo\":{\"@type\":\"java.util.LinkedHashMap\",\"BUY_AMOUNT\":\"3\",\"P_BIZ_ID\":\"USER_ID==2049884395&&CONTRACT_NO==\\\"no1513922344271\\\"\",\"SETTLE_SIDE\":\"654321\",\"SETTLE_CYCLE_TYPE\":\"3\",\"AUCTION_PRICE\":\"119\",\"CALCULATE_RANGE\":\"STORE\",\"TOTAL_NUM\":\"1\",\"BILL_CYCLE\":\"201712\",\"IS_PRE_CHARGING\":\"false\",\"BRANCH_SHOP\":\"branchShop1\",\"CONTRACT_TYPE\":\"HEMA_CHARGING_PROD\",\"stepRateType\":\"3\",\"SOURCE_TYPE\":\"PURCHASE_ADJUST\",\"SETTLE_SIDE_NICK\":\"测试结算主体\",\"express_value\":\"USER_ID==2049884395&&CONTRACT_NO==\\\"no1513922344271\\\"\",\"BIZ_TIME\":\"2017-12-22 13:59:05\",\"TRADE_ID\":\"1513922344273\",\"QUANTITY\":\"3.000000\",\"MES_RECEIVE_TIME\":\"2017-12-22 13:59:05\",\"UN_TAX_UNIT_PRICE\":\"100.000000\",\"AUCTION_ID\":\"123\",\"AUCTION_NAME\":\"测试商品\",\"rate_value\":\"{\\\"extendInfo\\\":{},\\\"intervalValues\\\":[{\\\"max\\\":600.000000,\\\"min\\\":0.000000,\\\"rate\\\":0.600000},{\\\"max\\\":1000.000000,\\\"min\\\":600.000000,\\\"rate\\\":0.300000},{\\\"max\\\":999999999999.000000,\\\"min\\\":1000.000000,\\\"rate\\\":0.100000}]}\",\"CAT_ID\":\"16\",\"UNIT\":\"kilometer\",\"TERM_NAME\":\"盒马.合同返利.促销推广费\",\"USER_ID\":\"2049884395\",\"UNIT_PRICE\":\"119.000000\",\"tbRuleCode\":\"HM_SETTLE_CHARGING\",\"AMOUNT\":\"357.000000\",\"CAT_NAME\":\"水果\",\"EXTERNAL_NO\":\"HM==1513922344273\",\"CHANNEL\":\"online\",\"is_default_rate\":\"false\",\"CURRENCY\":\"CNY\",\"rate_rule_id\":\"300000531\",\"OTHER_USER_NICK\":\"甲方\",\"RATE_TYPE\":\"14\",\"ITEM_NAME\":\"盒马.促销推广费\",\"rate_rule_inst_id\":\"1009129180821\",\"TAX_RATE\":\"0.190000\",\"ITEM_CODE\":\"BILL_HM_6000007\",\"CONTRACT_SIDE\":\"12345\",\"UNTAX_AMOUNT\":\"300.000000\",\"CONTRACT_VERSION\":\"V001\",\"CONTRACT_NO\":\"no1513922344271\",\"P_TRADE_ID\":\"1513922344273\"},\"gmtCreate\":\"2017-12-23 14:11:03\",\"gmtModified\":\"2017-12-23 14:11:03\",\"id\":6235300020395,\"indexNum\":0,\"innerId\":6300120395,\"innerTable\":\"SETTLE_DATA\",\"isJoin\":\"FALSE\",\"itemId\":90000000007031,\"mesId\":3235,\"mesReceiveTime\":\"2017-12-22 13:59:05\",\"outBizId\":\"USER_ID==2049884395&&CONTRACT_NO==\\\"no1513922344271\\\"\",\"pTradeId\":3235,\"priority\":0,\"proration\":0.6,\"quantity\":476.000000,\"rateDefineId\":40000443,\"rateParams\":{\"@type\":\"java.util.LinkedHashMap\"},\"status\":\"SUCCESS\",\"tradeId\":3761,\"userId\":2049884395,\"userNick\":\"乙方\",\"version\":1}"; + Serializable obj = JSON.parseObject(event1, Serializable.class, config); + System.out.println(obj); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/FeeTypeMEnum.java b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/FeeTypeMEnum.java new file mode 100644 index 0000000000..088cd0ec98 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/FeeTypeMEnum.java @@ -0,0 +1,7 @@ +package com.alibaba.json.bvt.issue_1600.issue_1699.def; + +public enum FeeTypeMEnum { + TRADE, + REFUND; + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/InnerTypeMEnum.java b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/InnerTypeMEnum.java new file mode 100644 index 0000000000..a7aae6be4d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/InnerTypeMEnum.java @@ -0,0 +1,74 @@ +package com.alibaba.json.bvt.issue_1600.issue_1699.def; + +public enum InnerTypeMEnum { + + CHARGE_ORDER, + + PAY_ORDER, + + PAY_ORDER_DTL, + + SUB_DETAIL, + + BILL, + + FC_BILL, + + STEP_OPS_BILL, + + FC_USER_BILL, + + INIT, + + WRITEOFFBILL, + GW_MSG, + + REFUND_ORDER, + RATING_DETAIL, + + COUPON, + + SETTLE_BILL, + + SETTLEMENT_BILL, + + SETTLEMENT_BILL_SUM, + + WORKFLOW_INSTANCE, + + CONTRACT, + + WITHDRAW_ORDER, + + BANK_TRANSFER, + + SOURCE_DATA, + + SETTLE_DATA, + + CONTRACT_TERM_INST, + + MERGE_PAY_ORDER, + + FUNDS_TRANSFER_ORDER, + + SETTLE_POOL, + + SETTLE_POOL_JOURNAL, + + OFFLINE_REMITTANCE, + + OUT_SYSTEM_TRANSFER, + + HJ_EXECUTE_RULE, + + HJ_DISBURSE_INFO, + + USER_BILL, + + HJ_EXECUTE_PLAN + + ; + + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailIsJoinMEnum.java b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailIsJoinMEnum.java new file mode 100644 index 0000000000..950105090d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailIsJoinMEnum.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_1600.issue_1699.def; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public enum RatingDetailIsJoinMEnum { + + FALSE, + TRUE; + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailStatusMEnum.java b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailStatusMEnum.java new file mode 100644 index 0000000000..3dddc527c7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailStatusMEnum.java @@ -0,0 +1,11 @@ +package com.alibaba.json.bvt.issue_1600.issue_1699.def; + +public enum RatingDetailStatusMEnum { + + INIT, + SUCCESS, + FAIL, + WAIT; + + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailTypeMEnum.java b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailTypeMEnum.java new file mode 100644 index 0000000000..cc99e0211e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/def/RatingDetailTypeMEnum.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.issue_1600.issue_1699.def; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public enum RatingDetailTypeMEnum { + + COMM, + FC, + PRE_FC, + USAGE, + HPTX, + SUB_MONTH_FC, + COMM_DAY_FC, + COMM_MONTH_FC, + ADJUST, + FOREX_COMM, + COMM_REALTIME_FC, + OVERSETTLE_COMM, + FC_RATING, + PRE_TREAT, + REALTIME_CHARGING, + CYCLE_CHARGING, + SHARE_CHARGING, + ; + + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/obj/RatingDetailBO.java b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/obj/RatingDetailBO.java new file mode 100644 index 0000000000..2f955d6760 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1600/issue_1699/obj/RatingDetailBO.java @@ -0,0 +1,463 @@ +package com.alibaba.json.bvt.issue_1600.issue_1699.obj; + +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.json.bvt.issue_1600.issue_1699.def.InnerTypeMEnum; +import com.alibaba.json.bvt.issue_1600.issue_1699.def.RatingDetailIsJoinMEnum; +import com.alibaba.json.bvt.issue_1600.issue_1699.def.*; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Currency; +import java.util.Date; +import java.util.Map; + +/** + * + */ +public class RatingDetailBO implements Serializable { + + private static final long serialVersionUID = 6413142622719509002L; + + /** + * * + */ + private Long id; + + /** + * 用户ID + */ + private Long userId; + + /** + * 用户NICK + */ + private String userNick; + + /** + * 消息ID + */ + private Long mesId; + + /** + * 事件类型, 枚举值参照:ra_event_object.type + */ + private String eventType; + + /** + * 唯一去重号 + */ + private String bizId; + + /** + * 序列号 + */ + private Integer indexNum; + + /** + * 业务类型(同原始消息) + */ + private String bizType; + + /** + * 业务交易号 + */ + private String outBizId; + + /** + * 主订单ID + */ + private Long pTradeId; + + /** + * 子订单ID + */ + private Long tradeId; + + /** + * 业务交易时间 + */ + private Date bizTime; + + /** + * 消息接收时间 + */ + private Date mesReceiveTime; + + /** + * 处理时间 + */ + private Date dealTime; + + /** + * 详单科目编号 + */ + private Long itemId; + + /** + * 详单类型: 1、普通详单 2、分成详单 3、预收分成详单 + */ + private RatingDetailTypeMEnum detailType; + + /** + * 原始金额 + */ + private BigDecimal quantity; + + /** + * 金额 + */ + private BigDecimal amount; + + /** + * 费率编号 + */ + private Long rateDefineId; + + /** + * 计费因子 + */ + private BigDecimal proration; + + /** + * 产品编号 + */ + private Long prodId; + + /** + * 扩展信息 + */ + private Map extendInfo; + + private Map rateParams; + + private Currency currency; + + private InnerTypeMEnum innerTable; + private Long innerId; + + public Map getRateParams() { + return rateParams; + } + + public void setRateParams(Map rateParams) { + this.rateParams = rateParams; + } + + public Currency getCurrency() { + return currency; + } + + public void setCurrency(Currency currency) { + this.currency = currency; + } + + public InnerTypeMEnum getInnerTable() { + return innerTable; + } + + public void setInnerTable(InnerTypeMEnum innerTable) { + this.innerTable = innerTable; + } + + public Long getInnerId() { + return innerId; + } + + public void setInnerId(Long innerId) { + this.innerId = innerId; + } + + public void setExtendInfo(Map extendInfo) { + this.extendInfo = extendInfo; + } + + /** + * 环境标识 + */ + private String ownSign; + + /** + * 帐单ID, 记账结束后回写 + */ + private Long billId; + + /** + * 版本编号 + */ + private Integer version; + + /** + * 是否合并付款: 0、否 1、是 + */ + private RatingDetailIsJoinMEnum isJoin; + + /** + * 优先级, 值越大,优先级越高 + */ + private Integer priority; + + /** + * 状态: 0、初始 1、处理成功; 2、处理失败; 3、等待合并; + */ + private RatingDetailStatusMEnum status; + + /** + * 创建时间 + */ + private Date gmtCreate; + + /** + * 修改时间 + */ + private Date gmtModified; + + /** + * 交易项目:0、交易;1、退款 + */ + private FeeTypeMEnum feeType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getUserNick() { + return userNick; + } + + public void setUserNick(String userNick) { + this.userNick = userNick; + } + + public Long getMesId() { + return mesId; + } + + public void setMesId(Long mesId) { + this.mesId = mesId; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public String getBizId() { + return bizId; + } + + public void setBizId(String bizId) { + this.bizId = bizId; + } + + public String getBizType() { + return bizType; + } + + public void setBizType(String bizType) { + this.bizType = bizType; + } + + public String getOutBizId() { + return outBizId; + } + + public void setOutBizId(String outBizId) { + this.outBizId = outBizId; + } + + public Long getpTradeId() { + return pTradeId; + } + + public void setpTradeId(Long pTradeId) { + this.pTradeId = pTradeId; + } + + public Long getTradeId() { + return tradeId; + } + + public void setTradeId(Long tradeId) { + this.tradeId = tradeId; + } + + public Date getBizTime() { + return bizTime; + } + + public void setBizTime(Date bizTime) { + this.bizTime = bizTime; + } + + public Date getMesReceiveTime() { + return mesReceiveTime; + } + + public void setMesReceiveTime(Date mesReceiveTime) { + this.mesReceiveTime = mesReceiveTime; + } + + public Date getDealTime() { + return dealTime; + } + + public void setDealTime(Date dealTime) { + this.dealTime = dealTime; + } + + public Long getItemId() { + return itemId; + } + + public void setItemId(Long itemId) { + this.itemId = itemId; + } + + public Long getRateDefineId() { + return rateDefineId; + } + + public void setRateDefineId(Long rateDefineId) { + this.rateDefineId = rateDefineId; + } + + public Long getProdId() { + return prodId; + } + + public void setProdId(Long prodId) { + this.prodId = prodId; + } + + public String getOwnSign() { + return ownSign; + } + + public void setOwnSign(String ownSign) { + this.ownSign = ownSign; + } + + public Long getBillId() { + return billId; + } + + public void setBillId(Long billId) { + this.billId = billId; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + + public Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + public Date getGmtModified() { + return gmtModified; + } + + public void setGmtModified(Date gmtModified) { + this.gmtModified = gmtModified; + } + + public RatingDetailTypeMEnum getDetailType() { + return detailType; + } + + public void setDetailType(RatingDetailTypeMEnum detailType) { + this.detailType = detailType; + } + + public RatingDetailIsJoinMEnum getIsJoin() { + return isJoin; + } + + public void setIsJoin(RatingDetailIsJoinMEnum isJoin) { + this.isJoin = isJoin; + } + + public RatingDetailStatusMEnum getStatus() { + return status; + } + + public void setStatus(RatingDetailStatusMEnum status) { + this.status = status; + } + + public FeeTypeMEnum getFeeType() { + return feeType; + } + + public void setFeeType(FeeTypeMEnum feeType) { + this.feeType = feeType; + } + + public Map getExtendInfo() { + return extendInfo; + } + + public BigDecimal getQuantity() { + return quantity; + } + + public void setQuantity(BigDecimal quantity) { + this.quantity = quantity; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public BigDecimal getProration() { + return proration; + } + + public void setProration(BigDecimal proration) { + this.proration = proration; + } + + public Integer getIndexNum() { + return indexNum; + } + + public void setIndexNum(Integer indexNum) { + this.indexNum = indexNum; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1701.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1701.java new file mode 100644 index 0000000000..01d16e9b1c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1701.java @@ -0,0 +1,120 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration +public class Issue1701 { + + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac) // + .addFilter(new CharacterEncodingFilter("UTF-8", true)) // 设置服务器端返回的字符集为:UTF-8 + .build(); + } + + + @RestController + @RequestMapping() + public static class BeanController { + + @PostMapping(path = "/download", produces = "application/octet-stream;charset=UTF-8") + public @ResponseBody + ResponseEntity download(@RequestBody TestBean testBean) { + + byte[] body = new byte[0]; + InputStream in; + try { + in = Issue1701.class.getClassLoader().getResourceAsStream(testBean.getName()); + body = new byte[in.available()]; + in.read(body); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Disposition", "attachment;filename=1.txt"); + HttpStatus statusCode = HttpStatus.OK; + ResponseEntity response = new ResponseEntity(body, headers, statusCode); + + return response; + } + } + + + @ComponentScan(basePackages = "com.alibaba.json.bvt.issue_1700") + @Configuration + @EnableWebMvc + public static class WebMvcConfig extends WebMvcConfigurerAdapter { + + @Override + public void extendMessageConverters(List> converters) { + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON_UTF8)); + converters.add(0, converter); + } + } + + @Test + public void testBean() throws Exception { + mockMvc.perform( + (post("/download").characterEncoding("UTF-8") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content("{\"name\": \"1.txt\"}") + )).andExpect(status().isOk()).andDo(print()); + + } + + static class TestBean { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1723.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1723.java new file mode 100644 index 0000000000..8a70e32080 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1723.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue1723 extends TestCase { + public void test_for_issue() throws Exception { + User user = JSON.parseObject("{\"age\":\"0.9390308260917664\"}", User.class); + assertEquals(0.9390308260917664F, user.age); + } + + public void test_for_issue_1() throws Exception { + User user = JSON.parseObject("{\"age\":\"8.200000000000001\"}", User.class); + assertEquals(8.200000000000001F, user.age); + } + + public void test_for_issue_2() throws Exception { + User user = JSON.parseObject("[\"8.200000000000001\"]", User.class, Feature.SupportArrayToBean); + assertEquals(8.200000000000001F, user.age); + } + + public static class User { + private float age; + public float getAge() { + return age; + } + public void setAge(float age) { + this.age = age; + } + @Override + public String toString() { + return "User{" + + "age=" + age + + '}'; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1725.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1725.java new file mode 100644 index 0000000000..8391930499 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1725.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; + +public class Issue1725 extends TestCase { + public void test_for_issue() throws Exception { + Map map= new HashMap(); + map.put("enumField", 0); + + AbstractBean bean = JSON.parseObject(JSON.toJSONString(map), ConcreteBean.class); + assertEquals(FieldEnum.A, bean.enumField); + } + + public static class AbstractBean { + public FieldEnum enumField; + } + + public static class ConcreteBean extends AbstractBean { + + } + + public static enum FieldEnum { A, B } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1727.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1727.java new file mode 100644 index 0000000000..d92cc345ce --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1727.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.Date; + +public class Issue1727 extends TestCase { + public void test_for_issue() throws Exception { + String jsonString = "{\"gmtCreate\":\"20180131214157805-0800\"}"; + JSONObject.parseObject(jsonString, Model.class); //正常解析 + JSONObject.toJavaObject(JSON.parseObject(jsonString), Model.class); + } + + public static class Model { + @JSONField(format="yyyyMMddHHmmssSSSZ") + public Date gmtCreate; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1733_jsonpath.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1733_jsonpath.java new file mode 100644 index 0000000000..4e0cf8eb51 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1733_jsonpath.java @@ -0,0 +1,72 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +public class Issue1733_jsonpath extends TestCase { + public void test_for_issue() throws Exception { + Order order = new Order(); + order.books.add(new Book(10, "动漫")); + order.books.add(new Book(50, "科幻")); + order.books.add(new Book(60, "历史")); + + String path = "$.books[price>20 && category = '科幻']"; + List result = (List) JSONPath.eval(order, path); + assertSame(1, result.size()); + assertSame(order.books.get(1), result.get(0)); + } + + public void test_for_issue_or() throws Exception { + Order order = new Order(); + order.books.add(new Book(10, "动漫")); + order.books.add(new Book(50, "科幻")); + order.books.add(new Book(60, "历史")); + + String path = "$.books[price>20||category = '科幻']"; + List result = (List) JSONPath.eval(order, path); + assertEquals(2, result.size()); + assertSame(order.books.get(1), result.get(0)); + assertSame(order.books.get(2), result.get(1)); + } + + public void test_for_issue_or_1() throws Exception { + Order order = new Order(); + order.books.add(new Book(10, "动漫")); + order.books.add(new Book(50, "科幻")); + order.books.add(new Book(60, "历史")); + + String path = "$.books[category = '动漫' ||category = '科幻']"; + List result = (List) JSONPath.eval(order, path); + assertEquals(2, result.size()); + assertSame(order.books.get(0), result.get(0)); + assertSame(order.books.get(1), result.get(1)); + } + + public static class Order { + public List books = new ArrayList(); + + } + + public static class Book { + public BigDecimal price; + public String category; + + public Book() { + + } + + public Book(int price, String category) { + this(new BigDecimal(price), category); + } + + public Book(BigDecimal price, String category) { + this.price = price; + this.category = category; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1739.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1739.java new file mode 100644 index 0000000000..0250963871 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1739.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue1739 extends TestCase { + public void test_for_issue() throws Exception { + M0 model = new M0(); + model.data = new JSONObject(); + + String json = JSON.toJSONString(model); + assertEquals("{\"data\":{}}", json); + } + + public void test_for_issue_1() throws Exception { + M1 model = new M1(); + model.data = new JSONObject(); + + String json = JSON.toJSONString(model); + assertEquals("{}", json); + } + + public static class M0 { + private JSONObject data; + + @JSONField(deserialize = false) + public JSONObject getData() { + return data; + } + + public void setData(JSONObject data) { + this.data = data; + } + } + + public static class M1 { + private JSONObject data; + + @JSONField(serialize = false) + public JSONObject getData() { + return data; + } + + public void setData(JSONObject data) { + this.data = data; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1761.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1761.java new file mode 100644 index 0000000000..09ccce7bf9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1761.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Issue1761 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("null",""); + double d = jsonObject.getDoubleValue("null"); + assertEquals(d, 0.0D); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1763.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1763.java new file mode 100644 index 0000000000..847e718e53 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1763.java @@ -0,0 +1,72 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +public class Issue1763 extends TestCase { + public void test_for_issue() throws Exception { + String s = "{\"result\":{\"modelList\":[{\"sourceId\":\"81900002\"},{\"sourceId\":\"81900002\"},{\"sourceId\":\"81892012\"},{\"sourceId\":\"2062014\"},{\"sourceId\":\"2082007\"},{\"sourceId\":\"2082007\"},{\"sourceId\":\"2082007\"}]}}"; + + + Method method = ProcurementOrderInteractiveServiceForCloud.class.getMethod("queryOrderMateriel", Map.class); + Type type = method.getGenericReturnType(); + + BaseResult baseResult = JSON.parseObject(s, type); + InteractiveOrderMaterielQueryResult result = baseResult.getResult(); + + assertEquals(7, result.getModelList().size()); + assertEquals(InteractiveOrderMaterielModel.class, result.getModelList().get(0).getClass()); + } + + public static class BaseResult { + private T result; + + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } + } + + public static class BasePageQueryResult extends BaseResult{ + private List modelList; + + public List getModelList() { + return modelList; + } + + public void setModelList(List modelList) { + this.modelList = modelList; + } + } + + public static class InteractiveOrderMaterielModel { + private String sourceId; + + public String getSourceId() { + return sourceId; + } + + public void setSourceId(String sourceId) { + this.sourceId = sourceId; + } + } + + public static class InteractiveOrderMaterielQueryResult extends BasePageQueryResult { + + } + + public interface ProcurementOrderInteractiveServiceForCloud { + + BaseResult queryOrderMateriel(Map param); + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764.java new file mode 100644 index 0000000000..08eda23640 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import static com.alibaba.fastjson.serializer.SerializerFeature.BrowserCompatible; + +public class Issue1764 extends TestCase { + public void test_for_issue() throws Exception { + Model model = new Model(); + model.value = 9007199254741992L; + + String str = JSON.toJSONString(model); + assertEquals("{\"value\":\"9007199254741992\"}", str); + } + + public static class Model { + @JSONField(serialzeFeatures = BrowserCompatible) + public long value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean.java new file mode 100644 index 0000000000..f688ba7a35 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +import static com.alibaba.fastjson.serializer.SerializerFeature.BrowserCompatible; + +public class Issue1764_bean extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("{\"value\":\"9007199254741992\"}" + , JSON.toJSONString( + new Model(9007199254741992L))); + + assertEquals("{\"value\":\"9007199254741990\"}" + , JSON.toJSONString( + new Model(9007199254741990L))); + + assertEquals("{\"value\":100}" + , JSON.toJSONString( + new Model(100L))); + + assertEquals("{\"value\":\"-9007199254741990\"}" + , JSON.toJSONString( + new Model(-9007199254741990L))); + + assertEquals("{\"value\":-9007199254740990}" + , JSON.toJSONString( + new Model(-9007199254740990L))); + + } + + + + @JSONType(serialzeFeatures = BrowserCompatible) + public static class Model { + public long value; + + public Model() { + + } + + public Model(long value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger.java new file mode 100644 index 0000000000..60da8e4a71 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.math.BigInteger; + +import static com.alibaba.fastjson.serializer.SerializerFeature.BrowserCompatible; + +public class Issue1764_bean_biginteger extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("{\"value\":\"9007199254741992\"}" + , JSON.toJSONString( + new Model(9007199254741992L), BrowserCompatible)); + + assertEquals("{\"value\":\"-9007199254741992\"}" + , JSON.toJSONString( + new Model(-9007199254741992L), BrowserCompatible)); + + assertEquals("{\"value\":9007199254740990}" + , JSON.toJSONString( + new Model(9007199254740990L), BrowserCompatible)); + + assertEquals("{\"value\":-9007199254740990}" + , JSON.toJSONString( + new Model(-9007199254740990L), BrowserCompatible)); + + assertEquals("{\"value\":100}" + , JSON.toJSONString( + new Model(100), BrowserCompatible)); + + assertEquals("{\"value\":-100}" + , JSON.toJSONString( + new Model(-100), BrowserCompatible)); + } + + + + + public static class Model { + public BigInteger value; + + public Model() { + + } + + public Model(long value) { + this.value = BigInteger.valueOf(value); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger_field.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger_field.java new file mode 100644 index 0000000000..0a34adaef2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger_field.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +import java.math.BigInteger; + +import static com.alibaba.fastjson.serializer.SerializerFeature.BrowserCompatible; + +public class Issue1764_bean_biginteger_field extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("{\"value\":\"9007199254741992\"}" + , JSON.toJSONString( + new Model(9007199254741992L))); + + assertEquals("{\"value\":\"-9007199254741992\"}" + , JSON.toJSONString( + new Model(-9007199254741992L))); + + assertEquals("{\"value\":9007199254740990}" + , JSON.toJSONString( + new Model(9007199254740990L))); + + assertEquals("{\"value\":-9007199254740990}" + , JSON.toJSONString( + new Model(-9007199254740990L))); + + assertEquals("{\"value\":100}" + , JSON.toJSONString( + new Model(100))); + + assertEquals("{\"value\":-100}" + , JSON.toJSONString( + new Model(-100))); + } + + + + + public static class Model { + @JSONField(serialzeFeatures = BrowserCompatible) + public BigInteger value; + + public Model() { + + } + + public Model(long value) { + this.value = BigInteger.valueOf(value); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger_type.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger_type.java new file mode 100644 index 0000000000..4e4fe9d423 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1764_bean_biginteger_type.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +import java.math.BigInteger; + +import static com.alibaba.fastjson.serializer.SerializerFeature.BrowserCompatible; + +public class Issue1764_bean_biginteger_type extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("{\"value\":\"9007199254741992\"}" + , JSON.toJSONString( + new Model(9007199254741992L))); + + assertEquals("{\"value\":\"-9007199254741992\"}" + , JSON.toJSONString( + new Model(-9007199254741992L))); + + assertEquals("{\"value\":9007199254740990}" + , JSON.toJSONString( + new Model(9007199254740990L))); + + assertEquals("{\"value\":-9007199254740990}" + , JSON.toJSONString( + new Model(-9007199254740990L))); + + assertEquals("{\"value\":100}" + , JSON.toJSONString( + new Model(100))); + + assertEquals("{\"value\":-100}" + , JSON.toJSONString( + new Model(-100))); + } + + + + @JSONType(serialzeFeatures = BrowserCompatible) + public static class Model { + public BigInteger value; + + public Model() { + + } + + public Model(long value) { + this.value = BigInteger.valueOf(value); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1766.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1766.java new file mode 100644 index 0000000000..5f533fab68 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1766.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.Date; + +public class Issue1766 extends TestCase { + public void test_for_issue() throws Exception { +// succ + String json = "{\"name\":\"张三\"\n, \"birthday\":\"2017-01-01 01:01:01\"}"; + User user = JSON.parseObject(json, User.class); + assertEquals("张三", user.getName()); + assertNotNull(user.getBirthday()); + + // failed + json = "{\"name\":\"张三\", \"birthday\":\"2017-01-01 01:01:02\"\n}"; + user = JSON.parseObject(json, User.class);// will exception + assertEquals("张三", user.getName()); + assertNotNull(user.getBirthday()); + } + + public static class User + { + private String name; + + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private Date birthday; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public Date getBirthday() + { + return birthday; + } + + public void setBirthday(Date birthday) + { + this.birthday = birthday; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1769.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1769.java new file mode 100644 index 0000000000..fddbff508a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1769.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue1769 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + byte[] newby = "{\"beginTime\":\"420180319160440\"}".getBytes(); + QueryTaskResultReq rsp3 = JSON.parseObject(newby, QueryTaskResultReq.class); + assertEquals("{\"beginTime\":\"152841225111920\"}", new String(JSON.toJSONBytes(rsp3))); + } + + @JSONType(orders = {"beginTime"}) + public static class QueryTaskResultReq + { + private Date beginTime; + + @JSONField(format = "yyyyMMddHHmmss") + public Date getBeginTime() { + return beginTime; + } + + public void setBeginTime(Date beginTime) { + this.beginTime = beginTime; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1772.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1772.java new file mode 100644 index 0000000000..b6b170f8d0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1772.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Issue1772 extends TestCase { + public void test_0() throws Exception { + Date date = JSON.parseObject("\"-14189155200000\"", Date.class); + assertEquals(-14189155200000L, date.getTime()); + } + + public void test_1() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("time", "-14189155200000"); + + Model m = jsonObject.toJavaObject(Model.class); + assertEquals(-14189155200000L, m.time.getTime()); + } + + public static class Model { + public Date time; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1780_JSONObject.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1780_JSONObject.java new file mode 100644 index 0000000000..299460cc17 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1780_JSONObject.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import org.junit.Assert; +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue1780_JSONObject extends TestCase { + + public void test_for_issue() { + org.json.JSONObject req = new org.json.JSONObject(); + req.put("id", 1111); + req.put("name", "name11"); + String text = JSON.toJSONString(req, SerializerFeature.SortField); + assertTrue("{\"id\":1111,\"name\":\"name11\"}".equals(text) + || "{\"name\":\"name11\",\"id\":1111}".equals(text) + ); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1780_Module.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1780_Module.java new file mode 100644 index 0000000000..8bae18215d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1780_Module.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.issue_1700; + +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.spi.Module; + +import junit.framework.TestCase; + +public class Issue1780_Module extends TestCase { + + public void test_for_issue() { + org.json.JSONObject req = new org.json.JSONObject(); + + SerializeConfig config = new SerializeConfig(); + config.register(new myModule()); + req.put("id", 1111); + req.put("name", "name11"); + String text = JSON.toJSONString(req, SerializerFeature.SortField); + + assertTrue("{\"id\":1111,\"name\":\"name11\"}".equals(text) || "{\"name\":\"name11\",\"id\":1111}".equals(text)); + } + + public class myModule implements Module { + + @SuppressWarnings("rawtypes") + public ObjectDeserializer createDeserializer(ParserConfig config, Class type) { + return null; + } + + @SuppressWarnings("rawtypes") + public ObjectSerializer createSerializer(SerializeConfig config, Class type) { + return new ObjectSerializer() { + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, + int features) throws IOException { + System.out.println("-------------myModule.createSerializer-------------------"); + org.json.JSONObject req = (org.json.JSONObject) object; + serializer.out.write(req.toString()); + } + }; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1785.java b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1785.java new file mode 100644 index 0000000000..66ff970481 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/Issue1785.java @@ -0,0 +1,10 @@ +package com.alibaba.json.bvt.issue_1700; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue1785 extends TestCase { + public void test_for_issue() throws Exception { + JSON.parseObject("\"2006-8-9\"", java.sql.Timestamp.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/TestIssue1763_2.java b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/TestIssue1763_2.java new file mode 100644 index 0000000000..58d40927fc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/TestIssue1763_2.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.issue_1700.issue1763_2; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.json.bvt.issue_1700.issue1763_2.bean.BaseResult; +import com.alibaba.json.bvt.issue_1700.issue1763_2.bean.CouponResult; +import com.alibaba.json.bvt.issue_1700.issue1763_2.bean.PageResult; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Test Issue 1763_2 + * 如果有多层泛型且前面泛型已经实现的情况下,判断下一级泛型 + * @author cnlyml + */ +public class TestIssue1763_2 { + private String jsonStr; + private Class clazz; + + @Before + public void init() { + jsonStr = "{\"code\":0, \"message\":\"Success\", \"content\":{\"pageNum\":1, \"pageSize\":2, \"size\":2, \"startRow\":1, \"endRow\":1, \"total\":2, \"pages\":1, \"list\":[{\"id\":10000001, \"couponName\":\"Test1\"}, {\"id\":10000002, \"couponName\": \"Test2\"}]}}"; + clazz = (Class) CouponResult.class; + } + + // 修复test + @Test + public void testFixBug1763_2() { + BaseResult> data = JSON.parseObject(jsonStr, new TypeReference>>(clazz){}.getType()); + + Assert.assertTrue(data.isSuccess()); + Assert.assertTrue(data.getContent().getList().size() == 2); + Assert.assertTrue(data.getContent().getList().get(0).getId().equals(10000001L)); + Assert.assertEquals(CouponResult.class, data.getContent().getList().get(0).getClass()); + } + + // 复现BUG + @Test + public void testBug1763_2() { + BaseResult> data = JSON.parseObject(jsonStr, new TypeReferenceBug1763_2>>(clazz){}.getType()); + + Assert.assertTrue(data.isSuccess()); + Assert.assertTrue(data.getContent().getList().size() == 2); + try { + data.getContent().getList().get(0).getId(); + } catch (Throwable ex) { + Assert.assertEquals(ex.getCause() instanceof ClassCastException, false); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/TypeReferenceBug1763_2.java b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/TypeReferenceBug1763_2.java new file mode 100644 index 0000000000..fcc06daa99 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/TypeReferenceBug1763_2.java @@ -0,0 +1,89 @@ +package com.alibaba.json.bvt.issue_1700.issue1763_2; + +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.util.ParameterizedTypeImpl; +import com.alibaba.fastjson.util.TypeUtils; + +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class TypeReferenceBug1763_2 { + + static ConcurrentMap classTypeCache + = new ConcurrentHashMap(16, 0.75f, 1); + + protected final Type type; + + /** + * Constructs a new type literal. Derives represented class from type + * parameter. + * + *

Clients create an empty anonymous subclass. Doing so embeds the type + * parameter in the anonymous class's type hierarchy so we can reconstitute it + * at runtime despite erasure. + */ + protected TypeReferenceBug1763_2(){ + Type superClass = getClass().getGenericSuperclass(); + + Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; + + Type cachedType = classTypeCache.get(type); + if (cachedType == null) { + classTypeCache.putIfAbsent(type, type); + cachedType = classTypeCache.get(type); + } + + this.type = cachedType; + } + + /** + * @since 1.2.9 + * @param actualTypeArguments + */ + protected TypeReferenceBug1763_2(Type... actualTypeArguments){ + Class thisClass = this.getClass(); + Type superClass = thisClass.getGenericSuperclass(); + + ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0]; + Type rawType = argType.getRawType(); + Type[] argTypes = argType.getActualTypeArguments(); + + int actualIndex = 0; + for (int i = 0; i < argTypes.length; ++i) { + if (argTypes[i] instanceof TypeVariable && + actualIndex < actualTypeArguments.length) { + argTypes[i] = actualTypeArguments[actualIndex++]; + } + // fix for openjdk and android env + if (argTypes[i] instanceof GenericArrayType) { + argTypes[i] = TypeUtils.checkPrimitiveArray( + (GenericArrayType) argTypes[i]); + } + + } + + Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); + Type cachedType = classTypeCache.get(key); + if (cachedType == null) { + classTypeCache.putIfAbsent(key, key); + cachedType = classTypeCache.get(key); + } + + type = cachedType; + + } + + /** + * Gets underlying {@code Type} instance. + */ + public Type getType() { + return type; + } + + public final static Type LIST_STRING = new TypeReference>() {}.getType(); +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/BaseResult.java b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/BaseResult.java new file mode 100644 index 0000000000..50b33dde91 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/BaseResult.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.issue_1700.issue1763_2.bean; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * BaseResult + * + * @author cnlyml + */ +public class BaseResult { + private static final Integer SUCCESS_CODE = 0; + + private Integer code; + private String message; + @JSONField(name = "content") + private T content; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getContent() { + return content; + } + + public void setContent(T content) { + this.content = content; + } + + public boolean isSuccess() { + return code.equals(SUCCESS_CODE); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/CouponResult.java b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/CouponResult.java new file mode 100644 index 0000000000..c3710477e7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/CouponResult.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.issue_1700.issue1763_2.bean; + + +/** + * + * @author cnlyml + */ +public class CouponResult{ + /** + * 优惠券ID + */ + private Long id; + + /** + * 优惠券名称 + */ + private String couponName; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getCouponName() { + return couponName; + } + + public void setCouponName(String couponName) { + this.couponName = couponName; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/PageResult.java b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/PageResult.java new file mode 100644 index 0000000000..9a061e06c6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1700/issue1763_2/bean/PageResult.java @@ -0,0 +1,85 @@ +package com.alibaba.json.bvt.issue_1700.issue1763_2.bean; + +import java.util.List; + +/** + * 分页信息 + * @param + * + * @author cnlyml + */ +public class PageResult { + private Integer pageNum; + private Integer pageSize; + private Integer size; + private Integer startRow; + private Integer endRow; + private Integer total; + private Integer pages; + + private List list; + + public Integer getPageNum() { + return pageNum; + } + + public void setPageNum(Integer pageNum) { + this.pageNum = pageNum; + } + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + public Integer getStartRow() { + return startRow; + } + + public void setStartRow(Integer startRow) { + this.startRow = startRow; + } + + public Integer getEndRow() { + return endRow; + } + + public void setEndRow(Integer endRow) { + this.endRow = endRow; + } + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + public Integer getPages() { + return pages; + } + + public void setPages(Integer pages) { + this.pages = pages; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1821.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1821.java new file mode 100644 index 0000000000..8ee96cb2dc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1821.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +public class Issue1821 extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"type\":800,\"data\":\"HuYgMIxwfqdtvOJNv6kK025g5fh3yFHI2kaByO7udKk6FOBC3PGRWkGfwV0\\/vWQW6roN5ftKDHFZ3PWl0715OYue0rZj\\/VwrNsMvIL4MqTUNBBUGFU9SgZu87ss7RqmyijH6\\/sM968cK1Dv5U7Rrw79idl\\/hW8SILLn1YXvUa60=\"}"; + String expectStr = "{\"type\":800,\"data\":\"HuYgMIxwfqdtvOJNv6kK025g5fh3yFHI2kaByO7udKk6FOBC3PGRWkGfwV0/vWQW6roN5ftKDHFZ3PWl0715OYue0rZj/VwrNsMvIL4MqTUNBBUGFU9SgZu87ss7RqmyijH6/sM968cK1Dv5U7Rrw79idl/hW8SILLn1YXvUa60=\"}"; + Model m = JSON.parseObject(str, Model.class); + assertEquals(expectStr, JSON.toJSONString(m)); + + str = "{\"type\":800,\"data\":\"Y29tLmFsaWJhYmEuZmFzdGpzb24=\"}"; + m = JSON.parseObject(str, Model.class); + assertEquals(str, JSON.toJSONString(m)); + assertEquals("com.alibaba.fastjson", new String(m.data)); + + expectStr = str; + str = "{\"type\":800,\"data\":\"\\u005929tLmFsaWJ\\u0068YmEuZmFzdGpzb24\\u003d\"}"; + m = JSON.parseObject(str, Model.class); + assertEquals(expectStr, JSON.toJSONString(m)); + assertEquals("com.alibaba.fastjson", new String(m.data)); + + } + + @JSONType + public static class Model { + @JSONField(name="type", ordinal = 1) + public int type; + + @JSONField(name="data", ordinal = 2) + public byte[] data; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1834.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1834.java new file mode 100644 index 0000000000..f5e52f33e2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1834.java @@ -0,0 +1,65 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +public class Issue1834 extends TestCase { + public void test_for_issue() throws Exception { + IndexQuery_Number query_number = new IndexQuery_Number(); + IndexQuery_Comparable query_comparable = new IndexQuery_Comparable(); + List keys = Arrays.asList(1234); + query_number.setKeys(keys); + query_comparable.setKeys(keys); + + String json1 = JSON.toJSONString(query_number); + System.out.println(json1); + IndexQuery_Number queryNumber = JSON.parseObject(json1, new TypeReference(){}); + + String json2 = JSON.toJSONString(query_comparable); + System.out.println(json2); + IndexQuery_Comparable queryComparable = JSON.parseObject(json2, new TypeReference(){}); + } + + static class IndexQuery_Comparable{ + List keys; + + public List getKeys() { + return keys; + } + + public void setKeys(List keys) { + this.keys = keys; + } + + @Override + public String toString() { + return "IndexQuery{" + + "keys=" + keys + + '}'; + } + } + + static class IndexQuery_Number{ + List keys; + + public List getKeys() { + return keys; + } + + public void setKeys(List keys) { + this.keys = keys; + } + + @Override + public String toString() { + return "IndexQuery{" + + "keys=" + keys + + '}'; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1856.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1856.java new file mode 100644 index 0000000000..ca1b38d70b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1856.java @@ -0,0 +1,63 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.Labels; +import junit.framework.TestCase; + +public class Issue1856 extends TestCase { + public void test_excludes() throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + vo.setPassword("ooxxx"); + vo.setInfo("fofo"); + + String text = JSON.toJSONString(vo, Labels.excludes("AuditIdEntity")); + assertEquals("{\"id\":123,\"info\":\"fofo\",\"name\":\"wenshao\"}", text); + } + + public static class VO { + + private int id; + private String name; + private String password; + private String info; + + @JSONField(label = "LogicDeleteEntity") + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @JSONField(label = "LogicDeleteEntity") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @JSONField(label = "AuditIdEntity") + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getInfo() { + return info; + } + + public void setInfo(String info) { + this.info = info; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1870.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1870.java new file mode 100644 index 0000000000..5a3176baa4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1870.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue1870 extends TestCase { + public void test_for_issue() throws Exception { + + } + + public static class Comment { + @JSONField(name = "pic_arr") + public List pics; + + + public List getPics() { + return pics; + } + + public void setPics(List pics) { + this.pics = pics; + } + } + + public static class Pic { + public int height; + public String tburl; + public String url; + public String width; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1871.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1871.java new file mode 100644 index 0000000000..6f1101fdc9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1871.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +public class Issue1871 extends TestCase { + public void test_for_issue() throws Exception { + UnwrapClass m = new UnwrapClass(); + m.map = new HashMap(); + m.name = "ljw"; + m.map.put("a", "1"); + m.map.put("b", "2"); + + String json = JSON.toJSONString(m, SerializerFeature.WriteClassName); + System.out.println(json); + } + + public static class UnwrapClass { + + private String name; + + @JSONField(unwrapped = true) + private Map map; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1879.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1879.java new file mode 100644 index 0000000000..52dbe24f08 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1879.java @@ -0,0 +1,63 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +public class Issue1879 extends TestCase { +// public void test_for_issue() throws Exception { +// String json = "{\n" + +// " \"ids\" : \"1,2,3\"\n" + +// "}"; +// M1 m = JSON.parseObject(json, M1.class); +// } + + public void test_for_issue_2() throws Exception { + String json = "{\n" + + " \"ids\" : \"1,2,3\"\n" + + "}"; + M2 m = JSON.parseObject(json, M2.class); + } + + public static class M1 { + private List ids; + + @JSONCreator + public M1(@JSONField(name = "ids") String ids) { + this.ids = new ArrayList(); + for(String id : ids.split(",")) { + this.ids.add(Long.valueOf(id)); + } + } + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + } + + public static class M2 { + private List ids; + + @JSONCreator + public M2(@JSONField(name = "ids") Long id) { + this.ids = new ArrayList(); + this.ids.add(id); + } + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1892.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1892.java new file mode 100644 index 0000000000..25ea825fd8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue1892.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.time.LocalDateTime; + +public class Issue1892 extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("\"2018-10-10T00:00:00\"", + JSON.toJSONString( + LocalDateTime.of(2018, 10, 10, 0, 0) + ) + ); + } + + public void test_for_issue_1() throws Exception { + String json = JSON.toJSONString( + LocalDateTime.of(2018, 10, 10, 0, 0, 40, 788000000) + ); + assertEquals("\"2018-10-10T00:00:40.788\"", json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue_for_dianxing.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue_for_dianxing.java new file mode 100644 index 0000000000..8d73c10ab1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue_for_dianxing.java @@ -0,0 +1,75 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue_for_dianxing extends TestCase { + public void test_0() throws Exception { + String s = "{\"alarmLevel\":null,\"error\":null,\"errorCount\":0,\"maxAlarmCount\":10,\"warn\":null," + + "\"warnCount\":0}"; + TopAlarm b = JSON.parseObject(s, TopAlarm.class); + System.out.println(JSON.toJSONString(b)); + } + + public static class TopAlarm { + + private Double error; //为null表示不报警 + private int errorCount; + private Double warn; //为null表示不报警 + private int warnCount; + private Integer alarmLevel; + private int maxAlarmCount = 10; + + public TopAlarm() { + } + + public Double getError() { + return error; + } + + public void setError(Double error) { + this.error = error; + } + + public Double getWarn() { + return warn; + } + + public void setWarn(Double warn) { + this.warn = warn; + } + + public int getErrorCount() { + return errorCount; + } + + public void setErrorCount(int errorCount) { + this.errorCount = errorCount; + } + + public int getWarnCount() { + return warnCount; + } + + public void setWarnCount(int warnCount) { + this.warnCount = warnCount; + } + + public Integer getAlarmLevel() { + return alarmLevel; + } + + public void setAlarmLevel(Integer alarmLevel) { + this.alarmLevel = alarmLevel; + } + + public int getMaxAlarmCount() { + return maxAlarmCount; + } + + public void setMaxAlarmCount(int maxAlarmCount) { + this.maxAlarmCount = maxAlarmCount; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1800/Issue_for_float_zero.java b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue_for_float_zero.java new file mode 100644 index 0000000000..2a61bd9896 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1800/Issue_for_float_zero.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.issue_1800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue_for_float_zero extends TestCase { + public void test_0() throws Exception { + M1 m = new M1(1.0f); + assertEquals("{\"val\":1.0}", JSON.toJSONString(m, SerializerFeature.WriteNullNumberAsZero)); + } + + public void test_1() throws Exception { + M2 m = new M2(1.0); + assertEquals("{\"val\":1.0}", JSON.toJSONString(m, SerializerFeature.WriteNullNumberAsZero)); + } + + public static class M1 { + public float val; + + public M1(float val) { + this.val = val; + } + } + + public static class M2 { + public double val; + + public M2(double val) { + this.val = val; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1901.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1901.java new file mode 100644 index 0000000000..488a3da1c6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1901.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue1901 extends TestCase { + protected Locale locale; + protected TimeZone timeZone; + protected void setUp() throws Exception { + locale = JSON.defaultLocale; + timeZone = JSON.defaultTimeZone; + JSON.defaultLocale = Locale.CHINA; + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + } + + protected void tearDown() throws Exception { + JSON.defaultLocale = locale; + JSON.defaultTimeZone = timeZone; + } + + public void test_for_issue() throws Exception { + Model m = JSON.parseObject("{\"time\":\"Thu Mar 22 08:58:37 +0000 2018\"}", Model.class); + assertEquals("{\"time\":\"星期四 三月 22 16:58:37 CST 2018\"}", JSON.toJSONString(m)); + } + + public void test_for_issue_1() throws Exception { + Model m = JSON.parseObject("{\"time\":\"星期四 三月 22 16:58:37 CST 2018\"}", Model.class); + assertEquals("{\"time\":\"星期四 三月 22 16:58:37 CST 2018\"}", JSON.toJSONString(m)); + } + + public static class Model { + @JSONField(format = "EEE MMM dd HH:mm:ss zzz yyyy") + public Date time; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1903.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1903.java new file mode 100644 index 0000000000..f7ac9719a7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1903.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.beans.Transient; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; +public class Issue1903 extends TestCase { + public void test_issue() throws Exception { + MapHandler mh = new MapHandler(); + mh.add("name", "test"); + mh.add("age", 20); + + Issues1903 issues = (Issues1903) Proxy.newProxyInstance(mh.getClass().getClassLoader(), new Class[]{Issues1903.class}, mh); + System.out.println(issues.getName()); + System.out.println(issues.getAge()); + + System.out.println(JSON.toJSON(issues).toString()); //正确结果: {"age":20} + System.out.println(JSON.toJSONString(issues)); //正确结果: {"age":20} + Assert.assertEquals("{\"age\":20}", JSON.toJSON(issues).toString()); + Assert.assertEquals("{\"age\":20}", JSON.toJSONString(issues)); + } + + interface Issues1903{ + @Transient + @JSONField(serialzeFeatures = { SerializerFeature.SkipTransientField }) + public String getName(); + public void setName(String name); + + public Integer getAge(); + public void setAge(Integer age); + } + + + class MapHandler implements InvocationHandler { + Map map = new HashMap(); + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String name = method.getName().substring(3); + String first = String.valueOf(name.charAt(0)); + name = name.replaceFirst(first, first.toLowerCase()); + return map.get(name); + } + + public void add(String key, Object val){ + map.put(key, val); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1909.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1909.java new file mode 100644 index 0000000000..06f149d8d6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1909.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue1909 extends TestCase { + public void test_for_issue() throws Exception { + JSONArray params = new JSONArray(); + params.add("val1"); + params.add(2); + ParamRequest pr = new ParamRequest("methodName", "stringID", params); + System.out.println(JSON.toJSONString(pr)); + Request paramRequest = JSON.parseObject(JSON.toJSONString(pr), ParamRequest.class); + } + + public static class ParamRequest extends Request { + private String methodName; + + @JSONField(name = "id", ordinal = 3, serialize = true, deserialize = true) + private Object id; + + private List params; + + public ParamRequest(String methodName, Object id, List params) { + this.methodName = methodName; + this.id = id; + this.params = params; + } + + public String getMethodName() { + return methodName; + } + + public Object getId() { + return id; + } + + public List getParams() { + return params; + } + } + + public static class Request { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1933.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1933.java new file mode 100644 index 0000000000..348e9b3583 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1933.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue1933 extends TestCase { + public void test_for_issue() throws Exception { + OrderInfoVO v0 = JSON.parseObject("{\"orderStatus\":1}", OrderInfoVO.class); + assertEquals(1, v0.orderStatus); + assertEquals(0, v0.oldStatus); + assertEquals(0, v0.oldOrderStatus); + } + + public void test_for_issue_1() throws Exception { + OrderInfoVO v0 = JSON.parseObject("{\"oldStatus\":1}", OrderInfoVO.class); + assertEquals(0, v0.orderStatus); + assertEquals(1, v0.oldStatus); + assertEquals(0, v0.oldOrderStatus); + } + + + public void test_for_issue_2() throws Exception { + OrderInfoVO v0 = JSON.parseObject("{\"oldOrderStatus\":1}", OrderInfoVO.class); + assertEquals(0, v0.orderStatus); + assertEquals(0, v0.oldStatus); + assertEquals(1, v0.oldOrderStatus); + } + + + public static class OrderInfoVO { + private int orderStatus; + private int oldStatus; + private int oldOrderStatus; + + public int getOrderStatus() { + return orderStatus; + } + + public void setOrderStatus(int orderStatus) { + this.orderStatus = orderStatus; + } + + public int getOldStatus() { + return oldStatus; + } + + public void setOldStatus(int oldStatus) { + this.oldStatus = oldStatus; + } + + public int getOldOrderStatus() { + return oldOrderStatus; + } + + public void setOldOrderStatus(int oldOrderStatus) { + this.oldOrderStatus = oldOrderStatus; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1939.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1939.java new file mode 100644 index 0000000000..e54c6a4b38 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1939.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.annotation.*; +import java.io.Serializable; +import java.io.StringReader; +import java.util.List; + +public class Issue1939 extends TestCase { + @XmlRootElement(name = "Container") + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "any" + }) + public static class Container implements Serializable { + @XmlAnyElement(lax = true) + public List any; + } + private static final String MESSAGE = "" + + "0" + + ""; + + public void test_for_issue() throws Exception { + JAXBContext context = JAXBContext.newInstance(Container.class, Issue1939.class); + Container con = (Container) context.createUnmarshaller().unmarshal(new StringReader(MESSAGE)); + assertEquals("{\"any\":[\"0\"]}", + JSON.toJSONString(con)); + } + + public void test_for_issue_1() throws Exception { + JAXBContext context = JAXBContext.newInstance(Container.class, Issue1939.class); + Container con = (Container) context.createUnmarshaller().unmarshal(new StringReader(MESSAGE)); + assertEquals("{\"any\":[\"0\"]}", + JSON.toJSON(con).toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1941.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1941.java new file mode 100644 index 0000000000..0f0b981ee6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1941.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +public class Issue1941 extends TestCase { + + public void test_for_issue() throws Exception { + String json = "{\"type\":\"floorV2\",\"templateId\":\"x123\",\"name\":\"floorname2\"}"; + FloorV2 a=(FloorV2) JSON.parseObject(json,Area.class); + assertEquals("floorname2", a.name); + assertEquals("x123", a.templateId); + } + + @JSONType(seeAlso = {FloorV2.class}, typeKey = "type") + public static interface Area { + } + + @JSONType(typeName = "floorV2") + public static class FloorV2 implements Area { + public String type; + public String templateId; + public String name; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1941_JSONField_order.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1941_JSONField_order.java new file mode 100644 index 0000000000..9261c947b6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1941_JSONField_order.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; + +public class Issue1941_JSONField_order extends TestCase { + + public void test_for_issue() throws Exception { + String json = "{\"type\":\"floorV2\",\"templateId\":\"x123\",\"name\":\"floorname2\"}"; + FloorV2 a=(FloorV2) JSON.parseObject(json,Area.class); + assertEquals("floorname2", a.name); + assertEquals("x123", a.templateId); + } + + @JSONType(seeAlso = {FloorV2.class}, typeKey = "type") + public static interface Area { + } + + @JSONType(typeName = "floorV2") + public static class FloorV2 implements Area { + @JSONField(ordinal = -1) + public String type; + public String templateId; + public String name; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1944.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1944.java new file mode 100644 index 0000000000..e0e3294665 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1944.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue1944 extends TestCase { + public void test_for_issue() throws Exception { + assertEquals(90.82195113f, JSON.parseObject("{\"value\":90.82195113}", Model.class).value); + } + + public static class Model { + public float value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1945.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1945.java new file mode 100644 index 0000000000..d76f39d4c7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1945.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import static com.alibaba.fastjson.serializer.SerializerFeature.WriteClassName; + +public class Issue1945 extends TestCase { + public void test_0() throws Exception { + B b = new B(); + b.clazz = new Class[]{String.class}; + b.aInstance = new HashMap(); + b.aInstance.put("test", "test"); + String s = JSON.toJSONString(b, WriteClassName); + System.out.println(s); + B a1 = JSON.parseObject(s, B.class); + } + + static class B implements Serializable { + public Class[] clazz; + public Map aInstance; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1955.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1955.java new file mode 100644 index 0000000000..549c868df1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1955.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue1955 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + String strVal = "0100-01-27 11:22:00.000"; + Date date = JSON.parseObject('"' + strVal + '"', Date.class); + + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA); + df.setTimeZone(JSON.defaultTimeZone); + + assertEquals(df.parse(strVal), date); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1972.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1972.java new file mode 100644 index 0000000000..a77b802670 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1972.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue1972 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject jsonObject = new JSONObject(); + final JSONObject a = new JSONObject(); + final JSONObject b = new JSONObject(); + a.put("b", b); + + b.put("c", "2018-04"); + b.put("d", new JSONArray()); + + Integer obj = Integer.valueOf(123); + + jsonObject.put("a", a); + JSONPath.arrayAdd(jsonObject,"$.a.b[c = '2018-04'].d", obj); + + assertEquals("{\"a\":{\"b\":{\"c\":\"2018-04\",\"d\":[123]}}}", jsonObject.toString()); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1977.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1977.java new file mode 100644 index 0000000000..00645d72ab --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1977.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.Locale; +import java.util.TimeZone; + +public class Issue1977 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + java.sql.Date date = new java.sql.Date(1533265119604L); + String json = JSON.toJSONString(date, SerializerFeature.UseISO8601DateFormat); + assertEquals("\"2018-08-03T10:58:39.604+08:00\"", json); +// new java.sql.Date(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1987.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1987.java new file mode 100644 index 0000000000..a26da283c7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1987.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.time.LocalDateTime; + +public class Issue1987 extends TestCase { + public void test_for_issue() throws Exception { + JsonExample example = new JsonExample(); + + //test1 正确执行, test2, test3 执行出错 com.alibaba.fastjson.JSONException: can not cast to : java.time.LocalDateTime + example.setTestLocalDateTime(LocalDateTime.now()); + + //纳秒数设置为0 ,test1,test2,test3 全部正确执行 + //example.setTestLocalDateTime(LocalDateTime.now().withNano(0)); + String text = JSON.toJSONString(example, SerializerFeature.PrettyFormat); + System.out.println(text); + + //test1, 全部可以正常执行 + JsonExample example1 = JSON.parseObject(text, JsonExample.class); + System.out.println(JSON.toJSONString(example1)); + + //test2 纳秒数为0, 可以正常执行, 不为0则报错 + JsonExample example2 = JSONObject.parseObject(text).toJavaObject(JsonExample.class); + System.out.println(JSON.toJSONString(example2)); + + //test3 纳秒数为0, 可以正常执行, 不为0则报错 + JsonExample example3 = JSON.parseObject(text).toJavaObject(JsonExample.class); + System.out.println(JSON.toJSONString(example3)); + } + + public static class JsonExample { + + private LocalDateTime testLocalDateTime; + + public LocalDateTime getTestLocalDateTime() { + return testLocalDateTime; + } + + public void setTestLocalDateTime(LocalDateTime testLocalDateTime) { + this.testLocalDateTime = testLocalDateTime; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1996.java b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1996.java new file mode 100644 index 0000000000..e3b039b8d9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1900/Issue1996.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.issue_1900; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue1996 extends TestCase { + public void test_for_issue() throws Exception { + StringBuilder sb = new StringBuilder(); + + char start = '\uD800'; + char end = '\uDFFF'; + + for (char i = start; i <= end; i++) { + if (Character.isLowSurrogate(i)) { + sb.append(i); + } + } + String s = sb.toString(); + + // ok + String json1 = JSON.toJSONString(s); + byte[] bytes = json1.getBytes("utf-8"); + + byte[] bytes2 = JSON.toJSONBytes(s); + assertEquals(new String(bytes), new String(bytes2)); + + assertEquals(bytes.length, bytes2.length); + for (int i = 0; i < bytes.length; i++) { + assertEquals(bytes[i], bytes[i]); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2012.java b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2012.java new file mode 100644 index 0000000000..abc4654c4f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2012.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.issue_2000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue2012 extends TestCase { + public void test_for_issue() throws Exception { + Model foo = new Model(); + foo.bytes = new byte[0]; + String str = JSON.toJSONString(foo, SerializerFeature.WriteClassName); + assertEquals("{\"@type\":\"com.alibaba.json.bvt.issue_2000.Issue2012$Model\",\"bytes\":x''}", str); + + ParserConfig config = new ParserConfig(); + config.setAutoTypeSupport(true); + foo = JSON.parseObject(str, Object.class,config); + assertEquals(0, foo.bytes.length); + } + + public static class Model { + public byte[] bytes; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2040.java b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2040.java new file mode 100644 index 0000000000..9f3306463c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2040.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.issue_2000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.fasterxml.jackson.databind.ObjectMapper; +import junit.framework.TestCase; +import org.gitlab4j.api.GitLabApi; +import org.gitlab4j.api.GitLabApiException; +import org.gitlab4j.api.models.AccessLevel; +import org.gitlab4j.api.models.Permissions; +import org.gitlab4j.api.models.Project; +import org.gitlab4j.api.models.Visibility; + +import java.util.List; + +public class Issue2040 extends TestCase { + final ParserConfig config = new ParserConfig(); + protected void setUp() throws Exception { + config.setJacksonCompatible(true); + } + + public void test_for_issue_2040() throws Exception { + Model model = JSON.parseObject("{\"accessLevel\":30,\"visibility\":\"PUBLIC\"}", Model.class, config); + assertSame(AccessLevel.DEVELOPER, model.accessLevel); + } + + public void test_for_issue_2040_2() throws Exception { + String json = "{\n" + + " \"project_access\": null,\n" + + " \"group_access\": {\n" + + " \"access_level\": 50,\n" + + " \"notification_level\": 3\n" + + " }\n" + + " }"; + + ObjectMapper objectMapper = new ObjectMapper(); +// Permissions permissions = objectMapper.readValue(json, Permissions.class); + + Permissions permissions = JSON.parseObject(json, Permissions.class, config); + System.out.println(JSON.toJSONString(permissions)); + } + + public static class Model { + public AccessLevel accessLevel; + public Visibility visibility; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2065.java b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2065.java new file mode 100644 index 0000000000..e5091199d6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2065.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.issue_2000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Test; + +public class Issue2065 extends TestCase { + + public void test_for_issue() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"code\":1}", Model.class); + } catch (JSONException e) { + error = e; + } + assertNotNull(error); + error.printStackTrace(); + } + + public void test_for_issue_01() { + Exception error = null; + try { + JSON.parseObject("1", EnumClass.class); + } catch (JSONException e) { + error = e; + } + assertNotNull(error); + error.printStackTrace(); + } + + @Test + public void test_for_issue_02() { + JSON.parseObject("0", EnumClass.class); + } + + @Test + public void test_for_issue_03() { + JSON.parseObject("{\"code\":0}", Model.class); + } + + public static class Model { + @JSONField(name = "code") + private EnumClass code; + + public Model() {} + + public EnumClass getCode() { + return code; + } + + public void setCode(EnumClass code) { + this.code = code; + } + } + + public static enum EnumClass { + A(1); + + @JSONField + private int code; + + EnumClass(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2066.java b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2066.java new file mode 100644 index 0000000000..769ad9aa56 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2066.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.issue_2000; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue2066 extends TestCase { + + + public void test_issue() throws Exception { + JSON.parseObject("{\"values\":[[1,2],[3,4]]}", Model.class); + } + + public static class Model { + private List values; + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2074.java b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2074.java new file mode 100644 index 0000000000..54efeb7946 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2074.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.issue_2000; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue2074 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject object = new JSONObject(); + object.put("name", null); + + assertEquals("{\"name\":null}" + , object.toString(SerializerFeature.WriteMapNullValue)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2086.java b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2086.java new file mode 100644 index 0000000000..3a03e6b3b8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2086.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.issue_2000; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue2086 extends TestCase { + public void test_for_issue() throws Exception { + JSON.parseObject("{\"id\":123}", Model.class); + JSON.toJSONString(new Model()); + } + + public static class Model { + public void set() { + + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2088.java b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2088.java new file mode 100644 index 0000000000..041ca07c68 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2000/Issue2088.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.issue_2000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue2088 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + String json = "{\"date\":\"20181011103607186+0800\"}"; + Model m = JSON.parseObject(json, Model.class); + + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSSZ"); + format.setTimeZone(JSON.defaultTimeZone); + Date date = format.parse("20181011103607186+0800"); + + assertEquals(date, m.date); + } + + public void test_for_issue_1() throws Exception { + String json = "{\"date\":\"20181011103607186-0800\"}"; + Model m = JSON.parseObject(json, Model.class); + + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSSZ", JSON.defaultLocale); + format.setTimeZone(JSON.defaultTimeZone); + Date date = format.parse("20181011103607186-0800"); + + assertEquals(date, m.date); + } + + public static class Model { + @JSONField(format = "yyyyMMddHHmmssSSSZ") + public Date date; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2129.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2129.java new file mode 100644 index 0000000000..e7b6847c4d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2129.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSON; +import com.google.common.collect.LinkedHashMultimap; +import junit.framework.TestCase; + +public class Issue2129 extends TestCase { + public void test_for_issue() throws Exception { + LinkedHashMultimap map = LinkedHashMultimap.create(); + map.put("a", "1"); + map.put("a", "b"); + map.put("b", "1"); + String json = JSON.toJSONString(map); + assertEquals("{\"a\":[\"1\",\"b\"],\"b\":[\"1\"]}", json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2130.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2130.java new file mode 100644 index 0000000000..39fbff6f31 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2130.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Issue2130 extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"score\":0.000099369485}"; + JSONObject object = JSON.parseObject(str); + assertEquals("{\"score\":0.000099369485}", object.toJSONString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2132.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2132.java new file mode 100644 index 0000000000..61b96d3d09 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2132.java @@ -0,0 +1,145 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +public class Issue2132 extends TestCase { + public void test_for_issue() throws Exception { + Cpu cpu = new Cpu("intel", 3.3); + Screen screen = new Screen(16, 9, "samsung"); + Student student = new Student(); + Computer computer = student.assembling(cpu,screen); + cpu.setName("intell"); + + Object[] objectArray = new Object[4]; + objectArray[0] = cpu; + objectArray[1] = screen; + objectArray[2] = "2"; + objectArray[3] = "3"; + List list1 = new ArrayList(); + list1.add(objectArray); + list1.add(computer); + String s = JSON.toJSONString(list1); + + assertEquals("[[{\"name\":\"intell\",\"speed\":3.3},{\"height\":9,\"name\":\"samsung\",\"width\":16},\"2\",\"3\"],{\"cpu\":{\"$ref\":\"$[0][0]\"},\"screen\":{\"$ref\":\"$[0][1]\"}}]", s); + } + + public static class Cpu { + private String name; + private double speed; + + public Cpu(String name, double speed) { + this.name = name; + this.speed = speed; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + } + + public static class Screen { + private int width; + private int height; + private String name; + + public Screen(int width, int height, String name) { + this.width = width; + this.height = height; + this.name = name; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class Computer { + Cpu cpu; + Screen screen; + + public Computer(Cpu cpu, Screen screen) { + this.cpu = cpu; + this.screen = screen; + } + + public Cpu getCpu() { + return cpu; + } + + public void setCpu(Cpu cpu) { + this.cpu = cpu; + } + + public Screen getScreen() { + return screen; + } + + public void setScreen(Screen screen) { + this.screen = screen; + } + } + + public static class Student { + private Cpu cpu; + private Screen screen; + + public Computer assembling(Cpu cpu, Screen screen) { + this.cpu = cpu; + this.screen = screen; + + return new Computer(cpu, screen); + } + + public Cpu getCpu() { + return cpu; + } + + public void setCpu(Cpu cpu) { + this.cpu = cpu; + } + + public Screen getScreen() { + return screen; + } + + public void setScreen(Screen screen) { + this.screen = screen; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2150.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2150.java new file mode 100644 index 0000000000..527faddb3a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2150.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSONArray; +import junit.framework.TestCase; + +public class Issue2150 extends TestCase { + public void test_for_issue() throws Exception { + int [][][] arr = new int[100][100][100]; + JSONArray jsonObj = (JSONArray) JSONArray.toJSON(arr); + assertNotNull(jsonObj); + assertNotNull(jsonObj.getJSONArray(0)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2156.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2156.java new file mode 100644 index 0000000000..462f9bd97b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2156.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.text.SimpleDateFormat; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue2156 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + +// public void test_for_issue() throws Exception { +// SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); +// sf.setTimeZone(JSON.defaultTimeZone); +// java.sql.Date date = new java.sql.Date(sf.parse("2018-07-15").getTime()); +// String str = JSON.toJSONStringWithDateFormat(date, JSON.DEFFAULT_DATE_FORMAT); +// assertEquals("\"2018-07-15\"", str); +// } +// +// public void test_for_issue1() throws Exception { +// SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); +// sf.setTimeZone(JSON.defaultTimeZone); +// java.sql.Date date = new java.sql.Date(sf.parse("2018-07-15").getTime()); +// String str = JSON.toJSONStringWithDateFormat(date, JSON.DEFFAULT_DATE_FORMAT); +// assertEquals("\"2018-07-15\"", str); +// } +// +// public void test_for_issue2() throws Exception { +// SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); +// sf.setTimeZone(JSON.defaultTimeZone); +// java.sql.Date date = java.sql.Date.valueOf("2018-07-15"); +// String str = JSON.toJSONStringWithDateFormat(date, JSON.DEFFAULT_DATE_FORMAT); +// assertEquals("\"2018-07-15\"", str); +// } + + public void test_for_issue_time() throws Exception { + java.sql.Time date = java.sql.Time.valueOf("12:13:14"); + String str = JSON.toJSONStringWithDateFormat(date, JSON.DEFFAULT_DATE_FORMAT); + assertEquals("\"12:13:14\"", str); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2164.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2164.java new file mode 100644 index 0000000000..8c12793a34 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2164.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue2164 extends TestCase { + public void test_for_issue() throws Exception { + java.sql.Timestamp ts = new java.sql.Timestamp(-65001600000L); + String json = JSON.toJSONString(ts); + assertEquals("-65001600000", json); + java.sql.Timestamp ts2 = JSON.parseObject(json, java.sql.Timestamp.class); + assertEquals(ts.getTime(), ts2.getTime()); + } + + public void test_for_issue_1() throws Exception { + Model m = new Model(-65001600000L); + String json = JSON.toJSONString(m); + assertEquals("{\"time\":-65001600000}", json); + Model m2 = JSON.parseObject(json, Model.class); + assertEquals(m.time.getTime(), m2.time.getTime()); + } + + public static class Model { + public java.sql.Timestamp time; + + public Model() { + + } + + public Model(long ts) { + this.time = new java.sql.Timestamp(ts); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2165.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2165.java new file mode 100644 index 0000000000..3982df7957 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2165.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue2165 extends TestCase { + + public void test_for_issue() throws Exception { + Exception error = null; + try { + JSON.parseObject("9295260120", Integer.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals("parseInt error", error.getMessage()); + } + + public void test_for_issue_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"value\":9295260120}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals("parseInt error, field : value", error.getMessage()); + } + + public void test_for_issue_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("[9295260120]", Model.class, Feature.SupportArrayToBean); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals("parseInt error : 9295260120", error.getMessage()); + } + + public static class Model { + public int value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2179.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2179.java new file mode 100644 index 0000000000..b76da71d21 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2179.java @@ -0,0 +1,330 @@ +package com.alibaba.json.bvt.issue_2100; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Type; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.StringCodec; +import com.alibaba.fastjson.spi.Module; + +import junit.framework.TestCase; + +public class Issue2179 extends TestCase { + + // 场景:序列化 + public void test_for_issue() throws Exception { + Model1 model = new Model1(ProductType1.Phone, ProductType1.Computer); + String out = "{\"l_k_assbalv4\":{\"code\":1,\"prompt\":\"手机\"},\"type1\":{\"code\":2,\"prompt\":\"电脑\"}}"; + Assert.assertEquals(out, JSON.toJSONString(model)); + } + + // 场景:使用@JSONType的deserializer = EnumAwareSerializer1.class测试自定义反序列化器 + public void test_for_issue2() { + String str = "{\"l_k_assbalv4\":{\"code\":1,\"prompt\":\"手机\"},\"type1\":{\"code\":2,\"prompt\":\"电脑\"}}"; + Model1 model = JSON.parseObject(str, Model1.class); + String out = "{\"l_k_assbalv4\":{\"code\":1,\"prompt\":\"手机\"},\"type1\":{\"code\":2,\"prompt\":\"电脑\"}}"; + Assert.assertEquals(out, JSON.toJSONString(model)); + } + + // 场景:使用@JSONField的deserializeUsing = EnumAwareSerializer2.class测试自定义测试自定义反序化器 + public void test_for_issue3() { + // l_k_assbalv4对应Model2中的Type走自定义,type1走默认枚举反序列化 + String str = "{\"l_k_assbalv4\":{\"code\":1,\"prompt\":\"手机\"},\"type1\":\"Computer\"}"; + Model2 model = JSON.parseObject(str, Model2.class); + String out = "{\"l_k_assbalv4\":{\"code\":1,\"prompt\":\"手机\"},\"type1\":{\"code\":2,\"prompt\":\"电脑\"}}"; + Assert.assertEquals(out, JSON.toJSONString(model)); + } + + // 场景:使用Module + public void test_for_issue4() { + ParserConfig config = new ParserConfig(); + config.register(new MyModuel()); + + String str = "{\"type\":\"Phone\",\"type1\":\"Computer\"}"; + Model3 model = JSON.parseObject(str, Model3.class, config); + String out = "{\"type\":{\"code\":2,\"prompt\":\"电脑\"},\"type1\":{\"code\":1,\"prompt\":\"手机\"}}"; + Assert.assertEquals(out, JSON.toJSONString(model)); + } + + interface EnumAware { + int getCode(); + + String getPrompt(); + } + + @JSONType(serializeEnumAsJavaBean = true, deserializer = EnumAwareSerializer1.class) + public static enum ProductType1 implements EnumAware { + Phone(1, "手机"), Computer(2, "电脑"); + + public final int code; + public final String prompt; + + ProductType1(int code, String prompt) { + this.code = code; + this.prompt = prompt; + } + + @Override + public int getCode() { + return this.code; + } + + @Override + public String getPrompt() { + return this.prompt; + } + + public static ProductType1 get(int code) { + switch (code) { + case 1: + return Phone; + case 2: + return Computer; + default: + return null; + } + } + } + + public static class Model1 { + @JSONField(name = "l_k_assbalv4") + private ProductType1 type; + private ProductType1 type1; + + public Model1(ProductType1 type, ProductType1 type1) { + this.type = type; + this.type1 = type1; + } + + public ProductType1 getType() { + return type; + } + + public void setType(ProductType1 type) { + this.type = type; + } + + public ProductType1 getType1() { + return type1; + } + + public void setType1(ProductType1 type1) { + this.type1 = type1; + } + } + + @JSONType(serializeEnumAsJavaBean = true) + public static enum ProductType2 implements EnumAware { + Phone(1, "手机"), Computer(2, "电脑"); + + public final int code; + public final String prompt; + + ProductType2(int code, String prompt) { + this.code = code; + this.prompt = prompt; + } + + @Override + public int getCode() { + return this.code; + } + + @Override + public String getPrompt() { + return this.prompt; + } + + public static ProductType2 get(int code) { + switch (code) { + case 1: + return Phone; + case 2: + return Computer; + default: + return null; + } + } + } + + public static class Model2 { + @JSONField(name = "l_k_assbalv4", deserializeUsing = EnumAwareSerializer2.class) + private ProductType2 type; + private ProductType2 type1; + + public Model2(ProductType2 type, ProductType2 type1) { + this.type = type; + this.type1 = type1; + } + + public ProductType2 getType() { + return type; + } + + public void setType(ProductType2 type) { + this.type = type; + } + + public ProductType2 getType1() { + return type1; + } + + public void setType1(ProductType2 type1) { + this.type1 = type1; + } + } + + @JSONType(serializeEnumAsJavaBean = true) + public static enum ProductType3 implements EnumAware { + Phone(1, "手机"), Computer(2, "电脑"); + + public final int code; + public final String prompt; + + @Override + public int getCode() { + return this.code; + } + + ProductType3(int code, String prompt) { + this.code = code; + this.prompt = prompt; + } + + @Override + public String getPrompt() { + return this.prompt; + } + + public static ProductType3 get(int code) { + switch (code) { + case 1: + return Phone; + case 2: + return Computer; + default: + return null; + } + } + } + + public static class Model3 { + private ProductType3 type; + private ProductType3 type1; + + public Model3(ProductType3 type, ProductType3 type1) { + this.type = type; + this.type1 = type1; + } + + public ProductType3 getType() { + return type; + } + + public void setType(ProductType3 type) { + this.type = type; + } + + public ProductType3 getType1() { + return type1; + } + + public void setType1(ProductType3 type1) { + this.type1 = type1; + } + } + + public static class EnumAwareSerializer1 implements ObjectDeserializer { + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + String val = StringCodec.instance.deserialze(parser, type, fieldName); + System.out.println("-----------------EnumAwareSerializer1.deserialze-----------------------------"); + System.out.println(val); + return (T) ProductType1.get(JSON.parseObject(val).getInteger("code")); + } + + @Override + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + } + + public static class EnumAwareSerializer2 implements ObjectDeserializer { + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + String val = StringCodec.instance.deserialze(parser, type, fieldName); + System.out.println("-----------------EnumAwareSerializer2.deserialze-----------------------------"); + System.out.println(val); + return (T) ProductType2.get(JSON.parseObject(val).getInteger("code")); + } + + @Override + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + } + + public static class MyModuel implements Module { + + @SuppressWarnings("rawtypes") + @Override + public ObjectDeserializer createDeserializer(ParserConfig config, Class type) { + return new ObjectDeserializer() { + @SuppressWarnings("unchecked") + @Override + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + String val = StringCodec.instance.deserialze(parser, type, fieldName); + System.out.println("-----------MyModuel.deserialze------------------------"); + System.out.println(val); + try { + Constructor c = Class.forName(type.getTypeName()).getDeclaredConstructor(ProductType3.class, + ProductType3.class); + return (T) c.newInstance(ProductType3.Computer, ProductType3.Phone); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @Override + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + }; + } + + @SuppressWarnings("rawtypes") + @Override + public ObjectSerializer createSerializer(SerializeConfig config, Class type) { + return new ObjectSerializer() { + @Override + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, + int features) throws IOException { + SerializeWriter out = serializer.out; + if (object == null) { + out.writeNull(); + return; + } + System.err.println("--------------MyModuel.write-------------------------"); + + StringCodec.instance.write(serializer, ((ProductType3) object).name(), fieldName, fieldType, + features); + } + }; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2182.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2182.java new file mode 100644 index 0000000000..afcbac7eee --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2182.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSON; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import junit.framework.TestCase; + +public class Issue2182 extends TestCase { + public void test_for_issue() throws Exception { + Multimap multimap = ArrayListMultimap.create(); + multimap.put("admin", "admin.create"); + multimap.put("admin", "admin.update"); + multimap.put("admin", "admin.delete"); + multimap.put("user", "user.create"); + multimap.put("user", "user.delete"); + + String json = JSON.toJSONString(multimap); + assertEquals("{\"admin\":[\"admin.create\",\"admin.update\",\"admin.delete\"],\"user\":[\"user.create\",\"user.delete\"]}", json); + + ArrayListMultimap multimap1 = JSON.parseObject(json, ArrayListMultimap.class); + + assertEquals(multimap.size(), multimap1.size()); + assertEquals(json, JSON.toJSONString(multimap1)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2185.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2185.java new file mode 100644 index 0000000000..42bdd71253 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2185.java @@ -0,0 +1,91 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.Date; +import java.util.HashMap; + +public class Issue2185 extends TestCase { + + public void test_for_issue() throws Exception { + Exception error = null; + try { + JSONObject origin = new JSONObject(); + JSONArray jsonArray = new JSONArray().fluentAdd(origin.getInnerMap()); + jsonArray.getJSONObject(0).put("key", "value"); + // now we expect jsonArray is [{"key":"value"}] + assertEquals(1, jsonArray.getJSONObject(0).size()); + assertTrue(origin.getInnerMap() == jsonArray.getJSONObject(0).getInnerMap()); + } catch (JSONException ex) { + error = ex; + } + assertNull(error); + } + + /** + * To prove casting from Map<Object,Object> won't cause exception + * + * @throws Exception + */ + public void test_for_issue_1() throws Exception { + Exception error = null; + try { + HashMap origin = new HashMap(); + origin.put(new Object(), "value"); + JSONArray jsonArray = new JSONArray().fluentAdd(origin); + jsonArray.getJSONObject(0); + // now jsonArray is [{{}:"value"}] + assertEquals(1, jsonArray.getJSONObject(0).size()); + } catch (JSONException ex) { + error = ex; + } + assertNull(error); + } + + /** + * To prove casting from Map<primitive type, Object> won't cause exception + * + * @throws Exception + */ + public void test_for_issue_2() throws Exception { + Exception error = null; + try { + HashMap origin = new HashMap(); + origin.put(5.3f, "value"); + JSONArray jsonArray = new JSONArray().fluentAdd(origin); + jsonArray.getJSONObject(0); + // now jsonArray is [{5.3:"value"}] + assertEquals(1, jsonArray.getJSONObject(0).size()); + } catch (JSONException ex) { + error = ex; + } + assertNull(error); + } + + /** + * To prove casting from Map<Date, Object> won't cause exception + * + * @throws Exception + */ + public void test_for_issue_3() throws Exception { + Exception error = null; + try { + HashMap origin = new HashMap(); + origin.put(new Date(), "value"); + JSONArray jsonArray = new JSONArray().fluentAdd(origin); + jsonArray.getJSONObject(0); + // now jsonArray is [{154xxxxxxxxx:"value"}] + assertEquals(1, jsonArray.getJSONObject(0).size()); + } catch (JSONException ex) { + error = ex; + } + assertNull(error); + } + + public static class Model { + public int value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2189.java b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2189.java new file mode 100644 index 0000000000..6e7ae662ba --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2100/Issue2189.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.issue_2100; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue2189 extends TestCase { + public void test_for_issue() throws Exception { + String str = "[{\"id\":\"1\",\"name\":\"a\"},{\"id\":\"2\",\"name\":\"b\"}]"; + assertEquals("[\"1\",\"2\"]", + JSONPath.extract(str, "$.*.id") + .toString() + ); + } + + public void test_for_issue_1() throws Exception { + String str = "[{\"id\":\"1\",\"name\":\"a\"},{\"id\":\"2\",\"name\":\"b\"}]"; + assertEquals("[\"2\"]", + JSONPath.extract(str, "$.*[?(@.name=='b')].id") + .toString() + ); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2201.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2201.java new file mode 100644 index 0000000000..768609b837 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2201.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue2201 extends TestCase { + public void test_for_issue() throws Exception { + ParserConfig.getGlobalInstance().register("M2001", Model.class); + + String json = "{\"@type\":\"M2001\",\"id\":3}"; + Model m = (Model) JSON.parseObject(json, Object.class); + assertEquals(3, m.id); + } + + public static class Model { + public int id; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2206.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2206.java new file mode 100644 index 0000000000..b874aff994 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2206.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.time.LocalDateTime; + +public class Issue2206 extends TestCase { + public void test_for_issue() throws Exception { + JSON.parseObject("{\"date\":\"20181229162849\"}", Model.class); + } + + public static class Model { + public LocalDateTime date; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2214.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2214.java new file mode 100644 index 0000000000..6b83892ac1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2214.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +public class Issue2214 extends TestCase { + public void test_for_issue() throws Exception { + List list = new ArrayList(); + list.add("robin"); + Object[] args = new Object[]{new List[][]{new List[]{list}}}; + String text = JSON.toJSONString(args); + Class clazz = User.class; + Method method = clazz.getMethod("testGenericArrayArray2", List[][].class); + Type[] types = method.getGenericParameterTypes(); + List argList = JSON.parseArray(text, types); + Object res = new User().testGenericArrayArray2((List[][]) argList.get(0)); + System.out.println(res); + } + + public static class User { + public List[][] testGenericArrayArray2(List[][] res){ + return res; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2216.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2216.java new file mode 100644 index 0000000000..3af97c186d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2216.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.Date; + +public class Issue2216 extends TestCase { + public void test_for_issue() throws Exception { + Model model = JSON.parseObject("{\"value\":\"20181229162849000+0800\"}", Model.class); + assertNotNull(model); + assertNotNull(model.value); + assertEquals(1546072129000L, model.value.getTime()); + } + + public void test_for_issue_2() throws Exception { + Model model = JSON.parseObject("{\"value\":\"20181229162849000+0800\"}").toJavaObject(Model.class); + assertNotNull(model); + assertNotNull(model.value); + assertEquals(1546072129000L, model.value.getTime()); + } + + public static class Model { + @JSONField(format = "yyyyMMddHHmmssSSSZ") + public Date value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2224.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2224.java new file mode 100644 index 0000000000..cb8f6c0850 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2224.java @@ -0,0 +1,119 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvt.issue_2200.issue2224.PersonCollection; +import com.alibaba.json.bvt.issue_2200.issue2224_2.PersonGroupedCollection; +import com.alibaba.json.bvt.issue_2200.issue2224_3.ArrayPersonGroupedCollection; +import com.alibaba.json.bvt.issue_2200.issue2224_4.MAPersonGroupedCollection; +import com.alibaba.json.bvt.issue_2200.issue2224_5.MA2PersonGroupedCollection; +import junit.framework.TestCase; + +public class Issue2224 extends TestCase { + //support inherit with other parameterized type + public void test_for_issue() { + String json = "[{\"idNo\":\"123456\",\"name\":\"tom\"},{\"idNo\":\"123457\",\"name\":\"jack\"}]"; + PersonCollection personCollection = JSON.parseObject(json, PersonCollection.class); + assertNotNull(personCollection); + assertEquals(2, personCollection.size()); + assertEquals("tom", personCollection.get("123456").getName()); + assertEquals("jack", personCollection.get("123457").getName()); + String json2 = JSON.toJSONString(personCollection); + assertNotNull(json2); + } + + //support inherit with other parameterized type and item type is generic + public void test_for_issue_2() { + String json = "[[{\"idNo\":\"123\",\"name\":\"张三\"},{\"idNo\":\"124\",\"name\":\"张三\"}],[{\"idNo\":\"223\",\"name\":\"李四\"},{\"idNo\":\"224\",\"name\":\"李四\"}]]"; + PersonGroupedCollection personCollection = JSON.parseObject(json, PersonGroupedCollection.class); + assertNotNull(personCollection); + assertEquals(2, personCollection.size()); + assertEquals(2, personCollection.get("张三").size()); + assertEquals("123", personCollection.get("张三").get(0).getIdNo()); + assertEquals("张三", personCollection.get("张三").get(0).getName()); + assertEquals("124", personCollection.get("张三").get(1).getIdNo()); + assertEquals("张三", personCollection.get("张三").get(1).getName()); + assertEquals(2, personCollection.get("李四").size()); + assertEquals("223", personCollection.get("李四").get(0).getIdNo()); + assertEquals("李四", personCollection.get("李四").get(0).getName()); + assertEquals("224", personCollection.get("李四").get(1).getIdNo()); + assertEquals("李四", personCollection.get("李四").get(1).getName()); + String json2 = JSON.toJSONString(personCollection); + assertNotNull(json2); + } + + //support inherit with other parameterized type and item type is bean array + public void test_for_issue_3() { + String json = "[[{\"idNo\":\"123\",\"name\":\"张三\"},{\"idNo\":\"124\",\"name\":\"张三\"}],[{\"idNo\":\"223\",\"name\":\"李四\"},{\"idNo\":\"224\",\"name\":\"李四\"}]]"; + ArrayPersonGroupedCollection personCollection = JSON.parseObject(json, ArrayPersonGroupedCollection.class); + assertNotNull(personCollection); + assertEquals(2, personCollection.size()); + assertEquals(2, personCollection.get("张三").length); + assertEquals("123", personCollection.get("张三")[0].getIdNo()); + assertEquals("张三", personCollection.get("张三")[0].getName()); + assertEquals("124", personCollection.get("张三")[1].getIdNo()); + assertEquals("张三", personCollection.get("张三")[1].getName()); + assertEquals(2, personCollection.get("李四").length); + assertEquals("223", personCollection.get("李四")[0].getIdNo()); + assertEquals("李四", personCollection.get("李四")[0].getName()); + assertEquals("224", personCollection.get("李四")[1].getIdNo()); + assertEquals("李四", personCollection.get("李四")[1].getName()); + String json2 = JSON.toJSONString(personCollection); + assertNotNull(json2); + } + + //support inherit with other parameterized type and item type is generic array + public void test_for_issue_4() { + String json = "[[{\"idNo\":\"123\",\"name\":\"张三\"},{\"idNo\":\"124\",\"name\":\"张三\"}],[{\"idNo\":\"223\",\"name\":\"李四\"},{\"idNo\":\"224\",\"name\":\"李四\"}]]"; + MAPersonGroupedCollection personCollection = JSON.parseObject(json, MAPersonGroupedCollection.class); + assertNotNull(personCollection); + assertEquals(2, personCollection.size()); + assertEquals(2, personCollection.get("张三").length); + assertEquals("123", personCollection.get("张三")[0].get("idNo")); + assertEquals("张三", personCollection.get("张三")[0].get("name")); + assertEquals("124", personCollection.get("张三")[1].get("idNo")); + assertEquals("张三", personCollection.get("张三")[1].get("name")); + assertEquals(2, personCollection.get("李四").length); + assertEquals("223", personCollection.get("李四")[0].get("idNo")); + assertEquals("李四", personCollection.get("李四")[0].get("name")); + assertEquals("224", personCollection.get("李四")[1].get("idNo")); + assertEquals("李四", personCollection.get("李四")[1].get("name")); + String json2 = JSON.toJSONString(personCollection); + assertNotNull(json2); + } + + //support inherit with other parameterized type and item type is generic array contains array + public void test_for_issue_5() { + String json = "[[{\"idNo\":[\"123\",\"123x\"],\"name\":[\"张三\",\"张三一\"]},{\"idNo\":[\"124\",\"124x\"],\"name\":[\"张三\",\"张三一\"]}],[{\"idNo\":[\"223\",\"223y\"],\"name\":[\"李四\",\"李小四\"]},{\"idNo\":[\"224\",\"224y\"],\"name\":[\"李四\",\"李小四\"]}]]"; + MA2PersonGroupedCollection personCollection = JSON.parseObject(json, MA2PersonGroupedCollection.class); + assertNotNull(personCollection); + assertEquals(2, personCollection.size()); + assertEquals(2, personCollection.get("张三").length); + assertEquals(2, personCollection.get("张三")[0].get("idNo").length); + assertEquals("123", personCollection.get("张三")[0].get("idNo")[0]); + assertEquals("123x", personCollection.get("张三")[0].get("idNo")[1]); + assertEquals(2, personCollection.get("张三")[0].get("name").length); + assertEquals("张三", personCollection.get("张三")[0].get("name")[0]); + assertEquals("张三一", personCollection.get("张三")[0].get("name")[1]); + assertEquals(2, personCollection.get("张三")[1].get("idNo").length); + assertEquals("124", personCollection.get("张三")[1].get("idNo")[0]); + assertEquals("124x", personCollection.get("张三")[1].get("idNo")[1]); + assertEquals(2, personCollection.get("张三")[1].get("name").length); + assertEquals("张三", personCollection.get("张三")[1].get("name")[0]); + assertEquals("张三一", personCollection.get("张三")[1].get("name")[1]); + assertEquals(2, personCollection.get("李四").length); + assertEquals(2, personCollection.get("李四")[0].get("idNo").length); + assertEquals("223", personCollection.get("李四")[0].get("idNo")[0]); + assertEquals("223y", personCollection.get("李四")[0].get("idNo")[1]); + assertEquals(2, personCollection.get("李四")[0].get("name").length); + assertEquals("李四", personCollection.get("李四")[0].get("name")[0]); + assertEquals("李小四", personCollection.get("李四")[0].get("name")[1]); + assertEquals(2, personCollection.get("李四")[1].get("idNo").length); + assertEquals("224", personCollection.get("李四")[1].get("idNo")[0]); + assertEquals("224y", personCollection.get("李四")[1].get("idNo")[1]); + assertEquals(2, personCollection.get("李四")[1].get("name").length); + assertEquals("李四", personCollection.get("李四")[1].get("name")[0]); + assertEquals("李小四", personCollection.get("李四")[1].get("name")[1]); + String json2 = JSON.toJSONString(personCollection); + assertNotNull(json2); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2229.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2229.java new file mode 100644 index 0000000000..2872e31ba4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2229.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.Date; + +public class Issue2229 extends TestCase { + public void test_for_issue() throws Exception { + Jon jon = JSON.parseObject("{\"dStr\":\" hahahaha \",\"user\":{\"createtime\":null,\"id\":0,\"username\":\" asdfsadf asdf asdf \"}}", Jon.class); + assertEquals(" asdfsadf asdf asdf ", jon.user.username); + } + + public void test_for_issue1() throws Exception { + Jon jon1 = JSON.parseObject("{'dStr':' hahahaha ','user':{'createtime':null,'id':0,'username':' asdfsadf asdf asdf '}}", Jon.class); + assertEquals(" asdfsadf asdf asdf ", jon1.user.username); + } + + public static class Jon { + public String dStr; + public User user; + } + + public static class User { + public int id; + public Date createtime; + public String username; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2234.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2234.java new file mode 100644 index 0000000000..b1ace677be --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2234.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue2234 extends TestCase { + public void test_for_issue() throws Exception { + String userStr = "{\"name\":\"asdfad\",\"ss\":\"\"}"; + User user = JSON.parseObject(userStr, User.class); + } + + public static class User { + public String name; + public List ss; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2238.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2238.java new file mode 100644 index 0000000000..62bf5c63eb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2238.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.math.BigDecimal; + +public class Issue2238 extends TestCase { + public void test_for_issue() throws Exception { + CapitalLimitMonenyDTO capitalLimitMonenyDTO =new CapitalLimitMonenyDTO(); + capitalLimitMonenyDTO.setMaxChargeMoney(new BigDecimal("200000")); + capitalLimitMonenyDTO.setMinChargeMoney(new BigDecimal(0.01)); + capitalLimitMonenyDTO.setMaxWithdrawMoney(new BigDecimal(0.01)); + capitalLimitMonenyDTO.setMinWithdrawMoney(new BigDecimal("500000")); + System.out.println(JSON.toJSONString(capitalLimitMonenyDTO)); + } + + public static class CapitalLimitMonenyDTO { + private BigDecimal maxChargeMoney; + private BigDecimal minChargeMoney; + private BigDecimal maxWithdrawMoney; + private BigDecimal minWithdrawMoney; + + public BigDecimal getMaxChargeMoney() { + return maxChargeMoney; + } + + public void setMaxChargeMoney(BigDecimal maxChargeMoney) { + this.maxChargeMoney = maxChargeMoney; + } + + public BigDecimal getMinChargeMoney() { + return minChargeMoney; + } + + public void setMinChargeMoney(BigDecimal minChargeMoney) { + this.minChargeMoney = minChargeMoney; + } + + public BigDecimal getMaxWithdrawMoney() { + return maxWithdrawMoney; + } + + public void setMaxWithdrawMoney(BigDecimal maxWithdrawMoney) { + this.maxWithdrawMoney = maxWithdrawMoney; + } + + public BigDecimal getMinWithdrawMoney() { + return minWithdrawMoney; + } + + public void setMinWithdrawMoney(BigDecimal minWithdrawMoney) { + this.minWithdrawMoney = minWithdrawMoney; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2239.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2239.java new file mode 100644 index 0000000000..f8a53edab7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2239.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue2239 extends TestCase { + public void test_for_issue() throws Exception { + + String json = "{\"page\":{}}"; + + BaseResponse bean = JSON.parseObject(json, + new TypeReference>() { + }); +// bean.getPage().getList(); // 得到的是空 + } + + public static class Bean { + + } + + public static class BaseResponse { + + private PageBean page; + + + + public PageBean getPage() { + return page; + } + } + + public static class PageBean { + + private List list; + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2240.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2240.java new file mode 100644 index 0000000000..fa6cac6bfe --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2240.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.Collections; +import java.util.Map; + +public class Issue2240 extends TestCase { + public void test_for_issue() throws Exception { + ResultMap resultMap = new ResultMap(); + resultMap.setA(Collections.emptyMap()); + resultMap.setB(Collections.emptyMap()); + assertEquals("{\"a\":{},\"b\":{}}", JSON.toJSONString(resultMap)); + + } + + public static class ResultMap { + private Map a; + private Map b; + + public Map getA() { + return a; + } + + public void setA(Map a) { + this.a = a; + } + + public Map getB() { + return b; + } + + public void setB(Map b) { + this.b = b; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2241.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2241.java new file mode 100644 index 0000000000..fde4afc067 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2241.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.joda.time.LocalDateTime; + +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue2241 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + String text = "{\"createTime\":1548166745}"; + + Order o = JSON.parseObject(text, Order.class); + assertEquals(1548166745000L, o.createTime.getTime()); + + String json = JSON.toJSONString(o); + assertEquals("{\"createTime\":1548166745}", json); + } + + public void test_for_issue2() throws Exception { + String text = "{\"createTime\":1548166745}"; + + Order2 o = JSON.parseObject(text, Order2.class); + assertEquals(1548166745000L, o.createTime.getTimeInMillis()); + + String json = JSON.toJSONString(o); + assertEquals("{\"createTime\":1548166745}", json); + } + + public void test_for_issue3() throws Exception { + String text = "{\"createTime\":\"20180714224948\"}"; + + Order3 o = JSON.parseObject(text, Order3.class); + assertEquals(1531579788000L, o.createTime.getTimeInMillis()); + + String json = JSON.toJSONString(o); + assertEquals("{\"createTime\":\"20180714224948\"}", json); + } + + public void test_for_issue4() throws Exception { + String text = "{\"createTime\":1548166745}"; + + Order4 o = JSON.parseObject(text, Order4.class); + assertEquals(1548166745L, o.createTime.toEpochSecond()); + + String json = JSON.toJSONString(o); + assertEquals("{\"createTime\":1548166745}", json); + } + + public static class Order { + @JSONField(format = "unixtime") + public Date createTime; + } + + public static class Order2 { + @JSONField(format = "unixtime") + public Calendar createTime; + } + + public static class Order3 { + @JSONField(format = "yyyyMMddHHmmss") + public Calendar createTime; + } + + public static class Order4 { + @JSONField(format = "unixtime") + public ZonedDateTime createTime; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2244.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2244.java new file mode 100644 index 0000000000..fad0f4e41d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2244.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.Date; + +public class Issue2244 extends TestCase { + public void test_for_issue() throws Exception { + String str = "\"2019-01-14T06:32:09.029Z\""; + JSON.parseObject(str, Date.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2249.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2249.java new file mode 100644 index 0000000000..50416e9667 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2249.java @@ -0,0 +1,77 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue2249 extends TestCase { + public void test_for_issue() throws Exception { + assertSame(Type.Big, JSON.parseObject("\"big\"", Type.class)); + assertSame(Type.Big, JSON.parseObject("\"Big\"", Type.class)); + assertSame(Type.Big, JSON.parseObject("\"BIG\"", Type.class)); + assertSame(Type.Small, JSON.parseObject("\"Small\"", Type.class)); + assertSame(Type.Small, JSON.parseObject("\"small\"", Type.class)); + assertSame(Type.Small, JSON.parseObject("\"SMALL\"", Type.class)); + assertSame(Type.Medium, JSON.parseObject("\"medium\"", Type.class)); + assertSame(Type.Medium, JSON.parseObject("\"MEDIUM\"", Type.class)); + assertSame(Type.Medium, JSON.parseObject("\"Medium\"", Type.class)); + assertSame(Type.Medium, JSON.parseObject("\"MediuM\"", Type.class)); + assertNull(JSON.parseObject("\"\"", Type.class)); + } + + public void test_for_issue_1() throws Exception { + assertSame(Type.Big, JSON.parseObject("{\"type\":\"bIG\"}", Model.class).type); + assertSame(Type.Big, JSON.parseObject("{\"type\":\"big\"}", Model.class).type); + assertSame(Type.Big, JSON.parseObject("{\"type\":\"Big\"}", Model.class).type); + assertSame(Type.Big, JSON.parseObject("{\"type\":\"BIG\"}", Model.class).type); + + assertSame(Type.Small, JSON.parseObject("{\"type\":\"Small\"}", Model.class).type); + assertSame(Type.Small, JSON.parseObject("{\"type\":\"SmAll\"}", Model.class).type); + assertSame(Type.Small, JSON.parseObject("{\"type\":\"small\"}", Model.class).type); + assertSame(Type.Small, JSON.parseObject("{\"type\":\"SMALL\"}", Model.class).type); + + assertSame(Type.Medium, JSON.parseObject("{\"type\":\"Medium\"}", Model.class).type); + assertSame(Type.Medium, JSON.parseObject("{\"type\":\"MediuM\"}", Model.class).type); + assertSame(Type.Medium, JSON.parseObject("{\"type\":\"medium\"}", Model.class).type); + assertSame(Type.Medium, JSON.parseObject("{\"type\":\"MEDIUM\"}", Model.class).type); + + } + + public void test_for_issue_null() throws Exception { + assertNull(JSON.parseObject("{\"type\":\"\"}", Model.class).type); + } + + public void test_for_issue_null_2() throws Exception { + assertNull(JSON.parseObject("{\"type\":\"\"}", Model.class, Feature.ErrorOnEnumNotMatch).type); + } + + + public void test_for_issue_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("\"xxx\"", Type.class, Feature.ErrorOnEnumNotMatch); + } catch (JSONException e) { + error = e; + } + assertNotNull(error); + } + + public void test_for_issue_error_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"type\":\"xxx\"}", Model.class, Feature.ErrorOnEnumNotMatch); + } catch (JSONException e) { + error = e; + } + assertNotNull(error); + } + + public enum Type { + Big,Small,Medium + } + + public static class Model { + public Type type; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2251.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2251.java new file mode 100644 index 0000000000..60e24face3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2251.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.LinkedList; +import java.util.Queue; + +public class Issue2251 extends TestCase { + public void test_for_issue() throws Exception { + Model m = new Model(); + m.queue = new LinkedList(); + m.queue.add(1); + m.queue.add(2); + + String str = JSON.toJSONString(m); + Model m2 = JSON.parseObject(str, Model.class); + assertNotNull(m2.queue); + } + + public static class Model { + public Queue queue; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2253.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2253.java new file mode 100644 index 0000000000..c628b40abd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2253.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class Issue2253 extends TestCase { + public void test_for_issue() throws Exception { + List> result = new ArrayList(); + result.add(new LinkedHashMap()); + result.get(0).put("3", 3); + result.get(0).put("2", 2); + result.get(0).put("7", 7); + + assertEquals("[{\"3\":3,\"2\":2,\"7\":7}]", JSON.toJSONString(result, SerializerFeature.WriteMapNullValue)); + + result = JSON.parseObject(JSON.toJSONString(result, SerializerFeature.WriteMapNullValue), new TypeReference>>() {}, Feature.OrderedField); + + assertEquals("[{\"3\":3,\"2\":2,\"7\":7}]", JSON.toJSONString(result, SerializerFeature.WriteMapNullValue)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2254.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2254.java new file mode 100644 index 0000000000..aab73c145e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2254.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue2254 extends TestCase { + public void test_for_issue() throws Exception { + String jsonString = "{\"a\":[1.0,2.0]}"; //{"a":[1.0,2.0]} + Exception error = null; + try { + JSON.parseObject(jsonString, TestClass.class); + } catch (Exception ex) { + error = ex; + } + assertNotNull(error); + } + + public static class TestClass { + public float[][] a; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2260.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2260.java new file mode 100644 index 0000000000..8c542fbb5e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2260.java @@ -0,0 +1,65 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.util.Calendar; + +public class Issue2260 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\"date\":\"1950-07-14\"}"; + M1 m = JSON.parseObject(json, M1.class); + assertEquals(1950, m.date.get(Calendar.YEAR)); + } + + public void test_for_jdk8_zdt_1() throws Exception { + String json = "{\"date\":\"1950-07-14\"}"; + M2 m = JSON.parseObject(json, M2.class); + assertEquals(1950, m.date.getYear()); + } + + public void test_for_jdk8_zdt_2() throws Exception { + String json = "{\"date\":\"1950-07-14 12:23:34\"}"; + M2 m = JSON.parseObject(json, M2.class); + assertEquals(1950, m.date.getYear()); + } + + public void test_for_jdk8_zdt_3() throws Exception { + String json = "{\"date\":\"1950-07-14T12:23:34\"}"; + M2 m = JSON.parseObject(json, M2.class); + assertEquals(1950, m.date.getYear()); + } + + public void test_for_jdk8_ldt_1() throws Exception { + String json = "{\"date\":\"1950-07-14\"}"; + M3 m = JSON.parseObject(json, M3.class); + assertEquals(1950, m.date.getYear()); + } + + public void test_for_jdk8_ldt_2() throws Exception { + String json = "{\"date\":\"1950-07-14 12:23:34\"}"; + M3 m = JSON.parseObject(json, M3.class); + assertEquals(1950, m.date.getYear()); + } + + public void test_for_jdk8_ldt_3() throws Exception { + String json = "{\"date\":\"1950-07-14T12:23:34\"}"; + M3 m = JSON.parseObject(json, M3.class); + assertEquals(1950, m.date.getYear()); + } + + public static class M1 { + public Calendar date; + } + + public static class M2 { + public ZonedDateTime date; + } + + public static class M3 { + public LocalDateTime date; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2262.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2262.java new file mode 100644 index 0000000000..73db6e7a9e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2262.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue2262 extends TestCase { + public void test_for_issue() throws Exception { + Model m = new Model(); + m.javaVersion = "1.6"; + + String json = JSON.toJSONString(m); + assertEquals("{\"java.version\":\"1.6\"}", json); + + Model m2 = JSON.parseObject(json, Model.class); + assertNotNull(m2); + assertEquals(m.javaVersion, m2.javaVersion); + } + + public static class Model { + @JSONField(name = "java.version") + public String javaVersion; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2264.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2264.java new file mode 100644 index 0000000000..1606dc3604 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2264.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue2264 extends TestCase { + public void test_for_issue() throws Exception { + String oID="{\"sys\":\"ROC\",\"code\":0,\"messages\":\"分页获取信息成功!\",\"data\":{\"pageNum\":1,\"pageSize\":10,\"totalPages\":11,\"total\":110,\"records\":[{\"id\":\"64e72850-d149-46d6-8bd7-5f1d332d2a16\",\"tenantCode\":\"clouds_dianmo\",\"name\":\"asr_t1\",\"operatorId\":\"38ba5660-ef6e-4b66-9673-b0236832f179\",\"createTime\":\"2019-01-25 14:21:03\",\"updateTime\":\"2019-01-25 14:21:03\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"liyiwan\",\"insRcuCnt\":0,\"distRcuCnt\":0},{\"id\":\"4f6a0975-3980-4fd9-b27c-09aa258f4e36\",\"tenantCode\":\"cloudminds\",\"name\":\"xianglong\",\"operatorId\":\"b9bf937f-01c6-4fe8-86f8-43ce7a08167a\",\"createTime\":\"2019-01-25 11:48:03\",\"updateTime\":\"2019-01-25 13:03:00\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"zhangxianglong\",\"insRcuCnt\":0,\"distRcuCnt\":1},{\"id\":\"b209b3b8-7b41-49dd-a087-fb7f6b5bfa51\",\"tenantCode\":\"cloudminds\",\"name\":\"cloud_pu\",\"operatorId\":\"21d08412-9c19-49c0-9428-a6a5ad1bb548\",\"createTime\":\"2019-01-25 11:45:14\",\"updateTime\":\"2019-01-25 11:45:14\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"dian\",\"insRcuCnt\":0,\"distRcuCnt\":1},{\"id\":\"a35e468d-3ff5-48e4-a0e9-b86249167ee5\",\"tenantCode\":\"CloudPepper_Test\",\"name\":\"welcome\",\"operatorId\":\"ca69a720-8b8e-4ee5-8b12-63a20e897ef1\",\"createTime\":\"2019-01-25 11:05:42\",\"updateTime\":\"2019-01-25 14:07:05\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"duwei\",\"insRcuCnt\":0,\"distRcuCnt\":1},{\"id\":\"25243f56-b31d-4b58-bd96-c6920628b06c\",\"tenantCode\":\"roc\",\"name\":\"士大夫撒点\",\"operatorId\":\"06f82222-48a4-4a6a-b1cc-52148ed27651\",\"createTime\":\"2019-01-25 11:02:02\",\"updateTime\":\"2019-01-25 11:02:02\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"admin\",\"insRcuCnt\":0,\"distRcuCnt\":0},{\"id\":\"229d9c33-0606-4cda-a4d5-8c1feba2a5ed\",\"tenantCode\":\"cloudminds\",\"name\":\"LocalAsr\",\"operatorId\":\"38ba5660-ef6e-4b66-9673-b0236832f179\",\"createTime\":\"2019-01-25 10:51:43\",\"updateTime\":\"2019-01-25 10:51:43\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"liyiwan\",\"insRcuCnt\":0,\"distRcuCnt\":0},{\"id\":\"3aedd158-24b8-4021-a9a3-d6effc91a32a\",\"tenantCode\":\"cloudminds\",\"name\":\"cloudAsr\",\"operatorId\":\"38ba5660-ef6e-4b66-9673-b0236832f179\",\"createTime\":\"2019-01-25 10:27:59\",\"updateTime\":\"2019-01-25 10:27:59\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"liyiwan\",\"insRcuCnt\":0,\"distRcuCnt\":1},{\"id\":\"53065639-a467-4872-8333-73e085c99e43\",\"tenantCode\":\"CloudPepper_Test\",\"name\":\"asrtest\",\"operatorId\":\"394e0148-ba95-4c39-a9f9-973abb2c718a\",\"createTime\":\"2019-01-25 10:17:36\",\"updateTime\":\"2019-01-25 13:12:01\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"liuyanan\",\"insRcuCnt\":0,\"distRcuCnt\":1},{\"id\":\"da2db833-c065-49dd-bdb7-939c2026faa3\",\"tenantCode\":\"CloudPepper_Test\",\"name\":\"testwqeq\",\"operatorId\":\"bb5cd865-baea-42a0-a36d-b9e354b88f27\",\"createTime\":\"2019-01-24 19:20:04\",\"updateTime\":\"2019-01-24 19:20:27\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"cqtest01\",\"insRcuCnt\":0,\"distRcuCnt\":0},{\"id\":\"da672b14-d968-4776-97ba-b7c1addaa3b3\",\"tenantCode\":\"CloudPepper_Test\",\"name\":\"cqtestASR\",\"operatorId\":\"bb5cd865-baea-42a0-a36d-b9e354b88f27\",\"createTime\":\"2019-01-24 16:46:40\",\"updateTime\":\"2019-01-24 18:14:15\",\"status\":0,\"robotType\":1,\"policyType\":0,\"policyVersion\":null,\"description\":null,\"extensionJson\":null,\"operatorCode\":\"cqtest01\",\"insRcuCnt\":0,\"distRcuCnt\":2}]},\"errors\":null,\"action\":0,\"script\":\"\"}"; + + JSONObject json = JSONObject.parseObject(oID); + String par="$..records[?(@.name=='asr_t1')].operatorId"; + Object source = JSONPath.eval(json,par); + String device_udid=JSONObject.toJSONString(source); + assertEquals("[\"38ba5660-ef6e-4b66-9673-b0236832f179\"]", device_udid); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2289.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2289.java new file mode 100644 index 0000000000..5397528193 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue2289.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import junit.framework.TestCase; + +public class Issue2289 extends TestCase { + public void test_for_issue() throws Exception { + B b = new B(); + b.id = 123; + + JSONSerializer jsonSerializer = new JSONSerializer(); + + jsonSerializer.writeAs(b, A.class); + + String str = jsonSerializer.toString(); + assertEquals("{}", str); + } + + public static class A { + + } + + public static class B extends A { + public int id; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/Issue_for_luohaoyu.java b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue_for_luohaoyu.java new file mode 100644 index 0000000000..96556038a7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/Issue_for_luohaoyu.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.issue_2200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; + +public class Issue_for_luohaoyu extends TestCase { + public void test_for_issue() throws Exception { + Map map = new HashMap(); + map.put(null, 123); + + String str = JSON.toJSONString(map); + assertEquals("{null:123}", str); + + JSONObject object = JSON.parseObject(str); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/CollectionEx.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/CollectionEx.java new file mode 100644 index 0000000000..e0e7bd1005 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/CollectionEx.java @@ -0,0 +1,6 @@ +package com.alibaba.json.bvt.issue_2200.issue2224; + +import java.util.Collection; + +interface CollectionEx extends Collection { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/KeyedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/KeyedCollection.java new file mode 100644 index 0000000000..f5e82dbee9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/KeyedCollection.java @@ -0,0 +1,105 @@ +package com.alibaba.json.bvt.issue_2200.issue2224; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class KeyedCollection implements CollectionEx, Cloneable { + private transient Map items = new LinkedHashMap(); + + protected abstract TKey getKeyForItem(TItem item); + + public TItem get(TKey key) { + return this.items.get(key); + } + + //region override + + public int size() { + return this.items.size(); + } + + public boolean isEmpty() { + return this.items.isEmpty(); + } + + public boolean contains(Object key) { + return this.items.containsKey(key); + } + + public Iterator iterator() { + return this.items.values().iterator(); + } + + public Object[] toArray() { + return this.items.values().toArray(); + } + + public T[] toArray(T[] a) { + return this.items.values().toArray(a); + } + + public boolean add(TItem item) { + if (item == null) + throw new IllegalArgumentException("item can not be null."); + TKey key = this.getKeyForItem(item); + this.items.put(key, item); + return true; + } + + public boolean remove(Object key) { + return this.items.remove(key) != null; + } + + public boolean containsAll(Collection keys) { + return this.items.keySet().containsAll(keys); + } + + public boolean addAll(Collection items) { + boolean modified = false; + for (TItem item : items) + modified |= this.add(item); + return modified; + } + + public boolean removeAll(Collection keys) { + boolean modified = false; + for (Object key : keys) + modified |= this.remove(key); + return modified; + } + + public boolean retainAll(Collection keys) { + boolean modified = false; + for (TKey key : this.items.keySet()) { + if (!keys.contains(key)) + modified |= this.remove(key); + } + return modified; + } + + public void clear() { + this.items.clear(); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append('['); + TItem item; + Iterator iterator = this.iterator(); + if (iterator.hasNext()) { + item = iterator.next(); + builder.append(item == this ? "(this Collection)" : item); + } + while (iterator.hasNext()) { + item = iterator.next(); + builder.append(", ").append(item == this ? "(this Collection)" : item); + } + builder.append(']'); + return builder.toString(); + } + + //endregion +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/Person.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/Person.java new file mode 100644 index 0000000000..a1bf6d6f0e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/Person.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.issue_2200.issue2224; + +public class Person { + private String idNo; + private String name; + + public String getIdNo() { + return this.idNo; + } + + public void setIdNo(String idNo) { + this.idNo = idNo; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/PersonCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/PersonCollection.java new file mode 100644 index 0000000000..f73622367a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224/PersonCollection.java @@ -0,0 +1,7 @@ +package com.alibaba.json.bvt.issue_2200.issue2224; + +public class PersonCollection extends KeyedCollection { + protected String getKeyForItem(Person person) { + return person.getIdNo(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/GroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/GroupedCollection.java new file mode 100644 index 0000000000..7fa586e9ec --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/GroupedCollection.java @@ -0,0 +1,8 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_2; + +import com.alibaba.json.bvt.issue_2200.issue2224.KeyedCollection; + +import java.util.List; + +abstract class GroupedCollection extends KeyedCollection> { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/PersonGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/PersonGroupedCollection.java new file mode 100644 index 0000000000..2cb2e4178c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/PersonGroupedCollection.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_2; + +import com.alibaba.json.bvt.issue_2200.issue2224.Person; + +import java.util.List; + +public class PersonGroupedCollection extends StringGroupedCollection { + @Override + protected String getKeyForItem(List list) { + if (list == null || list.isEmpty()) + return null; + return list.get(0).getName(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/StringGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/StringGroupedCollection.java new file mode 100644 index 0000000000..9c97b16892 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_2/StringGroupedCollection.java @@ -0,0 +1,4 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_2; + +abstract class StringGroupedCollection extends GroupedCollection { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayGroupedCollection.java new file mode 100644 index 0000000000..f8c7fedf40 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayGroupedCollection.java @@ -0,0 +1,6 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_3; + +import com.alibaba.json.bvt.issue_2200.issue2224.KeyedCollection; + +abstract class ArrayGroupedCollection extends KeyedCollection { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayPersonGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayPersonGroupedCollection.java new file mode 100644 index 0000000000..cbeba3fe20 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayPersonGroupedCollection.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_3; + +import com.alibaba.json.bvt.issue_2200.issue2224.Person; + +public class ArrayPersonGroupedCollection extends ArrayStringGroupedCollection { + @Override + protected String getKeyForItem(Person[] array) { + if (array == null || array.length == 0) + return null; + return array[0].getName(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayStringGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayStringGroupedCollection.java new file mode 100644 index 0000000000..9c089bd0f9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_3/ArrayStringGroupedCollection.java @@ -0,0 +1,4 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_3; + +abstract class ArrayStringGroupedCollection extends ArrayGroupedCollection { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAGroupedCollection.java new file mode 100644 index 0000000000..cd8f6ae03a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAGroupedCollection.java @@ -0,0 +1,6 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_4; + +import com.alibaba.json.bvt.issue_2200.issue2224.KeyedCollection; + +abstract class MAGroupedCollection extends KeyedCollection { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAPersonGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAPersonGroupedCollection.java new file mode 100644 index 0000000000..cd26397048 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAPersonGroupedCollection.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_4; + +import java.util.Map; + +public class MAPersonGroupedCollection extends MAStringGroupedCollection> { + @Override + protected String getKeyForItem(Map[] array) { + if (array == null || array.length == 0) + return null; + Object name = array[0].get("name"); + return name == null ? null : name.toString(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAStringGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAStringGroupedCollection.java new file mode 100644 index 0000000000..9c5e9c6fa9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_4/MAStringGroupedCollection.java @@ -0,0 +1,4 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_4; + +abstract class MAStringGroupedCollection extends MAGroupedCollection { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2GroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2GroupedCollection.java new file mode 100644 index 0000000000..bbf949b226 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2GroupedCollection.java @@ -0,0 +1,6 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_5; + +import com.alibaba.json.bvt.issue_2200.issue2224.KeyedCollection; + +abstract class MA2GroupedCollection extends KeyedCollection { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2PersonGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2PersonGroupedCollection.java new file mode 100644 index 0000000000..88c2461052 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2PersonGroupedCollection.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_5; + +import java.util.Map; + +public class MA2PersonGroupedCollection extends MA2StringGroupedCollection { + @Override + protected String getKeyForItem(Map[] array) { + if (array == null || array.length == 0) + return null; + final String[] names = array[0].get("name"); + return names == null || names.length == 0 ? null : names[0]; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2StringGroupedCollection.java b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2StringGroupedCollection.java new file mode 100644 index 0000000000..3dc5f31051 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2200/issue2224_5/MA2StringGroupedCollection.java @@ -0,0 +1,6 @@ +package com.alibaba.json.bvt.issue_2200.issue2224_5; + +import java.util.Map; + +abstract class MA2StringGroupedCollection extends MA2GroupedCollection> { +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2300.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2300.java new file mode 100644 index 0000000000..b09fdaa5a3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2300.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.Date; + +public class Issue2300 extends TestCase { + public void test_for_issue() throws Exception { + String text = "{\"createTime\":1548166745}"; + + Order o = JSON.parseObject(text, Order.class); + assertEquals(1548166745000L, o.createTime.getTime()); + + String json = JSON.toJSONString(o); + assertEquals("{\"createTime\":1548166745}", json); + + //新增校验1 + JSONObject jsonObject = JSONObject.parseObject(text); + Order order1 = JSONObject.toJavaObject(jsonObject, Order.class); + //校验不通过 + assertEquals(1548166745000L, order1.createTime.getTime()); + + //新增校验2 + Order order2 = jsonObject.toJavaObject(Order.class); + //校验不通过 + assertEquals(1548166745000L, order2.createTime.getTime()); + } + + public static class Order { + @JSONField(format = "unixtime") + public Date createTime; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2306.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2306.java new file mode 100644 index 0000000000..217670cc01 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2306.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue2306 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject object = new JSONObject(); + object.put("help_score_avg.cbm", 123); + + assertEquals(123 + , JSONPath.extract( + object.toJSONString(), "['help_score_avg.cbm']")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2311.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2311.java new file mode 100644 index 0000000000..563f7c6baa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2311.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSONPath; +import com.jayway.jsonpath.JsonPath; +import junit.framework.TestCase; + +public class Issue2311 extends TestCase { + public void test_for_issue() throws Exception { + String t = "{\"groups\":[{\"timers\":[{\"date\":\"00000001\",\"dps\":{\"1\":true},\"loops\":\"1111111\",\"timezoneId\":\"Asia/Shanghai\",\"time\":\"13:06\",\"status\":1},{\"date\":\"00000010\",\"dps\":{\"1\":true},\"loops\":\"1111111\",\"timezoneId\":\"Asia/Shanghai\",\"time\":\"13:07\",\"status\":1}],\"id\":\"1:\"},{\"timers\":[{\"date\":\"00000100\",\"dps\":{\"1\":true},\"loops\":\"1111111\",\"timezoneId\":\"Asia/Shanghai\",\"time\":\"13:06\",\"status\":1},{\"date\":\"00001000\",\"dps\":{\"1\":true},\"loops\":\"1111111\",\"timezoneId\":\"Asia/Shanghai\",\"time\":\"13:07\",\"status\":1}],\"id\":\"2:\"}],\"category\":{\"category\":\"xxxxxx\",\"status\":1}}"; + System.out.println((Object) JsonPath.read(t, "$.groups[*].timers[*].dps.1")); + System.out.println(JSONPath.extract(t, "$.groups[*].timers[*].dps['1']")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2334.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2334.java new file mode 100644 index 0000000000..53a066794d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2334.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue2334 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\n" + + "\"EXTINFO\":{\n" + + "\"bct_loan_account_status[15]\":\"aaa\",\n" + + "\"wc_bank_num_of_trans_last_3_mon[6]\":-9999,\n" + + "\"fahai_shixin_post_time[46]\":\"bbb\",\n" + + "\"zs_punishbreak_regdateclean[22]\":\"ccc\"\n" + + "}\n" + + "}"; + + JSONObject object = JSON.parseObject(json); + + assertEquals("aaa" + , JSONPath.eval(object, "$.EXTINFO.bct_loan_account_status\\[15\\]")); + + Object result = JSONPath.extract(json, "$.EXTINFO.bct_loan_account_status\\[15\\]"); + assertEquals("aaa", result.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2341.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2341.java new file mode 100644 index 0000000000..01bc58ac7b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2341.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Issue2341 extends TestCase { + public void test_for_issue() throws Exception { + String ss = "{\"@type\":\"1234\"}"; + JSONObject object = JSON.parseObject(ss); + assertEquals("1234", object.get("@type")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2343.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2343.java new file mode 100644 index 0000000000..4fb060b3a0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2343.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue2343 extends TestCase { + public void test_for_issue() throws Exception { + A a = new A(); + a.f1 = 101; + a.f2 = 102; + a.f3 = 103; + + String str = JSON.toJSONString(a); + assertEquals("{\"f2\":102,\"f1\":101,\"f3\":103}", str); + + JSONObject object = JSON.parseObject(str); + A a1 = object.toJavaObject(A.class); + assertEquals(a.f1, a1.f1); + assertEquals(a.f2, a1.f2); + assertEquals(a.f3, a1.f3); + } + + public static class A { + @JSONField(ordinal = 1) + public int f1; + + @JSONField(ordinal = 0) + public int f2; + + @JSONField(ordinal = 2) + public int f3; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2344.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2344.java new file mode 100644 index 0000000000..d0a6069ad9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2344.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvtVO.basic.LongPrimitiveEntity; +import junit.framework.TestCase; + +public class Issue2344 extends TestCase { + public void test_for_issue() throws Exception { + LongPrimitiveEntity vo = new LongPrimitiveEntity(9007199254741992L); + + assertEquals("{\"value\":\"9007199254741992\"}" + , JSON.toJSONString(vo, SerializerFeature.BrowserCompatible)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2346.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2346.java new file mode 100644 index 0000000000..a2c0f60085 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2346.java @@ -0,0 +1,83 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONPOJOBuilder; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; +import lombok.Builder; +import lombok.Getter; + +public class Issue2346 extends TestCase { + public void test_for_issue() throws Exception { + String jsonStr = "{\"age\":1,\"name\":\"aa\"}"; + TestEntity testEntity = JSON.parseObject(jsonStr, TestEntity.class); + assertEquals(jsonStr, JSON.toJSONString(testEntity)); + } + + @Builder(builderClassName = "TestEntityBuilder") + @Getter + @JSONType(builder = TestEntity.TestEntityBuilder.class) + public static class TestEntity { + private String name; + + private int age; + + @JSONPOJOBuilder(withPrefix = "") + public static class TestEntityBuilder{ + + } + } + + @JSONType(builder = TestEntity2.TestEntity2Builder.class) + @Getter + public static class TestEntity2 { + private String name; + + private int age; + + @JSONPOJOBuilder(withPrefix = "www") + public static class TestEntity2Builder{ + private TestEntity2 testEntity2 = new TestEntity2(); + + public TestEntity2 build(){ + return testEntity2; + } + + public TestEntity2Builder wwwAge(int age) { + testEntity2.age = age; + return this; + } + + public TestEntity2Builder wwwName(String name) { + testEntity2.name = name; + return this; + } + } + } + + @JSONType(builder = TestEntity3.TestEntity3Builder.class) + @Getter + public static class TestEntity3 { + private String name; + + private int age; + + public static class TestEntity3Builder{ + private TestEntity3 testEntity3 = new TestEntity3(); + + public TestEntity3 build(){ + return testEntity3; + } + + public TestEntity3Builder withAge(int age) { + testEntity3.age = age; + return this; + } + + public TestEntity3Builder withName(String name) { + testEntity3.name = name; + return this; + } + } + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2348.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2348.java new file mode 100644 index 0000000000..72fa84f1ab --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2348.java @@ -0,0 +1,635 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.io.Serializable; +import java.util.List; + +public class Issue2348 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\n" + + "\"ID\": null,\n" + + "\"XM\": \"陈XX\",\n" + + "\"XB\": \"1\",\n" + + "\"XB_\": \"男\",\n" + + "\"ZJH\": \"522401198310176625\",\n" + + "\"JSH\": \"0101\",\n" + + "\"GJ\": \"156\",\n" + + "\"GJ_\": \"中国\",\n" + + "\"MZ\": \"01\",\n" + + "\"MZ_\": \"汉族\",\n" + + "\"WHCD\": \"48\",\n" + + "\"WHCD_\": \"相当中专或中技毕业\",\n" + + "\"ZY\": null,\n" + + "\"ZY_\": null,\n" + + "\"CSRQ\": \"1532448000000\",\n" + + "\"CBZ\": null,\n" + + "\"LFFH\": \"370100111201807250001\",\n" + + "\"NL\": \"0\",\n" + + "\"RSRQ\": \"1537167900000\",\n" + + "\"AY\": \"010180\",\n" + + "\"AY_\": \"资助活动案\",\n" + + "\"ZZ\": \"AAAA\",\n" + + "\"BAHJ\": \"11\",\n" + + "\"BAHJ_\": \"事留\",\n" + + "\"JYQX\": null,\n" + + "\"ZSZT\": \"11\",\n" + + "\"ZSZT_\": null,\n" + + "\"PWH\": \"16\",\n" + + "\"WXDJ\": \"3\",\n" + + "\"WXDJ_\": \"二级\",\n" + + "\"JKZK\": null,\n" + + "\"JKZK_\": null,\n" + + "\"FZJJ\": \"阿德\",\n" + + "\"ZDRY\": \"0\",\n" + + "\"ZDRY_\": \"非重点\",\n" + + "\"Photo\": \"\",\n" + + "\"TZZ\": \"\",\n" + + "\"TZZ2\": \"\",\n" + + "\"GYQX\": \"2018/8/30 0:00:00\",\n" + + "\"ZZD\": \"QQQQ\",\n" + + "\"RSAQ\": \"阿德\",\n" + + "\"SG\": 22,\n" + + "\"TZ\": 22,\n" + + "\"HYZK\": null,\n" + + "\"HYZK_\": null,\n" + + "\"BHLX\": \"1\",\n" + + "\"BHLX_\": null,\n" + + "\"RFID\": \"23\",\n" + + "\"RFID_\": \"理发\",\n" + + "\"ZBZT\": null,\n" + + "\"JDXJ\": null,\n" + + "\"WCNR\": null,\n" + + "\"BYZDE\": \"3\",\n" + + "\"BYZDE_\": null,\n" + + "\"GL\": null,\n" + + "\"GZDW\": \"无单位\",\n" + + "\"ZJLX\": \"居民身份证\",\n" + + "\"CARDID\": \"D0CB8F1B\",\n" + + "\"JBR\": null,\n" + + "\"SKSJ\": null,\n" + + "\"SKYY\": null,\n" + + "\"YE\": 7427.87,\n" + + "\"BADW\": \"市看\",\n" + + "\"RSXZ\": \"事留\",\n" + + "\"ZB\": null,\n" + + "\"TYPE\": \"1\",\n" + + "\"CSSJ\": null,\n" + + "\"CSYY\": null,\n" + + "\"YXGW\": \"1\"\n" + + "}"; + + PersonnelModel p = JSON.parseObject(json, PersonnelModel.class); + assertEquals("23", p.getRfid()); + assertEquals("1", p.getBhlx()); + assertEquals(null, p.getJdxj()); + } + + public static class RoomPersonnel { + private String code; + private List data; + private int count; + static RoomPersonnel roompersonnel; + + public static RoomPersonnel getRoomPersonnel(){ + if(roompersonnel==null){ + roompersonnel=new RoomPersonnel(); + } + return roompersonnel; + } + + public void setCode(String code) { + this.code = code; + } + public String getCode() { + return code; + } + + + public void setData(List data) { + this.data = data; + } + public List getData() { + return data; + } + + + public void setCount(int count) { + this.count = count; + } + public int getCount() { + return count; + } + } + + public static class PersonnelModel implements Serializable { + + private String xm; + private String xb; + private String xb_; + private String zjh; + private String jsh; + private String gj; + private String gj_; + private String mz; + private String mz_; + private String whcd; + private String whcd_; + private String zy; + private String zy_; + private String csrq; + private String cbz; + private String lffh; + private String nl; + private String rsrq; + private String ay; + private String ay_; + private String zz; + private String bahj; + private String bahj_; + private String jyqx; + private String zszt; + private String zszt_; + private String pwh; + private String wxdj; + private String wxdj_; + private String jkzk; + private String fzjj; + private String zdry; + private String zdry_; + private String photo; + private String tzz; + private String tzz2; + private String gyqx; + private String zzd; + private String rsaq; + private String sg; + private String tz; + private String hyzk; + private String hyzk_; + private String bhlx; + private String rfid; + private String jkzk_; + private String gzdw; + private String zjlx; + private String zbzt; + private String jdxj; + private String wcnr; + private String byzde; + private String byzde_; + private String badw; + private String type; + private String rsxz; + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getBadw() { + return badw; + } + + public void setBadw(String badw) { + this.badw = badw; + } + + public String getByzde() { + return byzde; + } + + public void setByzde(String byzde) { + this.byzde = byzde; + } + + public String getByzde_() { + return byzde_; + } + + public void setByzde_(String byzde_) { + this.byzde_ = byzde_; + } + + public String getJdxj() { + return jdxj; + } + + public void setJdxj(String jdxj) { + this.jdxj = jdxj; + } + + public String getWcnr() { + return wcnr; + } + + public void setWcnr(String wcnr) { + this.wcnr = wcnr; + } + + public String getGzdw() { + return gzdw; + } + + public String getZbzt() { + return zbzt; + } + + public void setZbzt(String zbzt) { + this.zbzt = zbzt; + } + + public void setGzdw(String gzdw) { + this.gzdw = gzdw; + } + + public String getZjlx() { + return zjlx; + } + + public void setZjlx(String zjlx) { + this.zjlx = zjlx; + } + + public String getJkzk_() { + return jkzk_; + } + + public void setJkzk_(String jkzk_) { + this.jkzk_ = jkzk_; + } + + public String getHyzk() { + return hyzk; + } + + public void setHyzk(String hyzk) { + this.hyzk = hyzk; + } + + public String getHyzk_() { + return hyzk_; + } + + public void setHyzk_(String hyzk_) { + this.hyzk_ = hyzk_; + } + + public String getBhlx() { + return bhlx; + } + + public void setBhlx(String bhlx) { + this.bhlx = bhlx; + } + + public String getRfid() { + return rfid; + } + + public void setRfid(String rfid) { + this.rfid = rfid; + } + + public void setXm(String xm) { + this.xm = xm; + } + + public String getGyqx() { + return gyqx; + } + + public void setGyqx(String gyqx) { + this.gyqx = gyqx; + } + + public String getZzd() { + return zzd; + } + + public void setZzd(String zzd) { + this.zzd = zzd; + } + + public String getRsaq() { + return rsaq; + } + + public void setRsaq(String rsaq) { + this.rsaq = rsaq; + } + + public String getSg() { + return sg; + } + + public void setSg(String sg) { + this.sg = sg; + } + + public String getTz() { + return tz; + } + + public void setTz(String tz) { + this.tz = tz; + } + + public String getXm() { + return xm; + } + + public void setXb(String xb) { + this.xb = xb; + } + + public String getXb() { + return xb; + } + + public void setXb_(String xb_) { + this.xb_ = xb_; + } + + public String getXb_() { + return xb_; + } + + public void setZjh(String zjh) { + this.zjh = zjh; + } + + public String getZjh() { + return zjh; + } + + public void setJsh(String jsh) { + this.jsh = jsh; + } + + public String getJsh() { + return jsh; + } + + public void setGj(String gj) { + this.gj = gj; + } + + public String getGj() { + return gj; + } + + public void setGj_(String gj_) { + this.gj_ = gj_; + } + + public String getGj_() { + return gj_; + } + + public void setMz(String mz) { + this.mz = mz; + } + + public String getMz() { + return mz; + } + + public void setMz_(String mz_) { + this.mz_ = mz_; + } + + public String getMz_() { + return mz_; + } + + public void setWhcd(String whcd) { + this.whcd = whcd; + } + + public String getWhcd() { + return whcd; + } + + public void setWhcd_(String whcd_) { + this.whcd_ = whcd_; + } + + public String getWhcd_() { + return whcd_; + } + + public void setZy(String zy) { + this.zy = zy; + } + + public String getZy() { + return zy; + } + + public void setZy_(String zy_) { + this.zy_ = zy_; + } + + public String getZy_() { + return zy_; + } + + public void setCsrq(String csrq) { + this.csrq = csrq; + } + + public String getCsrq() { + return csrq; + } + + public void setCbz(String cbz) { + this.cbz = cbz; + } + + public String getCbz() { + return cbz; + } + + public void setLffh(String lffh) { + this.lffh = lffh; + } + + public String getLffh() { + return lffh; + } + + public void setNl(String nl) { + this.nl = nl; + } + + public String getNl() { + return nl; + } + + public void setRsrq(String rsrq) { + this.rsrq = rsrq; + } + + public String getRsrq() { + return rsrq; + } + + public void setAy(String ay) { + this.ay = ay; + } + + public String getAy() { + return ay; + } + + public void setAy_(String ay_) { + this.ay_ = ay_; + } + + public String getAy_() { + return ay_; + } + + public void setZz(String zz) { + this.zz = zz; + } + + public String getZz() { + return zz; + } + + public void setBahj(String bahj) { + this.bahj = bahj; + } + + public String getBahj() { + return bahj; + } + + public void setBahj_(String bahj_) { + this.bahj_ = bahj_; + } + + public String getBahj_() { + return bahj_; + } + + public void setJyqx(String jyqx) { + this.jyqx = jyqx; + } + + public String getJyqx() { + return jyqx; + } + + public void setZszt(String zszt) { + this.zszt = zszt; + } + + public String getZszt() { + return zszt; + } + + public void setZszt_(String zszt_) { + this.zszt_ = zszt_; + } + + public String getZszt_() { + return zszt_; + } + + public void setPwh(String pwh) { + this.pwh = pwh; + } + + public String getPwh() { + return pwh; + } + + public void setWxdj(String wxdj) { + this.wxdj = wxdj; + } + + public String getWxdj() { + return wxdj; + } + + public void setWxdj_(String wxdj_) { + this.wxdj_ = wxdj_; + } + + public String getWxdj_() { + return wxdj_; + } + + public void setJkzk(String jkzk) { + this.jkzk = jkzk; + } + + public String getJkzk() { + return jkzk; + } + + public void setFzjj(String fzjj) { + this.fzjj = fzjj; + } + + public String getFzjj() { + return fzjj; + } + + public void setZdry(String zdry) { + this.zdry = zdry; + } + + public String getZdry() { + return zdry; + } + + public void setZdry_(String zdry_) { + this.zdry_ = zdry_; + } + + public String getZdry_() { + return zdry_; + } + + public void setPhoto(String photo) { + this.photo = photo; + } + + public String getPhoto() { + return photo; + } + + public void setTzz(String tzz) { + this.tzz = tzz; + } + + public String getTzz() { + return tzz; + } + + public void setTzz2(String tzz2) { + this.tzz2 = tzz2; + } + + public String getTzz2() { + return tzz2; + } + + + public void setRsxz(String rsxz) { + this.rsxz = rsxz; + } + + public String getRsxz() { + return rsxz; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2351.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2351.java new file mode 100644 index 0000000000..6343252a84 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2351.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +public class Issue2351 extends TestCase { + public void test_for_issue() throws Exception { +// ParserConfig.getGlobalInstance().setAsmEnable(false); + // 创建空白对象 + Bean1 c = new Bean1(); + c.a = ""; + + // 序列化 + // 输出[null,null] + String s = JSON.toJSONString(c, SerializerFeature.BeanToArray); + assertEquals("[\"\",null]", s); + + // 反序列化报错 + // Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error, expect [, actual [ + JSON.parseObject(s, Bean1.class, Feature.SupportArrayToBean); + } + + public static class Bean1 { + + public String a; + + public List b; + } + + public static class Bean2 { + private String c; + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2355.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2355.java new file mode 100644 index 0000000000..4c33e4c73c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2355.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.math.BigDecimal; + +public class Issue2355 extends TestCase { + public void test_for_issue() throws Exception { + VO vo = new VO(); + BigDecimal num = new BigDecimal("0.00000001"); + vo.setNum(num); + String json = JSON.toJSONString(vo); + + assertEquals("{\"num\":0.00000001}", json); + } + + static class VO { + + @JSONField(serialzeFeatures = {SerializerFeature.WriteBigDecimalAsPlain}) + private BigDecimal num; + + public BigDecimal getNum() { + return num; + } + + public void setNum(BigDecimal num) { + this.num = num; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2357.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2357.java new file mode 100644 index 0000000000..f0ea91ca3c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2357.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.nio.ByteBuffer; + +public class Issue2357 extends TestCase { + public void test_for_issue() throws Exception { + ByteBuffer buff = ByteBuffer.allocate(32); + buff.putInt(100); + buff.flip(); + + String result = JSON.toJSONString(buff); + System.out.println(result); + + assertEquals("{\"array\":\"AAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\"limit\":4,\"position\":0}", result); + + ByteBuffer buf1 = JSON.parseObject(result, ByteBuffer.class); + + assertEquals(buff.capacity(), buf1.capacity()); + assertEquals(buff.limit(), buf1.limit()); + assertEquals(buff.position(), buf1.position()); + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2358.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2358.java new file mode 100644 index 0000000000..d864dc6c9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2358.java @@ -0,0 +1,75 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue2358 extends TestCase { + + public void test_for_issue() throws Exception { + String str = "[{\n" + + " \"test1\":\"1\",\n" + + " \"test2\":\"2\"\n" + + "},\n" + + " {\n" + + " \"test1\":\"1\",\n" + + " \"test2\":\"2\"\n" + + " }]"; + + Exception error = null; + try { + List testJsons = JSONObject.parseArray(str, TestJson2.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals("can't create non-static inner class instance.", error.getMessage()); + } + + class TestJson { + + private String test1; + private String test2; + + public String getTest1() { + return test1; + } + + public void setTest1(String test1) { + this.test1 = test1; + } + + public String getTest2() { + return test2; + } + + public void setTest2(String test2) { + this.test2 = test2; + } + + + } + + class TestJson2 { + private String test1; + private String test2; + + public String getTest1() { + return test1; + } + + public void setTest1(String test1) { + this.test1 = test1; + } + + public String getTest2() { + return test2; + } + + public void setTest2(String test2) { + this.test2 = test2; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2371.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2371.java new file mode 100644 index 0000000000..38192a52f8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2371.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue2371 extends TestCase { + public void test_for_issue() throws Exception { + RpcRespObj> resources = convertResult(Resource.class); + assertEquals(2, resources.data.get(0).resourceId.intValue()); + assertEquals("own佛恩", resources.data.get(0).resourceName); + } + + public static RpcRespObj> convertResult(Class type) { + String str = "{\"status\":0,\"data\":[{\"resourceId\":2,\"resourceName\":\"own佛恩\",\"systemCode\":\"ad\"}]}"; + RpcRespObj> result = JSON.parseObject(str, new TypeReference>>(type) {}); + return result; + } + + + public static class RpcRespObj { + public Integer status; + public Integer errcode; + public Integer errno; + public T data; + } + + + public static class Resource { + public Integer resourceId; + public String resourceName; + public String systemCode; + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2387.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2387.java new file mode 100644 index 0000000000..9c98c6dbf3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2387.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue2387 extends TestCase +{ + public void test_for_issue() throws Exception { + String jsonStr = "{id:\"ss\",ddd:\"sdfsd\",name:\"hh\"}"; + TestEntity news = JSON.parseObject(jsonStr, TestEntity.class, Feature.InitStringFieldAsEmpty); + assertEquals("{\"ddd\":\"sdfsd\",\"id\":\"ss\",\"name\":\"hh\"}", JSON.toJSONString(news)); + } + + public static class TestEntity { + private String id; + private String ddd; + private String name; + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public String getDdd() + { + return ddd; + } + + public void setDdd(String ddd) + { + this.ddd = ddd; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2397.java b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2397.java new file mode 100644 index 0000000000..2df9987c4d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2300/Issue2397.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.issue_2300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.io.Serializable; +import java.util.List; + +public class Issue2397 extends TestCase { + + public void test_for_bug(){ + String jsonStr = "{\"items\":[{\"id\":1,\"name\":\"kata\"}]}"; + TestReply testReply = JSON.parseObject(jsonStr, new TypeReference() { + }); + + Assert.assertEquals(testReply.getItems().get(0).getId() , 1); + } + + public static class SuperBaseReply { + private List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + } + + public static class BaseReply extends SuperBaseReply { + + } + + public static class Msg implements Serializable { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Msg(int id, String name) { + this.id = id; + this.name = name; + } + } + + public static class TestReply extends BaseReply { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2428.java b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2428.java new file mode 100644 index 0000000000..c694046541 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2428.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.issue_2400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.PropertyNamingStrategy; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class Issue2428 extends TestCase { + private String myName; + private NestedBean nestedBean; + + @AllArgsConstructor + @Data + public static class NestedBean { + private String myId; + } + + public void test_for_issue() { + Issue2428 demoBean = new Issue2428(); + demoBean.setMyName("test name"); + demoBean.setNestedBean(new NestedBean("test id")); + String text = JSON.toJSONString(JSON.toJSON(demoBean), SerializerFeature.SortField); + assertEquals("{\"nestedBean\":{\"myId\":\"test id\"},\"myName\":\"test name\"}", text); + + SerializeConfig serializeConfig = new SerializeConfig(); + serializeConfig.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase; + text = JSON.toJSONString(JSON.toJSON(demoBean, serializeConfig), SerializerFeature.SortField); + assertEquals("{\"my_name\":\"test name\",\"nested_bean\":{\"my_id\":\"test id\"}}", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2429.java b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2429.java new file mode 100644 index 0000000000..807a77899e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2429.java @@ -0,0 +1,11 @@ +package com.alibaba.json.bvt.issue_2400; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue2429 extends TestCase { + public void testForIssue() { + String str = "{\"schema\":{$ref:\"111\"},\"name\":\"ft\",\"age\":12,\"address\":\"杭州\"}"; + JSON.parseObject(str); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2430.java b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2430.java new file mode 100644 index 0000000000..5eef27eb24 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2430.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.issue_2400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.google.common.collect.ArrayListMultimap; + +import junit.framework.TestCase; + +public class Issue2430 extends TestCase { + public void testForIssue() { + ArrayListMultimap multimap = ArrayListMultimap.create(); + multimap.put("a", "1"); + multimap.put("a", "2"); + multimap.put("a", "3"); + multimap.put("b", "1"); + + VO vo = new VO(); + vo.setMap(multimap); + vo.setName("zhangsan"); + + assertEquals("{\"map\":{\"a\":[\"1\",\"2\",\"3\"],\"b\":[\"1\"]},\"name\":\"zhangsan\"}", + JSON.toJSONString(vo, SerializerFeature.MapSortField)); + } + + public void testForIssue2() { + String jsonString = "{\"map\":{\"a\":[\"1\",\"2\",\"3\"],\"b\":[\"1\"]},\"name\":\"zhangsan\"}"; + VO vo = JSON.parseObject(jsonString, VO.class); + assertEquals("{\"map\":{\"a\":[\"1\",\"2\",\"3\"],\"b\":[\"1\"]},\"name\":\"zhangsan\"}", JSON.toJSONString(vo, SerializerFeature.MapSortField)); + } + + public static class VO { + private String name; + private ArrayListMultimap map; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ArrayListMultimap getMap() { + return map; + } + + public void setMap(ArrayListMultimap map) { + this.map = map; + } + + @Override + public String toString() { + return String.format("VO:{name->%s,map->%s}", this.name, this.map.toString()); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2447.java b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2447.java new file mode 100644 index 0000000000..0d6ac9b5ad --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2447.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.issue_2400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class Issue2447 extends TestCase { + + public void test_for_issue() { + VO vo = new VO(); + vo.id = 123; + vo.location = new Location(127, 37); + + Object obj = JSON.toJSON(vo); + String text = JSON.toJSONString(obj, SerializerFeature.SortField); + assertEquals("{\"latitude\":37,\"id\":123,\"longitude\":127}", text); + } + + public void test_for_issue2() { + VO2 vo = new VO2(); + vo.id = 123; + vo.properties.put("latitude", 37); + vo.properties.put("longitude", 127); + + Object obj = JSON.toJSON(vo); + String text = JSON.toJSONString(obj, SerializerFeature.SortField); + assertEquals("{\"latitude\":37,\"id\":123,\"longitude\":127}", text); + } + + public static class VO { + + public int id; + + @JSONField(unwrapped = true) + public Location location; + } + + public static class VO2 { + public int id; + + @JSONField(unwrapped = true) + public Map properties = new LinkedHashMap(); + } + + + public static class Location { + public int longitude; + public int latitude; + + public Location() {} + + public Location(int longitude, int latitude) { + this.longitude = longitude; + this.latitude = latitude; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2464.java b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2464.java new file mode 100644 index 0000000000..72328a9fbe --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2464.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.issue_2400; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue2464 extends TestCase { + public void test1() throws Exception { + String json = "[\"Mjg4NDd8MXxjb20uY2Fpbmlhby5pc2ltdS5xLndvcmtmbG93LmNvbGxlY3Quc2NoZWR1bGUuaW1wbC5UYXNrU3RvcENvbGxlY3RDYWxsQmFja0hhbmRsZXJJbXBsfDB8\",1]"; + Object result = JSON.parseArray(json,new Class[]{byte[].class,Integer.class}); + assertEquals(json, JSON.toJSONString(result)); + + result = JSON.parseArray(json,new Class[]{char[].class,Integer.class}); + assertEquals(json, JSON.toJSONString(result)); + } + + public void test2() throws Exception { + String json = "[1,\"Mjg4NDd8MXxjb20uY2Fpbmlhby5pc2ltdS5xLndvcmtmbG93LmNvbGxlY3Quc2NoZWR1bGUuaW1wbC5UYXNrU3RvcENvbGxlY3RDYWxsQmFja0hhbmRsZXJJbXBsfDB8\"]"; + Object result = JSON.parseArray(json,new Class[]{Integer.class,byte[].class}); + assertEquals(json, JSON.toJSONString(result)); + + result = JSON.parseArray(json,new Class[]{Integer.class, char[].class}); + assertEquals(json, JSON.toJSONString(result)); + } + + public void test3() throws Exception { + String json = "[1,\"aaa\",\"bbb\",\"ccc\"]"; + Object result = JSON.parseArray(json, new Class[]{Integer.class, String[].class}); + assertEquals("[1,[\"aaa\",\"bbb\",\"ccc\"]]", JSON.toJSONString(result)); + } + + public void test4() throws Exception { + String json = "[1,97,98,99]"; + Object result = JSON.parseArray(json, new Class[]{Integer.class, byte[].class}); + assertEquals("[1,\"YWJj\"]", JSON.toJSONString(result)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2488.java b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2488.java new file mode 100644 index 0000000000..85f183b9c4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2400/Issue2488.java @@ -0,0 +1,92 @@ +package com.alibaba.json.bvt.issue_2400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Issue2488 extends TestCase { + public void testForIssue_1() { + String a = "{\"$a_b\":\"a1_b2\",\"_c_d\":\"c3_d4\",\"aaaa\":\"CC\",\"__flag\":\"true\",\"$flag\":\"true\"}"; + JSONObject obj = (JSONObject) JSONObject.parse(a); + TestJsonObj2 stu = JSONObject.toJavaObject(obj, TestJsonObj2.class); + assertEquals("TestJsonObj2{$a_b=\"a1_b2\",_c_d=\"c3_d4\",aaaa=\"CC\",__flag=true,$flag=true}", stu.toString()); + } + + public void testForIssue_2() { + String a = "{\"$a_b\":\"aa3_bb4\",\"_c_d\":\"cc1_dd2\",\"aaaa\":\"BB\",\"__flag\":\"true\",\"$flag\":\"true\"}"; + TestJsonObj2 stu = JSON.parseObject(a, TestJsonObj2.class); + assertEquals("TestJsonObj2{$a_b=\"aa3_bb4\",_c_d=\"cc1_dd2\",aaaa=\"BB\",__flag=true,$flag=true}", + stu.toString()); + } + + public void testForIssue_3() { + TestJsonObj2 vo = new TestJsonObj2("aa_bb", "cc_dd", "AA", true, true); + String text = JSON.toJSONString(vo); + assertEquals("{\"$a_b\":\"aa_bb\",\"$flag\":true,\"__flag\":true,\"_c_d\":\"cc_dd\",\"aaaa\":\"AA\"}", text); + } + + public static class TestJsonObj2 { + private String $a_b; + private String _c_d; + private String aaaa; + private boolean __flag; + private boolean $flag; + + public TestJsonObj2() { + } + + public TestJsonObj2(String $a_b, String _c_d, String aaaa, boolean __flag, boolean $flag) { + this.$a_b = $a_b; + this._c_d = _c_d; + this.aaaa = aaaa; + this.__flag = __flag; + this.$flag = $flag; + } + + public String get$a_b() { + return $a_b; + } + + public void set$a_b(String $a_b) { + this.$a_b = $a_b; + } + + public String get_c_d() { + return _c_d; + } + + public void set_c_d(String _c_d) { + this._c_d = _c_d; + } + + public String getaaaa() { + return aaaa; + } + + public void setaaaa(String aaaa) { + this.aaaa = aaaa; + } + + public boolean is__flag() { + return __flag; + } + + public void set__flag(boolean __flag) { + this.__flag = __flag; + } + + public boolean is$flag() { + return $flag; + } + + public void set$flag(boolean $flag) { + this.$flag = $flag; + } + + @Override + public String toString() { + return String.format("TestJsonObj2{$a_b=\"%s\",_c_d=\"%s\",aaaa=\"%s\",__flag=%b,$flag=%b}", this.$a_b, + this._c_d, this.aaaa, this.__flag, this.$flag); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2515.java b/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2515.java new file mode 100644 index 0000000000..c4806969ab --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2515.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_2500; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue2515 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\n" + + " \"a\":\"{\\\"b\\\":\\\"cd\\\"}\"\n" + + "}"; + + JSONObject obj = JSON.parseObject(json); + + assertEquals("cd", JSONPath.eval(obj, "$.a.b")); + assertEquals(1, JSONPath.eval(obj, "$.a.size")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2516.java b/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2516.java new file mode 100644 index 0000000000..8bebaa402d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2516.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.issue_2500; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.Collection; +import java.util.List; + +public class Issue2516 extends TestCase +{ + public void test_for_issue() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.toJavaObject(JSONObject.class); + jsonObject.toJavaObject(JSON.class); + + new JSONArray().toJavaObject(JSON.class); + new JSONArray().toJavaObject(JSONArray.class); + new JSONArray().toJavaObject(Collection.class); + new JSONArray().toJavaObject(List.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2579.java b/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2579.java new file mode 100644 index 0000000000..5a15d74097 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2500/Issue2579.java @@ -0,0 +1,207 @@ +package com.alibaba.json.bvt.issue_2500; + +import java.awt.Point; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.UUID; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; + +import junit.framework.TestCase; + +public class Issue2579 extends TestCase { + + // 场景:走ASM + public void test_for_issue1() throws Exception { + run_test("MyPoint1"); + } + + // 场景:不走ASM,通过JSONType(asm=false),关闭了ASM + public void test_for_issue2() throws Exception { + run_test("MyPoint2"); + } + + // 场景:随机顺序组合JSON字符串测试2000次 + private void run_test(String className) { + String begin = "{"; + String end = "}"; + String jsonString; + for (int i = 1; i < 2000; i++) { + jsonString = getString(i, className); + jsonString = begin + jsonString + end; + try { + Object obj = JSON.parse(jsonString, Feature.SupportAutoType); + if ("MyPoint1".equals(className)) { + Assert.assertEquals(i, ((MyPoint1) obj).getBatchNumber()); + } else { + Assert.assertEquals(i, ((MyPoint2) obj).getBatchNumber()); + } + } catch (JSONException e) { + System.out.println(jsonString); + e.printStackTrace(); + Assert.assertTrue(false); + } + } + } + + private static String getString(int batchNumber, String className) { + List list = new ArrayList(); + list.add("\"@type\":\"com.alibaba.json.bvt.issue_2500.Issue2579$" + className + "\""); + list.add("\"date\":1563867975335"); + list.add("\"id\":\"0f075036-9e52-4821-800a-9c51761a7227b\""); + list.add("\"location\":{\"@type\":\"java.awt.Point\",\"x\":11,\"y\":1}"); + list.add("\"point\":{\"@type\":\"java.awt.Point\",\"x\":9,\"y\":1}"); + list.add( + "\"pointArr\":[{\"@type\":\"java.awt.Point\",\"x\":4,\"y\":6},{\"@type\":\"java.awt.Point\",\"x\":7,\"y\":8}]"); + list.add("\"strArr\":[\"te-st\",\"tes-t2\"]"); + list.add("\"x\":2.0D"); + list.add("\"y\":3.0D"); + list.add("\"batchNumber\":" + batchNumber); + + Iterator it = list.iterator(); + StringBuffer buffer = new StringBuffer(); + int len; + int index; + while (it.hasNext()) { + len = list.size(); + index = getRandomIndex(len); + buffer.append(list.get(index)); + buffer.append(","); + list.remove(index); + } + buffer.deleteCharAt(buffer.length() - 1); + return buffer.toString(); + } + + private static int getRandomIndex(int length) { + Random random = new Random(); + return random.nextInt(length); + } + + @SuppressWarnings("serial") + public static class MyPoint1 extends Point { + private UUID id; + private int batchNumber; + private Point point = new Point(); + private String[] strArr = { "te-st", "tes-t2" }; + private Date date = new Date(); + private Point[] pointArr = { new Point(), new Point() }; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public int getBatchNumber() { + return batchNumber; + } + + public void setBatchNumber(int batchNumber) { + this.batchNumber = batchNumber; + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + public String[] getStrArr() { + return strArr; + } + + public void setStrArr(String[] strArr) { + this.strArr = strArr; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public Point[] getPointArr() { + return pointArr; + } + + public void setPointArr(Point[] pointArr) { + this.pointArr = pointArr; + } + + } + + @SuppressWarnings("serial") + @JSONType(asm = false) + public static class MyPoint2 extends Point { + private UUID id; + private int batchNumber; + private Point point = new Point(); + private String[] strArr = { "te-st", "tes-t2" }; + private Date date = new Date(); + private Point[] pointArr = { new Point(), new Point() }; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public int getBatchNumber() { + return batchNumber; + } + + public void setBatchNumber(int batchNumber) { + this.batchNumber = batchNumber; + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + public String[] getStrArr() { + return strArr; + } + + public void setStrArr(String[] strArr) { + this.strArr = strArr; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public Point[] getPointArr() { + return pointArr; + } + + public void setPointArr(Point[] pointArr) { + this.pointArr = pointArr; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2606.java b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2606.java new file mode 100644 index 0000000000..2378accaaf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2606.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.issue_2600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue2606 extends TestCase { + @Override + public void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getDefault(); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + String str = "2019-07-03 19:34:22,547"; + Date d = TypeUtils.castToDate(str); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS"); + sdf.setTimeZone(TimeZone.getDefault()); + assertEquals(str, sdf.format(d)); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2617.java b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2617.java new file mode 100644 index 0000000000..39b77fd036 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2617.java @@ -0,0 +1,108 @@ +package com.alibaba.json.bvt.issue_2600; + +import java.lang.reflect.Type; +import java.util.Date; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.MapDeserializer; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +import junit.framework.TestCase; + +public class Issue2617 extends TestCase { + + // 场景:通过@JSONField(deserializeUsing = MyDateDeserializer.class)来自定义解析 + public void test_for_issue() throws Exception { + String str = "{ \"a\": { \"date\": 6, \"day\": 2, \"hours\": 18, \"minutes\": 37, \"month\": 7, \"seconds\": 1, \"time\": 1565087821607, \"timezoneOffset\": -480, \"year\": 119 } }"; + Date date = JSON.parseObject(str, A.class).getA(); + Date date2 = new Date(1565087821607L); + + assertEquals(date2.getDate(), date.getDate()); + assertEquals(date2.getDay(), date.getDay()); + assertEquals(date2.getHours(), date.getHours()); + assertEquals(date2.getMinutes(), date.getMinutes()); + assertEquals(date2.getMonth(), date.getMonth()); + assertEquals(date2.getSeconds(), date.getSeconds()); + assertEquals(date2.getTime(), date.getTime()); + assertEquals(date2.getTimezoneOffset(), date.getTimezoneOffset()); + assertEquals(date2.getYear(), date.getYear()); + } + + // 场景:通过ParserConfig的putDeserializer自定义解析 + public void test_for_issue_2() throws Exception { + String str = "{ \"a\": { \"date\": 6, \"day\": 2, \"hours\": 18, \"minutes\": 37, \"month\": 7, \"seconds\": 1, \"time\": 1565087821607, \"timezoneOffset\": -480, \"year\": 119 } }"; + + ParserConfig config = new ParserConfig(); + config.putDeserializer(Date.class, new MyDateDeserializer()); + + Date date = ((A2) JSON.parseObject(str, A2.class, config)).getA(); + + assertEquals(date.getDate(), date.getDate()); + assertEquals(date.getDay(), date.getDay()); + assertEquals(date.getHours(), date.getHours()); + assertEquals(date.getMinutes(), date.getMinutes()); + assertEquals(date.getMonth(), date.getMonth()); + assertEquals(date.getSeconds(), date.getSeconds()); + assertEquals(date.getTime(), date.getTime()); + assertEquals(date.getTimezoneOffset(), date.getTimezoneOffset()); + assertEquals(date.getYear(), date.getYear()); + } + + // 场景:还原楼主提出的报错场景 + public void test_for_issue_3() throws Exception { + String str = "{ \"a\": { \"date\": 6, \"day\": 2, \"hours\": 18, \"minutes\": 37, \"month\": 7, \"seconds\": 1, \"time\": 1565087821607, \"timezoneOffset\": -480, \"year\": 119 } }"; + try { + JSON.parseObject(str, A2.class); + } catch (JSONException e) { + assertEquals("syntax error, expect }, actual ,", e.getMessage()); + } + } + + public static class A { + @JSONField(deserializeUsing = MyDateDeserializer.class) + private Date a; + + public Date getA() { + return a; + } + + public void setA(Date a) { + this.a = a; + } + } + + public static class A2 { + private Date a; + + public Date getA() { + return a; + } + + public void setA(Date a) { + this.a = a; + } + } + + public static class MyDateDeserializer implements ObjectDeserializer { + + @SuppressWarnings("unchecked") + @Override + public Date deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + Map map = MapDeserializer.instance.deserialze(parser, Map.class, fieldName); + long milliseconds = (Long) map.get("time"); + return new Date(milliseconds); + } + + @Override + public int getFastMatchToken() { + return JSONToken.LBRACE; + } + + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2628.java b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2628.java new file mode 100644 index 0000000000..c9c564bebc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2628.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.issue_2600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.math.BigInteger; + +public class Issue2628 extends TestCase { + public void test_for_issue() throws Exception { + long MAX_LONG = Long.MAX_VALUE; //9223372036854775807 + long MIN_LONG = Long.MIN_VALUE; //-9223372036854775808 + + String s1 = "9423372036854775807"; //-9423372036854775808 + BigInteger bi1 = JSON.parseObject(s1, BigInteger.class); //没问题 + assertEquals("9423372036854775807", bi1.toString()); + + BigInteger bi2 = new BigInteger(s1); //没问题 + assertEquals("9423372036854775807", bi2.toString()); + + Tobject tobj1 = new Tobject(); + tobj1.setBi(bi2); //没问题 + assertEquals("9423372036854775807", tobj1.getBi().toString());; + + String s2 = JSON.toJSONString(tobj1); + Tobject tobj2 = JSON.parseObject(s2, Tobject.class); //有问题 + assertEquals("9423372036854775807", tobj2.getBi().toString()); + } + + static class Tobject { + private BigInteger bi; + + public BigInteger getBi() { + return bi; + } + public void setBi(BigInteger bi) { + this.bi = bi; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2635.java b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2635.java new file mode 100644 index 0000000000..e2b864697d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2635.java @@ -0,0 +1,11 @@ +package com.alibaba.json.bvt.issue_2600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue2635 extends TestCase { + public void testForIssue() throws Exception { + String json = "{\"dt\":\"evt\",\"pr\":{\"_订单金额\":\"100\",\"$AA_epid#_优惠券金额\":848,\"$AA_eptp#_Client_id\":\"string\",\"$AA_eptp#_访客类别\":\"string\",\"$AA_uid\":856,\"$AA_eptp#_优惠券类型\":\"string\",\"$AA_sid\":1565851940554,\"$AA_eptp#_优惠券金额\":\"string\",\"$AA_epid#_订单金额\":855,\"$AA_epid#_订单号\":847,\"_优惠券名称\":\"60元优惠折扣券\",\"$eid\":\"小程序_订单确认\",\"$AA_eptp#_订单渠道\":\"string\",\"$ct\":1565854057608,\"$cuid\":\"YYYY\",\"_Experiment_id\":\"0\",\"$AA_epid#_优惠券类型\":853,\"_优惠券类型\":\"D4\",\"_店主ID\":\"53890475\",\"_优惠券金额\":\"100\",\"$AA_eptp#_Experiment_id\":\"string\",\"$AA_epid#_优惠券名称\":850,\"$AA_eptp#_优惠券名称\":\"string\",\"_优惠券 ID\":\"916090\",\"$AA_epid#_店主ID\":851,\"$tz\":28800000,\"$AA_eptp#_优惠券 ID\":\"string\",\"$AA_eptp#_订单号\":\"string\",\"$AA_AAid\":7097,\"$AA_eptp#_店主ID\":\"string\",\"$AA_eid\":175,\"$AA_epid#_Client_id\":21544,\"$sid\":1569851940554,\"_订单渠道\":\"云购小程序\",\"_Client_id\":\"1e8e82fe-c90f-f363-6693-143677891dfa\",\"$AA_epid#_事件类型\":3073,\"$AA_epid#_分享来源用户\":14694,\"$AA_epid#_Experiment_id\":21543,\"_分享来源用户\":\"53890475\",\"$AA_eptp#_订单金额\":\"string\",\"$AA_epid#_订单渠道\":852,\"$AA_eptp#_分享来源用户\":\"string\",\"$url\":\"http://171.90.15:87/CCTesting/data/toPrivateTest?test=https://u2.CCio.com/CC.js&appkey=b8868018cIO94114ad7a81cd5f1ddafd\",\"_访客类别\":\"ABO\",\"$AA_epid#_优惠券 ID\":854,\"_订单号\":\"PP190830000683\",\"_下单用户\":\"720003734\",\"$AA_epid#_下单用户\":849,\"$AA_eptp#_事件类型\":\"string\",\"$uuid\":\"5c910d893bc341aBHN02119708ec13df\",\"$AA_eptp#_下单用户\":\"string\",\"$AA_epid#_访客类别\":856,\"$AA_did\":6736,\"$referrer_domain\":\"10.33.180.15:8088\",\"_事件类型\":\"订单确认\",\"$ref\":\"http://10.283.100.10:8088/CCTesting/data/toPrivate\"}}\n"; + JSON.parseObject(json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2678.java b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2678.java new file mode 100644 index 0000000000..f0ed3fa272 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2678.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt.issue_2600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue2678 extends TestCase { + public void test_field() throws Exception { + Person person = new Person(); + person.setName("Ariston"); + person.setAge(23); + String json = JSON.toJSONString(person); + assertEquals("{\"age\":23,'name':'Ariston'}", json); + } + + public void test_getter() throws Exception { + Person2 person = new Person2(); + person.setName("Ariston"); + person.setAge(23); + String json = JSON.toJSONString(person); + assertEquals("{\"age\":23,'name':'Ariston'}", json); + } + + static class Person { + + @JSONField(serialzeFeatures = SerializerFeature.UseSingleQuotes) + private String name; + + private int age; + + public String getName() + { + return name; + } + + public void setName( String name ) + { + this.name = name; + } + + public int getAge() + { + return age; + } + + public void setAge( int age ) + { + this.age = age; + } + } + + static class Person2 { + + private String name; + + private int age; + + @JSONField(serialzeFeatures = SerializerFeature.UseSingleQuotes) + public String getName() + { + return name; + } + + public void setName( String name ) + { + this.name = name; + } + + public int getAge() + { + return age; + } + + public void setAge( int age ) + { + this.age = age; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2685.java b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2685.java new file mode 100644 index 0000000000..1745380f0b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2685.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.issue_2600; + +import java.lang.reflect.Type; + +import org.marre.sms.SmsMessage; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.StringCodec; +import com.zx.sms.codec.cmpp.msg.CmppSubmitResponseMessage; +import com.zx.sms.codec.smgp.msg.SMGPSubmitMessage; +import com.zx.sms.common.util.CMPPCommonUtil; +import com.zx.sms.common.util.MsgId; + +import junit.framework.TestCase; + +public class Issue2685 extends TestCase { + public void test_field() throws Exception { + SMGPSubmitMessage smgpSubmitMessage = new SMGPSubmitMessage(); + smgpSubmitMessage.setSequenceNo(1); + smgpSubmitMessage.setServiceId("hell"); + smgpSubmitMessage.setMsgContent("hello"); // 注释掉可以正常 + smgpSubmitMessage.setChargeTermId("123555"); + smgpSubmitMessage.setSrcTermId("10086"); + CmppSubmitResponseMessage submitResponseMessage = new CmppSubmitResponseMessage(1); + submitResponseMessage.setResult(0); + submitResponseMessage.setMsgId(new MsgId()); + + String smsMsg = JSON.toJSONString(smgpSubmitMessage); + // System.out.println(smsMsg); + + JSON.addMixInAnnotations(SMGPSubmitMessage.class, Mixin.class); + smgpSubmitMessage = JSON.parseObject(smsMsg, SMGPSubmitMessage.class); + assertEquals("hello", smgpSubmitMessage.getMsgContent()); + } + + public interface Mixin { + @JSONField(deserializeUsing = MyDeserializer.class) + void setMsgContent(SmsMessage msg); + } + + public static class MyDeserializer implements ObjectDeserializer { + + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + String msg = StringCodec.deserialze(parser); + return (T) CMPPCommonUtil.buildTextMessage(msg); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2689.java b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2689.java new file mode 100644 index 0000000000..5faa60fef9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2600/Issue2689.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.issue_2600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import junit.framework.TestCase; + +public class Issue2689 extends TestCase +{ + public void test_0() throws Exception { + Exception error = null; + try { + JSON.parse("{\"val\":\"\\x~\""); + } catch (JSONException ex) { + error = ex; + } + assertTrue( + error.getMessage().startsWith("invalid escape character")); + } + + public void test_1() throws Exception { + Exception error = null; + try { + JSON.parse("{\"val\":'\\x~'"); + } catch (JSONException ex) { + error = ex; + } + assertTrue( + error.getMessage().startsWith("invalid escape character")); + } + + public void test_2() throws Exception { + Exception error = null; + try { + JSON.parse("{\"val\":'\\x1'"); + } catch (JSONException ex) { + error = ex; + } + assertTrue( + error.getMessage().startsWith("invalid escape character")); + } + + public void test_3() throws Exception { + Exception error = null; + try { + JSON.parse("{\"val\":'\\x'"); + } catch (JSONException ex) { + error = ex; + } + assertTrue( + error.getMessage().startsWith("invalid escape character")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2703.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2703.java new file mode 100644 index 0000000000..0ce15c4fe1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2703.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Issue2703 extends TestCase { + public void test_for_issue() { + Object a = JSON.toJavaObject(new JSONObject(), JSON.class); + assertTrue(a instanceof JSONObject); + + Object b = new JSONObject().toJavaObject(JSON.class); + assertTrue(b instanceof JSONObject); + + Object c = JSON.toJavaObject(new JSONArray(), JSON.class); + assertTrue(c instanceof JSONArray); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2721Test.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2721Test.java new file mode 100644 index 0000000000..23b52a81d1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2721Test.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +public class Issue2721Test extends TestCase +{ + public void test2721() { + String chineseKeyString = "[{\"名称\": \"脆皮青豆\", \"配料\": [\"豌豆\", \"棕榈油\", \"白砂糖\", \"食用盐\", \"玉米淀粉\"]}]"; + System.out.println(JSONPath.read(chineseKeyString, "$[名称 = '脆皮青豆']")); + // [{"名称":"脆皮青豆","配料":["豌豆","棕榈油","白砂糖","食用盐","玉米淀粉"]}] + + String normalKeyString = "[{ \"name\": \"脆皮青豆\", \"配料\": [\"豌豆\", \"棕榈油\", \"白砂糖\", \"食用盐\", \"玉米淀粉\"] }]"; + System.out.println(JSONPath.read(normalKeyString, "$[name = '脆皮青豆']")); + // [{"name":"脆皮青豆","配料":["豌豆","棕榈油","白砂糖","食用盐","玉米淀粉"]}] +// + Assert.assertFalse("Chinese Key is NOT OK, Array length is 0!", ((List) JSONPath.read(chineseKeyString, "$[名称 = '脆皮青豆']")).isEmpty()); + Assert.assertFalse("Chinese Key is NOT OK, Array length is 0!", ((List) JSONPath.read(normalKeyString, "$[name = '脆皮青豆']")).isEmpty()); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2736.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2736.java new file mode 100644 index 0000000000..7965ca23df --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2736.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class Issue2736 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject s = JSONObject.parseObject("{1:2,3:4}"); + for(String s1 : s.keySet()){ + System.out.println(s1); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2743.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2743.java new file mode 100644 index 0000000000..cd80305650 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2743.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.issue_2700; + +//import static org.junit.Assert.assertArrayEquals; +// +//import java.util.regex.Pattern; + +import com.alibaba.fastjson.JSONPath; + +import junit.framework.TestCase; + +public class Issue2743 extends TestCase { + + // 场景:验证字符串数组,楼主提供的用例 + public void test_0() throws Exception { + String json = "{\"info\":{\"com.xxx.service.xxxServiceForOrder@queryGoodsV2(Long,Long,Long)\":[{\"method\":\"queryPrepayGoodsV2\"}]}}"; + Object obj = JSONPath.extract(json, + "$['info']['com.xxx.service.xxxServiceForOrder@queryGoodsV2(Long,Long,Long)']"); + assertEquals("[{\"method\":\"queryPrepayGoodsV2\"}]", obj.toString()); + } + + // 场景:验证数字数组 + public void test_1() throws Exception { + String json = "[10,11,12,13,14,15,16,17,18,19,20]"; + Object obj = JSONPath.extract(json, "$[3,4]"); + assertEquals("[13,14]", obj.toString()); + } +// +// // 场景:验证修复bug用的正则表达式 +// public void test_2() throws Exception { +// String strArrayRegex = "\'\\s*,\\s*\'"; +// Pattern strArrayPattern = Pattern.compile(strArrayRegex); +// +// assertFalse( +// strArrayPattern.matcher("'com.xxx.service.xxxServiceForOrder@queryGoodsV2(Long,Long,Long)'").find()); +// assertTrue(strArrayPattern.matcher("'id','name'").find()); +// assertTrue(strArrayPattern.matcher("'id' , 'name'").find()); +// assertTrue(strArrayPattern.matcher("'id', 'name'").find()); +// assertTrue(strArrayPattern.matcher("'id' ,'name'").find()); +// +// String[] strs = { "'com.xxx.service.xxxServiceForOrder@queryGoodsV2(Long,Long,Long)'" }; +// assertArrayEquals(strs, strs[0].split(strArrayRegex)); +// +// strs = new String[] { "'id", "name'" }; +// assertArrayEquals(strs, "'id','name'".split(strArrayRegex)); +// assertArrayEquals(strs, "'id' , 'name'".split(strArrayRegex)); +// assertArrayEquals(strs, "'id' ,'name'".split(strArrayRegex)); +// assertArrayEquals(strs, "'id', 'name'".split(strArrayRegex)); +// } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2752.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2752.java new file mode 100644 index 0000000000..cb37e82b4d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2752.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.issue_2700; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.MiscCodec; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.spi.Module; + +import junit.framework.TestCase; + +public class Issue2752 extends TestCase { + + public void test_for_issue() { + Pageable pageRequest = new PageRequest(0, 10, new Sort(new Sort.Order("id, desc"))); + SerializeConfig config = new SerializeConfig(); + config.register(new MyModule()); + String result = JSON.toJSONString(pageRequest, config); + assertTrue(result.indexOf("\"property\":\"id, desc\"") != -1); + } + + public class MyModule implements Module { + + @Override + public ObjectDeserializer createDeserializer(ParserConfig config, Class type) { + if (type.getName().equals("org.springframework.data.domain.Sort")) { + return MiscCodec.instance; + } + return null; + } + + @Override + public ObjectSerializer createSerializer(SerializeConfig config, Class type) { + if (type.getName().equals("org.springframework.data.domain.Sort")) { + return MiscCodec.instance; + } + return null; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2754.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2754.java new file mode 100644 index 0000000000..6950206f30 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2754.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; + +public class Issue2754 extends TestCase { + public void test_for_issue0() throws Exception { + String s = "{\"p1\":\"2019-09-18T20:35:00+12:45\"}"; + C c = JSON.parseObject(s, C.class); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + sdf.setTimeZone(TimeZone.getTimeZone("Pacific/Chatham")); + assertEquals("2019-09-18T20:35:00+12:45", sdf.format(c.p1.getTime())); + } + + public void test_for_issue1() throws Exception { + String s = "{\"p1\":\"2019-09-18T20:35:00+12:45\"}"; + C c = JSON.parseObject(s, C.class); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + sdf.setTimeZone(TimeZone.getTimeZone("NZ-CHAT")); + assertEquals("2019-09-18T20:35:00+12:45", sdf.format(c.p1.getTime())); + } + + public void test_for_issue2() throws Exception { + String s = "{\"p1\":\"2019-09-18T20:35:00+05:45\"}"; + C c = JSON.parseObject(s, C.class); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kathmandu")); + assertEquals("2019-09-18T20:35:00+05:45", sdf.format(c.p1.getTime())); + } + + public void test_for_issue3() throws Exception { + String s = "{\"p1\":\"2019-09-18T20:35:00+05:45\"}"; + C c = JSON.parseObject(s, C.class); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + sdf.setTimeZone(TimeZone.getTimeZone("Asia/Katmandu")); + assertEquals("2019-09-18T20:35:00+05:45", sdf.format(c.p1.getTime())); + } + + public void test_for_issue4() throws Exception { + String s = "{\"p1\":\"2019-09-18T20:35:00+08:45\"}"; + C c = JSON.parseObject(s, C.class); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + sdf.setTimeZone(TimeZone.getTimeZone("Australia/Eucla")); + assertEquals("2019-09-18T20:35:00+08:45", sdf.format(c.p1.getTime())); + } + public static class C{ + public Calendar p1; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2772.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2772.java new file mode 100644 index 0000000000..dd4dc67203 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2772.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.Date; + +public class Issue2772 extends TestCase { + public void test_for_issue() throws Exception { + { + java.sql.Time time = java.sql.Time.valueOf("12:13:14"); + long millis = time.getTime(); + assertEquals(Long.toString(millis/1000), JSON.toJSONStringWithDateFormat(time, "unixtime")); + assertEquals(Long.toString(millis), JSON.toJSONStringWithDateFormat(time, "millis")); + } + + long millis = System.currentTimeMillis(); + assertEquals(Long.toString(millis), JSON.toJSONStringWithDateFormat(new Date(millis), "millis")); + assertEquals(Long.toString(millis/1000), JSON.toJSONStringWithDateFormat(new Date(millis), "unixtime")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2779.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2779.java new file mode 100644 index 0000000000..742443a18b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2779.java @@ -0,0 +1,2221 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.List; + +public class Issue2779 extends TestCase { + + public void test_for_issue() throws Exception { + String str = JSON.toJSONString(new Model()); + JSON.parseObject(str, Model.class); + } + + public static class Model { + private List f000; + private List f001; + private List f002; + private List f003; + private List f004; + private List f005; + private List f006; + private List f007; + private List f008; + private List f009; + private List f010; + private List f011; + private List f012; + private List f013; + private List f014; + private List f015; + private List f016; + private List f017; + private List f018; + private List f019; + private List f020; + private List f021; + private List f022; + private List f023; + private List f024; + private List f025; + private List f026; + private List f027; + private List f028; + private List f029; + private List f030; + private List f031; + private List f032; + private List f033; + private List f034; + private List f035; + private List f036; + private List f037; + private List f038; + private List f039; + private List f040; + private List f041; + private List f042; + private List f043; + private List f044; + private List f045; + private List f046; + private List f047; + private List f048; + private List f049; + private List f050; + private List f051; + private List f052; + private List f053; + private List f054; + private List f055; + private List f056; + private List f057; + private List f058; + private List f059; + private List f060; + private List f061; + private List f062; + private List f063; + private List f064; + private List f065; + private List f066; + private List f067; + private List f068; + private List f069; + private List f070; + private List f071; + private List f072; + private List f073; + private List f074; + private List f075; + private List f076; + private List f077; + private List f078; + private List f079; + private List f080; + private List f081; + private List f082; + private List f083; + private List f084; + private List f085; + private List f086; + private List f087; + private List f088; + private List f089; + private List f090; + private List f091; + private List f092; + private List f093; + private List f094; + private List f095; + private List f096; + private List f097; + private List f098; + private List f099; + + + + + private List f100; + private List f101; + private List f102; + private List f103; + private List f104; + private List f105; + private List f106; + private List f107; + private List f108; + private List f109; + private List f110; + private List f111; + private List f112; + private List f113; + private List f114; + private List f115; + private List f116; + private List f117; + private List f118; + private List f119; + private List f120; + private List f121; + private List f122; + private List f123; + private List f124; + private List f125; + private List f126; + private List f127; + private List f128; + private List f129; + private List f130; + private List f131; + private List f132; + private List f133; + private List f134; + private List f135; + private List f136; + private List f137; + private List f138; + private List f139; + private List f140; + private List f141; + private List f142; + private List f143; + private List f144; + private List f145; + private List f146; + private List f147; + private List f148; + private List f149; + private List f150; + private List f151; + private List f152; + private List f153; + private List f154; + private List f155; + private List f156; + private List f157; + private List f158; + private List f159; + private List f160; + private List f161; + private List f162; + private List f163; + private List f164; + private List f165; + private List f166; + private List f167; + private List f168; + private List f169; + private List f170; + private List f171; + private List f172; + private List f173; + private List f174; + private List f175; + private List f176; + private List f177; + private List f178; + private List f179; + private List f180; + private List f181; + private List f182; + private List f183; + private List f184; + private List f185; + private List f186; + private List f187; + private List f188; + private List f189; + private List f190; + private List f191; + private List f192; + private List f193; + private List f194; + private List f195; + private List f196; + private List f197; + private List f198; + private List f199; + + public List getF000() + { + return f000; + } + + public void setF000(List f000) + { + this.f000 = f000; + } + + public List getF001() + { + return f001; + } + + public void setF001(List f001) + { + this.f001 = f001; + } + + public List getF002() + { + return f002; + } + + public void setF002(List f002) + { + this.f002 = f002; + } + + public List getF003() + { + return f003; + } + + public void setF003(List f003) + { + this.f003 = f003; + } + + public List getF004() + { + return f004; + } + + public void setF004(List f004) + { + this.f004 = f004; + } + + public List getF005() + { + return f005; + } + + public void setF005(List f005) + { + this.f005 = f005; + } + + public List getF006() + { + return f006; + } + + public void setF006(List f006) + { + this.f006 = f006; + } + + public List getF007() + { + return f007; + } + + public void setF007(List f007) + { + this.f007 = f007; + } + + public List getF008() + { + return f008; + } + + public void setF008(List f008) + { + this.f008 = f008; + } + + public List getF009() + { + return f009; + } + + public void setF009(List f009) + { + this.f009 = f009; + } + + public List getF010() + { + return f010; + } + + public void setF010(List f010) + { + this.f010 = f010; + } + + public List getF011() + { + return f011; + } + + public void setF011(List f011) + { + this.f011 = f011; + } + + public List getF012() + { + return f012; + } + + public void setF012(List f012) + { + this.f012 = f012; + } + + public List getF013() + { + return f013; + } + + public void setF013(List f013) + { + this.f013 = f013; + } + + public List getF014() + { + return f014; + } + + public void setF014(List f014) + { + this.f014 = f014; + } + + public List getF015() + { + return f015; + } + + public void setF015(List f015) + { + this.f015 = f015; + } + + public List getF016() + { + return f016; + } + + public void setF016(List f016) + { + this.f016 = f016; + } + + public List getF017() + { + return f017; + } + + public void setF017(List f017) + { + this.f017 = f017; + } + + public List getF018() + { + return f018; + } + + public void setF018(List f018) + { + this.f018 = f018; + } + + public List getF019() + { + return f019; + } + + public void setF019(List f019) + { + this.f019 = f019; + } + + public List getF020() + { + return f020; + } + + public void setF020(List f020) + { + this.f020 = f020; + } + + public List getF021() + { + return f021; + } + + public void setF021(List f021) + { + this.f021 = f021; + } + + public List getF022() + { + return f022; + } + + public void setF022(List f022) + { + this.f022 = f022; + } + + public List getF023() + { + return f023; + } + + public void setF023(List f023) + { + this.f023 = f023; + } + + public List getF024() + { + return f024; + } + + public void setF024(List f024) + { + this.f024 = f024; + } + + public List getF025() + { + return f025; + } + + public void setF025(List f025) + { + this.f025 = f025; + } + + public List getF026() + { + return f026; + } + + public void setF026(List f026) + { + this.f026 = f026; + } + + public List getF027() + { + return f027; + } + + public void setF027(List f027) + { + this.f027 = f027; + } + + public List getF028() + { + return f028; + } + + public void setF028(List f028) + { + this.f028 = f028; + } + + public List getF029() + { + return f029; + } + + public void setF029(List f029) + { + this.f029 = f029; + } + + public List getF030() + { + return f030; + } + + public void setF030(List f030) + { + this.f030 = f030; + } + + public List getF031() + { + return f031; + } + + public void setF031(List f031) + { + this.f031 = f031; + } + + public List getF032() + { + return f032; + } + + public void setF032(List f032) + { + this.f032 = f032; + } + + public List getF033() + { + return f033; + } + + public void setF033(List f033) + { + this.f033 = f033; + } + + public List getF034() + { + return f034; + } + + public void setF034(List f034) + { + this.f034 = f034; + } + + public List getF035() + { + return f035; + } + + public void setF035(List f035) + { + this.f035 = f035; + } + + public List getF036() + { + return f036; + } + + public void setF036(List f036) + { + this.f036 = f036; + } + + public List getF037() + { + return f037; + } + + public void setF037(List f037) + { + this.f037 = f037; + } + + public List getF038() + { + return f038; + } + + public void setF038(List f038) + { + this.f038 = f038; + } + + public List getF039() + { + return f039; + } + + public void setF039(List f039) + { + this.f039 = f039; + } + + public List getF040() + { + return f040; + } + + public void setF040(List f040) + { + this.f040 = f040; + } + + public List getF041() + { + return f041; + } + + public void setF041(List f041) + { + this.f041 = f041; + } + + public List getF042() + { + return f042; + } + + public void setF042(List f042) + { + this.f042 = f042; + } + + public List getF043() + { + return f043; + } + + public void setF043(List f043) + { + this.f043 = f043; + } + + public List getF044() + { + return f044; + } + + public void setF044(List f044) + { + this.f044 = f044; + } + + public List getF045() + { + return f045; + } + + public void setF045(List f045) + { + this.f045 = f045; + } + + public List getF046() + { + return f046; + } + + public void setF046(List f046) + { + this.f046 = f046; + } + + public List getF047() + { + return f047; + } + + public void setF047(List f047) + { + this.f047 = f047; + } + + public List getF048() + { + return f048; + } + + public void setF048(List f048) + { + this.f048 = f048; + } + + public List getF049() + { + return f049; + } + + public void setF049(List f049) + { + this.f049 = f049; + } + + public List getF050() + { + return f050; + } + + public void setF050(List f050) + { + this.f050 = f050; + } + + public List getF051() + { + return f051; + } + + public void setF051(List f051) + { + this.f051 = f051; + } + + public List getF052() + { + return f052; + } + + public void setF052(List f052) + { + this.f052 = f052; + } + + public List getF053() + { + return f053; + } + + public void setF053(List f053) + { + this.f053 = f053; + } + + public List getF054() + { + return f054; + } + + public void setF054(List f054) + { + this.f054 = f054; + } + + public List getF055() + { + return f055; + } + + public void setF055(List f055) + { + this.f055 = f055; + } + + public List getF056() + { + return f056; + } + + public void setF056(List f056) + { + this.f056 = f056; + } + + public List getF057() + { + return f057; + } + + public void setF057(List f057) + { + this.f057 = f057; + } + + public List getF058() + { + return f058; + } + + public void setF058(List f058) + { + this.f058 = f058; + } + + public List getF059() + { + return f059; + } + + public void setF059(List f059) + { + this.f059 = f059; + } + + public List getF060() + { + return f060; + } + + public void setF060(List f060) + { + this.f060 = f060; + } + + public List getF061() + { + return f061; + } + + public void setF061(List f061) + { + this.f061 = f061; + } + + public List getF062() + { + return f062; + } + + public void setF062(List f062) + { + this.f062 = f062; + } + + public List getF063() + { + return f063; + } + + public void setF063(List f063) + { + this.f063 = f063; + } + + public List getF064() + { + return f064; + } + + public void setF064(List f064) + { + this.f064 = f064; + } + + public List getF065() + { + return f065; + } + + public void setF065(List f065) + { + this.f065 = f065; + } + + public List getF066() + { + return f066; + } + + public void setF066(List f066) + { + this.f066 = f066; + } + + public List getF067() + { + return f067; + } + + public void setF067(List f067) + { + this.f067 = f067; + } + + public List getF068() + { + return f068; + } + + public void setF068(List f068) + { + this.f068 = f068; + } + + public List getF069() + { + return f069; + } + + public void setF069(List f069) + { + this.f069 = f069; + } + + public List getF070() + { + return f070; + } + + public void setF070(List f070) + { + this.f070 = f070; + } + + public List getF071() + { + return f071; + } + + public void setF071(List f071) + { + this.f071 = f071; + } + + public List getF072() + { + return f072; + } + + public void setF072(List f072) + { + this.f072 = f072; + } + + public List getF073() + { + return f073; + } + + public void setF073(List f073) + { + this.f073 = f073; + } + + public List getF074() + { + return f074; + } + + public void setF074(List f074) + { + this.f074 = f074; + } + + public List getF075() + { + return f075; + } + + public void setF075(List f075) + { + this.f075 = f075; + } + + public List getF076() + { + return f076; + } + + public void setF076(List f076) + { + this.f076 = f076; + } + + public List getF077() + { + return f077; + } + + public void setF077(List f077) + { + this.f077 = f077; + } + + public List getF078() + { + return f078; + } + + public void setF078(List f078) + { + this.f078 = f078; + } + + public List getF079() + { + return f079; + } + + public void setF079(List f079) + { + this.f079 = f079; + } + + public List getF080() + { + return f080; + } + + public void setF080(List f080) + { + this.f080 = f080; + } + + public List getF081() + { + return f081; + } + + public void setF081(List f081) + { + this.f081 = f081; + } + + public List getF082() + { + return f082; + } + + public void setF082(List f082) + { + this.f082 = f082; + } + + public List getF083() + { + return f083; + } + + public void setF083(List f083) + { + this.f083 = f083; + } + + public List getF084() + { + return f084; + } + + public void setF084(List f084) + { + this.f084 = f084; + } + + public List getF085() + { + return f085; + } + + public void setF085(List f085) + { + this.f085 = f085; + } + + public List getF086() + { + return f086; + } + + public void setF086(List f086) + { + this.f086 = f086; + } + + public List getF087() + { + return f087; + } + + public void setF087(List f087) + { + this.f087 = f087; + } + + public List getF088() + { + return f088; + } + + public void setF088(List f088) + { + this.f088 = f088; + } + + public List getF089() + { + return f089; + } + + public void setF089(List f089) + { + this.f089 = f089; + } + + public List getF090() + { + return f090; + } + + public void setF090(List f090) + { + this.f090 = f090; + } + + public List getF091() + { + return f091; + } + + public void setF091(List f091) + { + this.f091 = f091; + } + + public List getF092() + { + return f092; + } + + public void setF092(List f092) + { + this.f092 = f092; + } + + public List getF093() + { + return f093; + } + + public void setF093(List f093) + { + this.f093 = f093; + } + + public List getF094() + { + return f094; + } + + public void setF094(List f094) + { + this.f094 = f094; + } + + public List getF095() + { + return f095; + } + + public void setF095(List f095) + { + this.f095 = f095; + } + + public List getF096() + { + return f096; + } + + public void setF096(List f096) + { + this.f096 = f096; + } + + public List getF097() + { + return f097; + } + + public void setF097(List f097) + { + this.f097 = f097; + } + + public List getF098() + { + return f098; + } + + public void setF098(List f098) + { + this.f098 = f098; + } + + public List getF099() + { + return f099; + } + + public void setF099(List f099) + { + this.f099 = f099; + } + + public List getF100() + { + return f100; + } + + public void setF100(List f100) + { + this.f100 = f100; + } + + public List getF101() + { + return f101; + } + + public void setF101(List f101) + { + this.f101 = f101; + } + + public List getF102() + { + return f102; + } + + public void setF102(List f102) + { + this.f102 = f102; + } + + public List getF103() + { + return f103; + } + + public void setF103(List f103) + { + this.f103 = f103; + } + + public List getF104() + { + return f104; + } + + public void setF104(List f104) + { + this.f104 = f104; + } + + public List getF105() + { + return f105; + } + + public void setF105(List f105) + { + this.f105 = f105; + } + + public List getF106() + { + return f106; + } + + public void setF106(List f106) + { + this.f106 = f106; + } + + public List getF107() + { + return f107; + } + + public void setF107(List f107) + { + this.f107 = f107; + } + + public List getF108() + { + return f108; + } + + public void setF108(List f108) + { + this.f108 = f108; + } + + public List getF109() + { + return f109; + } + + public void setF109(List f109) + { + this.f109 = f109; + } + + public List getF110() + { + return f110; + } + + public void setF110(List f110) + { + this.f110 = f110; + } + + public List getF111() + { + return f111; + } + + public void setF111(List f111) + { + this.f111 = f111; + } + + public List getF112() + { + return f112; + } + + public void setF112(List f112) + { + this.f112 = f112; + } + + public List getF113() + { + return f113; + } + + public void setF113(List f113) + { + this.f113 = f113; + } + + public List getF114() + { + return f114; + } + + public void setF114(List f114) + { + this.f114 = f114; + } + + public List getF115() + { + return f115; + } + + public void setF115(List f115) + { + this.f115 = f115; + } + + public List getF116() + { + return f116; + } + + public void setF116(List f116) + { + this.f116 = f116; + } + + public List getF117() + { + return f117; + } + + public void setF117(List f117) + { + this.f117 = f117; + } + + public List getF118() + { + return f118; + } + + public void setF118(List f118) + { + this.f118 = f118; + } + + public List getF119() + { + return f119; + } + + public void setF119(List f119) + { + this.f119 = f119; + } + + public List getF120() + { + return f120; + } + + public void setF120(List f120) + { + this.f120 = f120; + } + + public List getF121() + { + return f121; + } + + public void setF121(List f121) + { + this.f121 = f121; + } + + public List getF122() + { + return f122; + } + + public void setF122(List f122) + { + this.f122 = f122; + } + + public List getF123() + { + return f123; + } + + public void setF123(List f123) + { + this.f123 = f123; + } + + public List getF124() + { + return f124; + } + + public void setF124(List f124) + { + this.f124 = f124; + } + + public List getF125() + { + return f125; + } + + public void setF125(List f125) + { + this.f125 = f125; + } + + public List getF126() + { + return f126; + } + + public void setF126(List f126) + { + this.f126 = f126; + } + + public List getF127() + { + return f127; + } + + public void setF127(List f127) + { + this.f127 = f127; + } + + public List getF128() + { + return f128; + } + + public void setF128(List f128) + { + this.f128 = f128; + } + + public List getF129() + { + return f129; + } + + public void setF129(List f129) + { + this.f129 = f129; + } + + public List getF130() + { + return f130; + } + + public void setF130(List f130) + { + this.f130 = f130; + } + + public List getF131() + { + return f131; + } + + public void setF131(List f131) + { + this.f131 = f131; + } + + public List getF132() + { + return f132; + } + + public void setF132(List f132) + { + this.f132 = f132; + } + + public List getF133() + { + return f133; + } + + public void setF133(List f133) + { + this.f133 = f133; + } + + public List getF134() + { + return f134; + } + + public void setF134(List f134) + { + this.f134 = f134; + } + + public List getF135() + { + return f135; + } + + public void setF135(List f135) + { + this.f135 = f135; + } + + public List getF136() + { + return f136; + } + + public void setF136(List f136) + { + this.f136 = f136; + } + + public List getF137() + { + return f137; + } + + public void setF137(List f137) + { + this.f137 = f137; + } + + public List getF138() + { + return f138; + } + + public void setF138(List f138) + { + this.f138 = f138; + } + + public List getF139() + { + return f139; + } + + public void setF139(List f139) + { + this.f139 = f139; + } + + public List getF140() + { + return f140; + } + + public void setF140(List f140) + { + this.f140 = f140; + } + + public List getF141() + { + return f141; + } + + public void setF141(List f141) + { + this.f141 = f141; + } + + public List getF142() + { + return f142; + } + + public void setF142(List f142) + { + this.f142 = f142; + } + + public List getF143() + { + return f143; + } + + public void setF143(List f143) + { + this.f143 = f143; + } + + public List getF144() + { + return f144; + } + + public void setF144(List f144) + { + this.f144 = f144; + } + + public List getF145() + { + return f145; + } + + public void setF145(List f145) + { + this.f145 = f145; + } + + public List getF146() + { + return f146; + } + + public void setF146(List f146) + { + this.f146 = f146; + } + + public List getF147() + { + return f147; + } + + public void setF147(List f147) + { + this.f147 = f147; + } + + public List getF148() + { + return f148; + } + + public void setF148(List f148) + { + this.f148 = f148; + } + + public List getF149() + { + return f149; + } + + public void setF149(List f149) + { + this.f149 = f149; + } + + public List getF150() + { + return f150; + } + + public void setF150(List f150) + { + this.f150 = f150; + } + + public List getF151() + { + return f151; + } + + public void setF151(List f151) + { + this.f151 = f151; + } + + public List getF152() + { + return f152; + } + + public void setF152(List f152) + { + this.f152 = f152; + } + + public List getF153() + { + return f153; + } + + public void setF153(List f153) + { + this.f153 = f153; + } + + public List getF154() + { + return f154; + } + + public void setF154(List f154) + { + this.f154 = f154; + } + + public List getF155() + { + return f155; + } + + public void setF155(List f155) + { + this.f155 = f155; + } + + public List getF156() + { + return f156; + } + + public void setF156(List f156) + { + this.f156 = f156; + } + + public List getF157() + { + return f157; + } + + public void setF157(List f157) + { + this.f157 = f157; + } + + public List getF158() + { + return f158; + } + + public void setF158(List f158) + { + this.f158 = f158; + } + + public List getF159() + { + return f159; + } + + public void setF159(List f159) + { + this.f159 = f159; + } + + public List getF160() + { + return f160; + } + + public void setF160(List f160) + { + this.f160 = f160; + } + + public List getF161() + { + return f161; + } + + public void setF161(List f161) + { + this.f161 = f161; + } + + public List getF162() + { + return f162; + } + + public void setF162(List f162) + { + this.f162 = f162; + } + + public List getF163() + { + return f163; + } + + public void setF163(List f163) + { + this.f163 = f163; + } + + public List getF164() + { + return f164; + } + + public void setF164(List f164) + { + this.f164 = f164; + } + + public List getF165() + { + return f165; + } + + public void setF165(List f165) + { + this.f165 = f165; + } + + public List getF166() + { + return f166; + } + + public void setF166(List f166) + { + this.f166 = f166; + } + + public List getF167() + { + return f167; + } + + public void setF167(List f167) + { + this.f167 = f167; + } + + public List getF168() + { + return f168; + } + + public void setF168(List f168) + { + this.f168 = f168; + } + + public List getF169() + { + return f169; + } + + public void setF169(List f169) + { + this.f169 = f169; + } + + public List getF170() + { + return f170; + } + + public void setF170(List f170) + { + this.f170 = f170; + } + + public List getF171() + { + return f171; + } + + public void setF171(List f171) + { + this.f171 = f171; + } + + public List getF172() + { + return f172; + } + + public void setF172(List f172) + { + this.f172 = f172; + } + + public List getF173() + { + return f173; + } + + public void setF173(List f173) + { + this.f173 = f173; + } + + public List getF174() + { + return f174; + } + + public void setF174(List f174) + { + this.f174 = f174; + } + + public List getF175() + { + return f175; + } + + public void setF175(List f175) + { + this.f175 = f175; + } + + public List getF176() + { + return f176; + } + + public void setF176(List f176) + { + this.f176 = f176; + } + + public List getF177() + { + return f177; + } + + public void setF177(List f177) + { + this.f177 = f177; + } + + public List getF178() + { + return f178; + } + + public void setF178(List f178) + { + this.f178 = f178; + } + + public List getF179() + { + return f179; + } + + public void setF179(List f179) + { + this.f179 = f179; + } + + public List getF180() + { + return f180; + } + + public void setF180(List f180) + { + this.f180 = f180; + } + + public List getF181() + { + return f181; + } + + public void setF181(List f181) + { + this.f181 = f181; + } + + public List getF182() + { + return f182; + } + + public void setF182(List f182) + { + this.f182 = f182; + } + + public List getF183() + { + return f183; + } + + public void setF183(List f183) + { + this.f183 = f183; + } + + public List getF184() + { + return f184; + } + + public void setF184(List f184) + { + this.f184 = f184; + } + + public List getF185() + { + return f185; + } + + public void setF185(List f185) + { + this.f185 = f185; + } + + public List getF186() + { + return f186; + } + + public void setF186(List f186) + { + this.f186 = f186; + } + + public List getF187() + { + return f187; + } + + public void setF187(List f187) + { + this.f187 = f187; + } + + public List getF188() + { + return f188; + } + + public void setF188(List f188) + { + this.f188 = f188; + } + + public List getF189() + { + return f189; + } + + public void setF189(List f189) + { + this.f189 = f189; + } + + public List getF190() + { + return f190; + } + + public void setF190(List f190) + { + this.f190 = f190; + } + + public List getF191() + { + return f191; + } + + public void setF191(List f191) + { + this.f191 = f191; + } + + public List getF192() + { + return f192; + } + + public void setF192(List f192) + { + this.f192 = f192; + } + + public List getF193() + { + return f193; + } + + public void setF193(List f193) + { + this.f193 = f193; + } + + public List getF194() + { + return f194; + } + + public void setF194(List f194) + { + this.f194 = f194; + } + + public List getF195() + { + return f195; + } + + public void setF195(List f195) + { + this.f195 = f195; + } + + public List getF196() + { + return f196; + } + + public void setF196(List f196) + { + this.f196 = f196; + } + + public List getF197() + { + return f197; + } + + public void setF197(List f197) + { + this.f197 = f197; + } + + public List getF198() + { + return f198; + } + + public void setF198(List f198) + { + this.f198 = f198; + } + + public List getF199() + { + return f199; + } + + public void setF199(List f199) + { + this.f199 = f199; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2784.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2784.java new file mode 100644 index 0000000000..caa4db40c5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2784.java @@ -0,0 +1,128 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.util.Date; + +public class Issue2784 extends TestCase { + public void test_for_issue() throws Exception { + Model m = new Model(); + m.time = java.time.LocalDateTime.now(); + String str = JSON.toJSONString(m); + assertEquals("{\"time\":" + + m.time.atZone(JSON.defaultTimeZone.toZoneId()).toInstant().toEpochMilli() + + "}", str); + + Model m1 = JSON.parseObject(str, Model.class); + assertEquals(m.time, m1.time); + } + + public void test_for_issue_1() throws Exception { + Model m = new Model(); + m.ztime = ZonedDateTime.now(); + String str = JSON.toJSONString(m); + assertEquals("{\"ztime\":" + + m.ztime.toInstant().toEpochMilli() + + "}", str); + + Model m1 = JSON.parseObject(str, Model.class); + assertEquals(m.ztime.toInstant().toEpochMilli(), m1.ztime.toInstant().toEpochMilli()); + } + + public void test_for_issue_2() throws Exception { + Model m = new Model(); + m.time1 = java.time.LocalDateTime.now(); + String str = JSON.toJSONString(m); + assertEquals("{\"time1\":" + + m.time1.atZone(JSON.defaultTimeZone.toZoneId()).toEpochSecond() + + "}", str); + + Model m1 = JSON.parseObject(str, Model.class); + assertEquals(m.time1.atZone(JSON.defaultTimeZone.toZoneId()).toEpochSecond() + , m1.time1.atZone(JSON.defaultTimeZone.toZoneId()).toEpochSecond()); + } + + public void test_for_issue_3() throws Exception { + Model m = new Model(); + m.ztime1 = ZonedDateTime.now(); + String str = JSON.toJSONString(m); + assertEquals("{\"ztime1\":" + + m.ztime1.toEpochSecond() + + "}", str); + + Model m1 = JSON.parseObject(str, Model.class); + assertEquals(m.ztime1.toEpochSecond() + , m1.ztime1.toEpochSecond()); + } + + public void test_for_issue_4() throws Exception { + Model m = new Model(); + m.date = new Date(); + String str = JSON.toJSONString(m); + assertEquals("{\"date\":" + + m.date.getTime() + + "}", str); + + Model m1 = JSON.parseObject(str, Model.class); + assertEquals(m.date.getTime() + , m1.date.getTime()); + } + + public void test_for_issue_5() throws Exception { + Model m = new Model(); + m.date1 = new Date(); + String str = JSON.toJSONString(m); + assertEquals("{\"date1\":" + + (m.date1.getTime() / 1000) + + "}", str); + + Model m1 = JSON.parseObject(str, Model.class); + assertEquals(m.date1.getTime() / 1000 + , m1.date1.getTime() / 1000); + } + + public void test_for_issue_6() throws Exception { + Model m = new Model(); + m.date1 = new Date(); + String str = JSON.toJSONString(m); + assertEquals("{\"date1\":" + + (m.date1.getTime() / 1000) + + "}", str); + + Model m1 = JSON.parseObject(str, Model.class); + assertEquals(m.date1.getTime() / 1000 + , m1.date1.getTime() / 1000); + } + + public void test_for_issue_7() throws Exception { + Model m = JSON.parseObject("{\"time2\":20190714121314}", Model.class); + assertEquals(m.time2, LocalDateTime.of(2019, 7, 14, 12, 13, 14)); + } + + public static class Model { + @JSONField(format = "millis") + public LocalDateTime time; + + @JSONField(format = "millis") + public ZonedDateTime ztime; + + @JSONField(format = "unixtime") + public LocalDateTime time1; + + @JSONField(format = "unixtime") + public ZonedDateTime ztime1; + + @JSONField(format = "millis") + public Date date; + + @JSONField(format = "unixtime") + public Date date1; + + @JSONField(format = "yyyyMMddHHmmss") + public LocalDateTime time2; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2787.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2787.java new file mode 100644 index 0000000000..3b2b2e995f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2787.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue2787 extends TestCase { + public void test_for_issue() throws Exception { + Model m = new Model(); + String str = JSON.toJSONString(m, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty); + assertEquals("{\"value\":[]}", str); + } + + public static class Model { + public int[] value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2791.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2791.java new file mode 100644 index 0000000000..0ea3b4f01b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2791.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue2791 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"dependencies\":[{\"values\":[{\"name\":\"Demo\"}]}]}"); + JSONPath.remove(jsonObject, "$.dependencies.values[?(@.name=='Demo')]"); + assertEquals("{\"dependencies\":[{\"values\":[]}]}", jsonObject.toString()); + } + + public void test_for_issue1() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"dependencies\":[{\"values\":{\"name\":\"Demo\"}}]}"); + JSONPath.remove(jsonObject, "$.dependencies.values[?(@.name=='Demo')]"); + assertEquals("{\"dependencies\":[]}", jsonObject.toString()); + } + + public void test_for_issue2() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"values\":[{\"name\":\"Demo\"}]}"); + JSONPath.remove(jsonObject, "$.values[?(@.name=='Demo')]"); + assertEquals("{\"values\":[]}", jsonObject.toString()); + } + + + public void test_for_issue3() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"values\":{\"name\":\"Demo\"}}"); + assertTrue(JSONPath.remove(jsonObject, "$.values[?(@.name=='Demo')]")); + assertEquals("{}", jsonObject.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2792.java b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2792.java new file mode 100644 index 0000000000..9619ef33ef --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2700/Issue2792.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_2700; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue2792 extends TestCase { + public void test_for_issue() throws Exception { + String jsonpath = "$.sku[?((@.quantity != 0)&&(@.is_onsale == 1))].sku_id"; + + JSONObject root = JSON.parseObject("{\"sku\":{\"quantity\":12,\"is_onsale\":1,\"sku_id\":42356}}"); + + assertEquals(42356, JSONPath.eval(root, jsonpath)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2830.java b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2830.java new file mode 100644 index 0000000000..0c2f01ac84 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2830.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_2800; + +import com.alibaba.fastjson.JSONObject; + +import junit.framework.TestCase; + +public class Issue2830 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject jsonObject = JSONObject.parseObject("{\"qty\":\"10\",\"qty1\":\"10.0\",\"qty2\":\"10.000\"}"); + + assertEquals(10, jsonObject.getIntValue("qty")); + assertEquals(10, jsonObject.getIntValue("qty1")); + assertEquals(10, jsonObject.getIntValue("qty2")); + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2866.java b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2866.java new file mode 100644 index 0000000000..6b3074a1a7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2866.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.issue_2800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue2866 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\"A1\":1,\"A2\":2,\"A3\":3}"; + + A a = JSON.parseObject(json, A.class, Feature.SupportNonPublicField); + + assertEquals(1, a.a1); + assertEquals(2, a.A2); + assertEquals(3, a.a3); + + } + + static class A{ + @JSONField(name="A1") + int a1; + int A2; + @JSONField(name="A3") + public int a3; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2894.java b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2894.java new file mode 100644 index 0000000000..96f63a0564 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2894.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.issue_2800; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import lombok.Data; + +import java.sql.Timestamp; +import java.util.Locale; +import java.util.TimeZone; + +public class Issue2894 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getDefault(); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + String json = "{\"timestamp\":\"2019-09-19 08:49:52.350000000\"}"; + Pojo pojo = JSONObject.parseObject(json, Pojo.class); + int nanos = pojo.timestamp.getNanos(); + assertEquals(nanos, 350000000); + assertEquals("{\"timestamp\":\"2019-09-19 08:49:52.000000350\"}", JSON.toJSONString(pojo)); + } + + public static class Pojo { + @JSONField(name = "timestamp", format = "yyyy-MM-dd HH:mm:ss.SSSSSSSSS") + public Timestamp timestamp; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2903.java b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2903.java new file mode 100644 index 0000000000..4ebb00dbaf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2800/Issue2903.java @@ -0,0 +1,103 @@ +package com.alibaba.json.bvt.issue_2800; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue2903 extends TestCase { + + public void test_1() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO dto = JSON.parseObject(date1, LoginRequestDTO.class); + LoginRequestDTO dto2 = JSON.parseObject(date2, LoginRequestDTO.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public void test_2() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO2 dto = JSON.parseObject(date1, LoginRequestDTO2.class); + LoginRequestDTO2 dto2 = JSON.parseObject(date2, LoginRequestDTO2.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public void test_3() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO3 dto = JSON.parseObject(date1, LoginRequestDTO3.class); + LoginRequestDTO3 dto2 = JSON.parseObject(date2, LoginRequestDTO3.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public void test_4() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO4 dto = JSON.parseObject(date1, LoginRequestDTO4.class); + LoginRequestDTO4 dto2 = JSON.parseObject(date2, LoginRequestDTO4.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public void test_5() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO5 dto = JSON.parseObject(date1, LoginRequestDTO5.class); + LoginRequestDTO5 dto2 = JSON.parseObject(date2, LoginRequestDTO5.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public void test_6() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO6 dto = JSON.parseObject(date1, LoginRequestDTO6.class); + LoginRequestDTO6 dto2 = JSON.parseObject(date2, LoginRequestDTO6.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public void test_7() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO7 dto = JSON.parseObject(date1, LoginRequestDTO7.class); + LoginRequestDTO7 dto2 = JSON.parseObject(date2, LoginRequestDTO7.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public void test_8() { + String date1 = "{createTime:\"1570636800000\"}"; + String date2 = "{createTime:1570636800000}"; + LoginRequestDTO8 dto = JSON.parseObject(date1, LoginRequestDTO8.class); + LoginRequestDTO8 dto2 = JSON.parseObject(date2, LoginRequestDTO8.class); + assertEquals(dto.createTime, dto2.createTime); + } + + public static class LoginRequestDTO { + public java.time.LocalDateTime createTime; + } + + public static class LoginRequestDTO2 { + public java.time.LocalDate createTime; + } + + public static class LoginRequestDTO3 { + public java.time.LocalTime createTime; + } + + public static class LoginRequestDTO4 { + public java.time.ZonedDateTime createTime; + } + + public static class LoginRequestDTO5 { + public org.joda.time.LocalDateTime createTime; + } + + public static class LoginRequestDTO6 { + public org.joda.time.LocalDate createTime; + } + + public static class LoginRequestDTO7 { + public org.joda.time.Instant createTime; + } + + public static class LoginRequestDTO8 { + public java.time.Instant createTime; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2914.java b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2914.java new file mode 100644 index 0000000000..b5093ce9ce --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2914.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt.issue_2900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +import junit.framework.TestCase; + +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; + +public class Issue2914 extends TestCase { + public void test_for_issue() throws Exception { + + ComplexInt complexInt = new ComplexInt(); + + Queue blockQueueInt = new ArrayBlockingQueue(5); + blockQueueInt.offer(1); + blockQueueInt.offer(2); + blockQueueInt.offer(3); + complexInt.setBlockQueue(blockQueueInt); + + String jsonInt = JSON.toJSONString(complexInt); + + assertEquals("{\"blockQueue\":[1,2,3]}",jsonInt); + + ComplexInt complexInt1 = JSON.parseObject(jsonInt,Issue2914.ComplexInt.class); + + assertEquals(3, complexInt1.getBlockQueue().size()); + + + Complex complex = new Complex(); + + Queue blockQueue = new ArrayBlockingQueue(5); + blockQueue.offer("BlockQueue 1"); + blockQueue.offer("BlockQueue 2"); + blockQueue.offer("BlockQueue 3"); + complex.setBlockQueue(blockQueue); + + String json = JSON.toJSONString(complex); + + assertEquals("{\"blockQueue\":[\"BlockQueue 1\",\"BlockQueue 2\",\"BlockQueue 3\"]}",json); + + Complex complex1 = JSON.parseObject(json,Issue2914.Complex.class); + + assertEquals(3, complex1.getBlockQueue().size()); + + } + + + + + public static class Complex { + + private Queue blockQueue; + + public Queue getBlockQueue() { + return blockQueue; + } + + public void setBlockQueue(Queue blockQueue) { + this.blockQueue = blockQueue; + } + } + + public static class ComplexInt { + + private Queue blockQueue; + + public Queue getBlockQueue() { + return blockQueue; + } + + public void setBlockQueue(Queue blockQueue) { + this.blockQueue = blockQueue; + } + } + + + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2939.java b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2939.java new file mode 100644 index 0000000000..dd958c0094 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2939.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.issue_2900; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; + +public class Issue2939 extends TestCase { + public void test_for_issue() throws Exception { + + LinkedMultiValueMap multiValueMap = new LinkedMultiValueMap(); + multiValueMap.add("k1","k11"); + multiValueMap.add("k1","k12"); + multiValueMap.add("k1","k13"); + multiValueMap.add("k2","k21"); + + + String json = JSON.toJSONString(multiValueMap); + assertEquals("{\"k1\":[\"k11\",\"k12\",\"k13\"],\"k2\":[\"k21\"]}", json); + + + Object obj = JSON.parseObject(json, LinkedMultiValueMap.class); + assertTrue(obj != null); + + LinkedMultiValueMap map = (LinkedMultiValueMap) obj; + assertSame(3, map.get("k1").size()); + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2952.java b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2952.java new file mode 100644 index 0000000000..080bda39b2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2952.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.issue_2900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import junit.framework.TestCase; + +public class Issue2952 extends TestCase { + public void test_for_issue() throws Exception { + String expected = "{\"l\":null,\"s\":null,\"b\":null,\"i\":null,\"o\":null}"; + SerializerFeature[] serializerFeatures = { + SerializerFeature.WriteNullListAsEmpty, + SerializerFeature.WriteNullStringAsEmpty, + SerializerFeature.WriteNullBooleanAsFalse, + SerializerFeature.WriteNullNumberAsZero + }; + SerializeConfig asmConfig = new SerializeConfig(); + asmConfig.setAsmEnable(true); + assertEquals(expected, JSON.toJSONString(new Pojo(), asmConfig, serializerFeatures)); + assertEquals(expected, JSON.toJSONString(new Pojo2(), asmConfig, serializerFeatures)); + SerializeConfig noasmConfig = new SerializeConfig(); + noasmConfig.setAsmEnable(false); + assertEquals(expected, JSON.toJSONString(new Pojo(), noasmConfig, serializerFeatures)); + assertEquals(expected, JSON.toJSONString(new Pojo2(), noasmConfig, serializerFeatures)); + } + + public static class Pojo { + @JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue, ordinal=0) + public Object[] l; + @JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue, ordinal=1) + public String s; + @JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue, ordinal=2) + public Boolean b; + @JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue, ordinal=3) + public Integer i; + @JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue, ordinal=4) + public Object o; + } + + @JSONType(serialzeFeatures=SerializerFeature.WriteMapNullValue) + public static class Pojo2 { + @JSONField(ordinal=0) + public Object[] l; + @JSONField(ordinal=1) + public String s; + @JSONField(ordinal=2) + public Boolean b; + @JSONField(ordinal=3) + public Integer i; + @JSONField(ordinal=4) + public Object o; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2962.java b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2962.java new file mode 100644 index 0000000000..654b860e2f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2962.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.issue_2900; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import junit.framework.TestCase; + +public class Issue2962 extends TestCase { + private TimeZone original = TimeZone.getDefault(); + + @Override + public void tearDown () { + TimeZone.setDefault(original); + JSON.defaultTimeZone = original; + } + + public void test_dates_different_timeZones() { + for (String id : TimeZone.getAvailableIDs()) { + TimeZone timeZone = TimeZone.getTimeZone(id); + TimeZone.setDefault(timeZone); + JSON.defaultTimeZone = timeZone; + + Calendar cal = Calendar.getInstance(); + Date now = cal.getTime(); + + VO vo = new VO(); + vo.date = now; + + String json = JSON.toJSONString(vo); + VO result = JSON.parseObject(json, VO.class); + assertEquals(vo.date, result.date); + + // with iso-format + json = JSON.toJSONString(vo, SerializerFeature.UseISO8601DateFormat); + System.out.println(id + " " + json); + result = JSON.parseObject(json, VO.class); + assertEquals(JSON.toJSONString(vo.date), JSON.toJSONString(result.date)); + } + } + + public static class VO { + public Date date; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2982.java b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2982.java new file mode 100644 index 0000000000..469444c752 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_2900/Issue2982.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_2900; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; +import org.junit.Test; + +public class Issue2982 extends TestCase { + + + @Test + public void test_for_issue() { + String jsonStr = "[ { \"activity_type\" : 0, \"activity_id\" : \"***\", \"activity_tip\" : \"***\", \"position\" : \"1\" }, { \"activity_type\" : 0, \"activity_id\" : \"2669\", \"activity_tip\" : \"****\", \"position\" : \"1\" }]"; + assertTrue(JSONArray.isValidArray(jsonStr)); + assertTrue(JSON.isValidArray(jsonStr)); + assertTrue(JSONObject.isValidArray(jsonStr)); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3031.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3031.java new file mode 100644 index 0000000000..005f21e64c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3031.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue3031 extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"success\":true,\"message\":null,\"data\":[{\"tblId\":78,\"partId\":104,\"values\":[\"p001\",\"q001\"],\"dbName\":\"db001\",\"tableName\":\"tbl001\",\"createTime\":1582293531,\"lastAccessTime\":1,\"sd\":{\"sdId\":182,\"cdId\":181,\"cols\":[{\"name\":\"col1\",\"type\":\"string\",\"comment\":null},{\"name\":\"col2\",\"type\":\"int\",\"comment\":\"col2\"},{\"name\":\"col3\",\"type\":\"boolean\",\"comment\":null}],\"location\":\"oss://temp/jianghu/db001/tbl001\",\"inputFormat\":\"org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat\",\"outputFormat\":\"org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat\",\"compressed\":true,\"numBuckets\":2,\"serdeInfo\":{\"serdeId\":182,\"name\":null,\"serializationLib\":\"org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe\",\"parameters\":{\"field.delim\":\"\\t\",\"serialization.format\":\"\\t\"}},\"bucketCols\":[\"col1\"],\"sortCols\":[{\"col\":\"col1\",\"order\":0}],\"parameters\":{},\"skewedInfo\":{\"skewedColNames\":[\"col1\",\"col3\"],\"skewedColValues\":[[\"2\",\"1\"],[\"3\",\"2\"]],\"skewedColValueLocationMaps\":{}},\"storedAsSubDirectories\":false},\"parameters\":{\"totalSize\":\"0\",\"numRows\":\"-1\",\"rawDataSize\":\"-1\",\"COLUMN_STATS_ACCURATE\":\"false\",\"numFiles\":\"0\",\"transient_lastDdlTime\":\"1582293531\"},\"parametersSize\":6},{\"tblId\":78,\"partId\":105,\"values\":[\"p001\",\"q002\"],\"dbName\":\"db001\",\"tableName\":\"tbl001\",\"createTime\":1582293531,\"lastAccessTime\":1,\"sd\":{\"sdId\":183,\"cdId\":181,\"cols\":[{\"name\":\"col1\",\"type\":\"string\",\"comment\":null},{\"name\":\"col2\",\"type\":\"int\",\"comment\":\"col2\"},{\"name\":\"col3\",\"type\":\"boolean\",\"comment\":null}],\"location\":\"oss://temp/jianghu/db001/tbl001\",\"inputFormat\":\"org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat\",\"outputFormat\":\"org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat\",\"compressed\":true,\"numBuckets\":2,\"serdeInfo\":{\"serdeId\":183,\"name\":null,\"serializationLib\":\"org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe\",\"parameters\":{\"field.delim\":\"\\t\",\"serialization.format\":\"\\t\"}},\"bucketCols\":[\"col1\"],\"sortCols\":[{\"col\":\"col1\",\"order\":0}],\"parameters\":{},\"skewedInfo\":{\"skewedColNames\":[\"col1\",\"col3\"],\"skewedColValues\":[[\"2\",\"1\"],[\"3\",\"2\"]],\"skewedColValueLocationMaps\":{}},\"storedAsSubDirectories\":false},\"parameters\":{\"totalSize\":\"0\",\"numRows\":\"-1\",\"rawDataSize\":\"-1\",\"COLUMN_STATS_ACCURATE\":\"false\",\"numFiles\":\"0\",\"transient_lastDdlTime\":\"1582293531\",\"$ref\":\"$[0].parameters\"},\"parametersSize\":7},{\"tblId\":78,\"partId\":106,\"values\":[\"p002\",\"q002\"],\"dbName\":\"db001\",\"tableName\":\"tbl001\",\"createTime\":1582293531,\"lastAccessTime\":1,\"sd\":{\"sdId\":184,\"cdId\":181,\"cols\":[{\"name\":\"col1\",\"type\":\"string\",\"comment\":null},{\"name\":\"col2\",\"type\":\"int\",\"comment\":\"col2\"},{\"name\":\"col3\",\"type\":\"boolean\",\"comment\":null}],\"location\":\"oss://temp/jianghu/db001/tbl001\",\"inputFormat\":\"org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat\",\"outputFormat\":\"org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat\",\"compressed\":true,\"numBuckets\":2,\"serdeInfo\":{\"serdeId\":184,\"name\":null,\"serializationLib\":\"org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe\",\"parameters\":{\"field.delim\":\"\\t\",\"serialization.format\":\"\\t\"}},\"bucketCols\":[\"col1\"],\"sortCols\":[{\"col\":\"col1\",\"order\":0}],\"parameters\":{},\"skewedInfo\":{\"skewedColNames\":[\"col1\",\"col3\"],\"skewedColValues\":[[\"2\",\"1\"],[\"3\",\"2\"]],\"skewedColValueLocationMaps\":{}},\"storedAsSubDirectories\":false},\"parameters\":{\"totalSize\":\"0\",\"numRows\":\"-1\",\"rawDataSize\":\"-1\",\"COLUMN_STATS_ACCURATE\":\"false\",\"numFiles\":\"0\",\"transient_lastDdlTime\":\"1582293531\",\"$ref\":\"$[0].parameters\"},\"parametersSize\":7}]}"; + System.out.println(str); + ResultData obj = JSON.parseObject(str, ResultData.class); + } + + public static class ResultData + { + private boolean success; + private String message; + private Object data; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3049.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3049.java new file mode 100644 index 0000000000..399a68e59a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3049.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue3049 extends TestCase { + public void test_for_issue() throws Exception { + String json1 = "{\"date\":\"2019-11-1 21:45:12\"}"; + MyObject myObject1 = JSON.parseObject(json1, MyObject.class); + String str2 = JSON.toJSONStringWithDateFormat(myObject1, "yyyy-MM-dd HH:mm:ss"); + assertEquals("{\"date\":\"2019-11-01 21:45:12\"}", str2); + } + + public static class MyObject { + public java.util.Date date; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3057.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3057.java new file mode 100644 index 0000000000..72204e5fec --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3057.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue3057 extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"q\":[]}"; + Bean bean = JSON.parseObject(str, Bean.class); + assertEquals(0, bean.q.size()); + } + + public static class Bean { + public java.util.Deque q; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3060.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3060.java new file mode 100644 index 0000000000..17fe077776 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3060.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue3060 extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"type\":1}"; + Bean bean = JSON.parseObject(str).toJavaObject(Bean.class); + Bean bean1 = JSON.parseObject(str, Bean.class); + assertEquals(bean.type, bean1.type); + } + + public static class Bean { + public int type; + } + + public enum Type { + Small, Big + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3065.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3065.java new file mode 100644 index 0000000000..0d56be242b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3065.java @@ -0,0 +1,150 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue3065 extends TestCase { + public void test_for_issue() throws Exception { + String data = "{\n" + + "\t\"code\":\"OK\",\n" + + "\t\"data\":[\n" + + "\t\t{\n" + + "\t\t\t\"createTime\":1584457789,\n" + + "\t\t\t\"dbName\":\"basic_test\",\n" + + "\t\t\t\"lastAccessTime\":0,\n" + + "\t\t\t\"parameters\":{\n" + + "\t\t\t\t\"transient_lastDdlTime\":\"1584457789\"\n" + + "\t\t\t},\n" + + "\t\t\t\"parametersSize\":2,\n" + + "\t\t\t\"partId\":2209,\n" + + "\t\t\t\"sd\":{\n" + + "\t\t\t\t\"bucketCols\":[],\n" + + "\t\t\t\t\"cdId\":2719,\n" + + "\t\t\t\t\"cols\":[\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_nationkey\",\n" + + "\t\t\t\t\t\t\"type\":\"int\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_name\",\n" + + "\t\t\t\t\t\t\"type\":\"string\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_regionkey\",\n" + + "\t\t\t\t\t\t\"type\":\"int\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_comment\",\n" + + "\t\t\t\t\t\t\"type\":\"string\"\n" + + "\t\t\t\t\t}\n" + + "\t\t\t\t],\n" + + "\t\t\t\t\"compressed\":false,\n" + + "\t\t\t\t\"inputFormat\":\"org.apache.hadoop.mapred.TextInputFormat\",\n" + + "\t\t\t\t\"location\":\"oss://hello/world/\",\n" + + "\t\t\t\t\"numBuckets\":0,\n" + + "\t\t\t\t\"outputFormat\":\"org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat\",\n" + + "\t\t\t\t\"parameters\":{},\n" + + "\t\t\t\t\"sdId\":2662,\n" + + "\t\t\t\t\"serDeInfo\":{\n" + + "\t\t\t\t\t\"name\":\"nation_part_hidden\",\n" + + "\t\t\t\t\t\"parameters\":{\n" + + "\t\t\t\t\t\t\"field.delim\":\"|\",\n" + + "\t\t\t\t\t\t\"serialization.format\":\"|\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t\"serdeId\":2720,\n" + + "\t\t\t\t\t\"serializationLib\":\"org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe\"\n" + + "\t\t\t\t},\n" + + "\t\t\t\t\"skewedInfo\":{\n" + + "\t\t\t\t\t\"skewedColNames\":[],\n" + + "\t\t\t\t\t\"skewedColValueLocationMaps\":{},\n" + + "\t\t\t\t\t\"skewedColValues\":[]\n" + + "\t\t\t\t},\n" + + "\t\t\t\t\"sortCols\":[],\n" + + "\t\t\t\t\"storedAsSubDirectories\":false\n" + + "\t\t\t},\n" + + "\t\t\t\"tableName\":\"nation_part_hidden\",\n" + + "\t\t\t\"tblId\":453,\n" + + "\t\t\t\"values\":[\n" + + "\t\t\t\t\"2019\",\n" + + "\t\t\t\t\"01\",\n" + + "\t\t\t\t\"15\"\n" + + "\t\t\t]\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"createTime\":1584457789,\n" + + "\t\t\t\"dbName\":\"basic_test\",\n" + + "\t\t\t\"lastAccessTime\":0,\n" + + "\t\t\t\"parameters\":{\n" + + "\t\t\t\t\"transient_lastDdlTime\":\"1584457789\"\n" + + "\t\t\t},\n" + + "\t\t\t\"parametersSize\":2,\n" + + "\t\t\t\"partId\":2210,\n" + + "\t\t\t\"sd\":{\n" + + "\t\t\t\t\"bucketCols\":[],\n" + + "\t\t\t\t\"cdId\":2719,\n" + + "\t\t\t\t\"cols\":[\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_nationkey\",\n" + + "\t\t\t\t\t\t\"type\":\"int\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_name\",\n" + + "\t\t\t\t\t\t\"type\":\"string\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_regionkey\",\n" + + "\t\t\t\t\t\t\"type\":\"int\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t{\n" + + "\t\t\t\t\t\t\"name\":\"n_comment\",\n" + + "\t\t\t\t\t\t\"type\":\"string\"\n" + + "\t\t\t\t\t}\n" + + "\t\t\t\t],\n" + + "\t\t\t\t\"compressed\":false,\n" + + "\t\t\t\t\"inputFormat\":\"org.apache.hadoop.mapred.TextInputFormat\",\n" + + "\t\t\t\t\"location\":\"oss://hello/world/\",\n" + + "\t\t\t\t\"numBuckets\":0,\n" + + "\t\t\t\t\"outputFormat\":\"org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat\",\n" + + "\t\t\t\t\"parameters\":{\n" + + "\t\t\t\t\t\"$ref\":\"$[0].sd.parameters\"\n" + + "\t\t\t\t},\n" + + "\t\t\t\t\"sdId\":2663,\n" + + "\t\t\t\t\"serDeInfo\":{\n" + + "\t\t\t\t\t\"name\":\"nation_part_hidden\",\n" + + "\t\t\t\t\t\"parameters\":{\n" + + "\t\t\t\t\t\t\"$ref\":\"$[0].sd.serDeInfo.parameters\"\n" + + "\t\t\t\t\t},\n" + + "\t\t\t\t\t\"serdeId\":2721,\n" + + "\t\t\t\t\t\"serializationLib\":\"org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe\"\n" + + "\t\t\t\t},\n" + + "\t\t\t\t\"skewedInfo\":{\n" + + "\t\t\t\t\t\"skewedColNames\":[],\n" + + "\t\t\t\t\t\"skewedColValueLocationMaps\":{},\n" + + "\t\t\t\t\t\"skewedColValues\":[]\n" + + "\t\t\t\t},\n" + + "\t\t\t\t\"sortCols\":[],\n" + + "\t\t\t\t\"storedAsSubDirectories\":false\n" + + "\t\t\t},\n" + + "\t\t\t\"tableName\":\"nation_part_hidden\",\n" + + "\t\t\t\"tblId\":453,\n" + + "\t\t\t\"values\":[\n" + + "\t\t\t\t\"2018\",\n" + + "\t\t\t\t\"12\",\n" + + "\t\t\t\t\"20\"\n" + + "\t\t\t]\n" + + "\t\t}\n" + + "\t],\n" + + "\t\"success\":true\n" + + "}"; + ResultData resultData = JSON.parseObject(data, ResultData.class); + System.out.println(resultData); + } + + public static class ResultData + { + private boolean success; + private String message; + private Object data; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3066.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3066.java new file mode 100644 index 0000000000..1d844bc0d8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3066.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class Issue3066 extends TestCase { + public void test_for_jsonpath() throws Exception { + String str = "{ 'id' : 0, 'items' : [ {'name': 'apple', 'price' : 30 }, {'name': 'pear', 'price' : 40 } ] }"; + JSONObject root = JSON.parseObject(str); + Object max = JSONPath.eval(root, "$.items[*].price.max()"); + assertEquals(40, max); + + Object min = JSONPath.eval(root, "$.items[*].price.min()"); + assertEquals(30, min); + + Object count = JSONPath.eval(root, "$.items[*].price.size()"); + assertEquals(2, count); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3075.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3075.java new file mode 100644 index 0000000000..82fc60453f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3075.java @@ -0,0 +1,448 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue3075 extends TestCase { + public void test_for_issue() throws Exception { + SerializerFeature[] features = { + SerializerFeature.BrowserSecure, + // 消除对同一对象重复引用的优化 + SerializerFeature.DisableCircularReferenceDetect, + // 将中文都会序列化为\Uxxxx 格式 + // 超过 −9007199254740992 到 9007199254740992 区间使用字符串,如:"9007199254740993" + // FIXME: 序列化的时候会导致空指针。 + SerializerFeature.BrowserCompatible, + // 不隐藏为空的字段 + SerializerFeature.IgnoreNonFieldGetter, + // map为Null,置为{} + SerializerFeature.WriteMapNullValue, + // Long、Integer、Short等number类型为Null,置为0 + SerializerFeature.WriteNullNumberAsZero, + // Boolean为Null,置为false + SerializerFeature.WriteNullBooleanAsFalse, + // List为Null,置为[] + SerializerFeature.WriteNullListAsEmpty, + // String为Null,置为"" + SerializerFeature.WriteNullStringAsEmpty + }; + + JSON.toJSONString(new TestBasicBO(), features); + JSON.toJSONString(new TestBO(), features); + } + + @NoArgsConstructor + @Data + public static class TestBasicBO { + String udgxhkk; + String dvbvgtm; + String cegnjlhiz; + String tmztsttazf; + List dszukwrs; + String stymi; + Float uwobf; + Float dcvnlfo; + Float bjlrxreby; + Float sgljt; + Float irqtbtgugfk; + Float usnvv; + Float gfeqybelageu; + Float bccbcqtb; + Float znkdwgblhji; + Float uktxicvsrxui; + Float sujnyvlz; + Integer grihhxsxehct; + Integer vqyqv; + Integer wiipi; + Float sxdihakgyuja; + Integer xpspehqs; + Integer aiysq; + Integer zdzbdg; + Float pzhjnnvzsujn; + Float wdyfoawjsupo; + List rtfskvdd; + String txwrimwo; + List rlsueycznbec; + Integer wiboqxnnyjby; + Integer tpjgzadsl; + Integer ncwzji; + Integer gxslparv; + Integer zcioiclpkc; + Integer esjloj; + Integer jrmzi; + Integer coqxh; + Integer csdylng; + Integer fliuk; + List rbnbk; + String kqclmytapnfm; + Integer dqlndt; + String ciergywnviyc; + Float qffnfbmg; + String hzases; + Integer yfywdwpckn; + String mfhkzjjtac; + String egldba; + Integer dsnkiipg; + String owllvncxwc; + String umcnrocpnk; + Integer pzjnnkxkpu; + String cbepkbipiwy; + String sidtoadm; + Integer gbebsls; + String qdmjhio; + String qwhctpjrqzl; + Integer asqxntoueop; + String diffdush; + Integer bkieoangrm; + List comyayjvkvw; + List ndvjktzzuzzu; + List dmncb; + List aicnh; + List noznm; + List mtovpqvrvt; + List cyoeso; + List xexcw; + List nhtdqd; + List lqrcqrsuobml; + List pbsdnbzzdw; + List yxlqyliyqvrg; + List tmlmaoycqtuw; + Integer ldcirqriayn; + Float yiqgeq; + Float olqnefjnprtz; + Float shkfyrpytfa; + Float tzcmipuj; + Integer fklflsx; + Integer walrdei; + Integer qwqtkuqmsla; + String nzqduoel; + Integer otpza; + String cctxjwhjmyi; + Integer mzsgtnyfk; + String ftskxhjtcb; + Integer gbrujvscq; + String dzxmmw; + Integer rhqdugvayl; + Integer aookder; + String qscvra; + Integer upyubsp; + String shzagw; + Integer tweniwhxvjjn; + Integer tzkuser; + Integer vkbutizlvwvv; + String qzvhgpew; + Integer wwrrphmki; + String xsvhkcmil; + Integer cyseso; + String uaqnzjmxru; + Integer ydmvnvwidrb; + String xppwn; + Integer egamsuczb; + String sdgcotcjilz; + Integer kxjkjlxllhqm; + String ycmkvjnwnxw; + Integer dnzba; + Integer gtxrnyzeeay; + Integer snhxyanxkjd; + String qcbcy; + List ahiatnsb; + String zuetqpbl; + Integer dmalnj; + String rhvkww; + Integer ccipz; + String batjsa; + Integer xilrdu; + String zcddn; + Integer savddhvsw; + String wpfkrmo; + Integer lxwqeglqg; + String pzrsbjwftbn; + String bksteu; + Float uldnytaqnvj; + Float tniiqgfvku; + Float pojntm; + String tfgkvrve; + Float lwtesutqb; + Float owqfxakmzooj; + Float cmmtltk; + Float hekkfyhn; + Float liedzk; + Float yvmiaa; + Float kprftdvaqi; + Float lqookvn; + Float bxpchxhsweq; + Float poqkjonoof; + Float qaioeuzuohn; + Float pifwzgq; + Float cdzuozdqwbgm; + Float lbifqqimiv; + Float pxsgjlv; + Float tttkh; + Float mbufzjclnhx; + Float scxuelvrmxsn; + Float bdptli; + Float xczxonza; + Float ldwssjxb; + Float wiouipwwqjbg; + Float vniafvt; + Float vssktgubhnx; + Float kflyvz; + Integer aknemh; + Integer nidynr; + Integer bpwizpukvh; + Integer crskvy; + String licwnil; + Integer ckanqgwvq; + Integer bxztcjyhgpw; + Integer nplybxzhxtsw; + Integer fqdcmqlq; + Integer crikxhlpbw; + Float ejegbhvhbqkp; + Float rhsvcd; + Float mtbpgsnbkfa; + Float fghdkkdl; + Float lvnmyj; + Integer bgsakgxawgjh; + String nzvgyrodtsr; + String abdrwew; + Float amvfspvwb; + Integer dqvyvmnmj; + Float xowqdimpyxmw; + Integer fkrdbixfma; + Float hhufuxqln; + Float uebyr; + Float syavzsxriebg; + Float zovgafxv; + Float ctdcbxbkwoll; + Float rinfpkytok; + Float gpulotiilxcr; + Float aovpmxvxpfg; + Float zigtcxcepxc; + Float mmavfb; + Float mczfhudqhqa; + Float nfqdpdkbxt; + Float lcjdxon; + Float xcmmtzhwraox; + Float bajzw; + Float fymfzjnu; + Float etkfygf; + Float dqlepesaxea; + Float lwsuvrnsf; + Float vbndsascz; + Float aoxujoci; + Integer jflepnqlqfrc; + String crmxb; + String lfxwl; + Integer aajylvzrzdhf; + String upoymzbopmks; + String wohec; + String eqaqhqbz; + Integer oblaryua; + String ibjqnseq; + String xhwwq; + Integer iyoak; + String mimgsfedn; + String gvoadzr; + List zsicdjrekfe; + String aghymcgm; + List szqwrym; + String nzwpcvb; + List yaqvf; + String oofni; + List gywrntf; + String vpliqryy; + List xghtojazsz; + String rlpvlptk; + Integer egntvt; + String awoqmlx; + Integer zpppbvgi; + String gaioivdrwz; + Integer lqmaz; + List tdblj; + List mmtavpe; + List mzxphtilz; + Integer xohrlfdgjq; + String surbjsnsnz; + String ibcsu; + String limfokbgjgr; + } + + @NoArgsConstructor + @Data + + public static class TestBO extends TestBasicBO{ + + public String mlbkyxy; + public List sqhgpd; + public List nikawljmoafb; + public String rphau; + public Integer iwhjp; + public String pjevuugkw; + public List orpkgtuiz; + public String jsbxdscp; + public String epnrgnejvfm; + public Integer poeihbdfwe; + public List mzzaoocfntzn; + public List lrvkotdxp; + public List udkknpqpey; + public Float uibav; + public Integer owuwykgifldl; + public String cjyxckl; + public String lkfkoddqme; + public Integer dkcggnjzgdzj; + public Float gerjcltp; + public String gcfaiwj; + public Float bmuniiladuu; + public List fsuahyioln; + public Integer knpvvsju; + public Integer bimvkoauvkdm; + public List fnuxllxfcc; + public List udkpqjtlhxy; + public String xtsrpb; + public List pmxbc; + public String rtkvfukhtca; + public Integer vnxnxg; + public Float gipmqit; + public Integer dzufoeglnsl; + public List wahnlujq; + public Float brqaxsksnpqn; + public Float mohysv; + public String jmodsimfpxp; + public Integer ypfimuf; + public List mfdmuwlxe; + public Float zmgqqr; + public List vuofhyfnh; + public Float ybizdwlx; + public String tfqvadbpzanx; + public Float orxtn; + public List kifznybnfvo; + public String pjsdytj; + public Float jobisey; + public List cnzsytgsrmh; + public List rqjdxemd; + public String bfxxethqvyo; + public String wgkkexdy; + public Integer giyeovmj; + public List unhholw; + public List anseshsvz; + public List ribmewsfzwcp; + public List tpwfr; + public List pxjsnytfth; + public List txsbr; + public Integer nrodwidtchl; + public List ocugbk; + public List cirelkacd; + public Integer hpqgpicypp; + public List lftecbun; + public Float ygewofr; + public String tgjcrxk; + public Float csujsjzm; + public String vxsusbwz; + public String rpnafceep; + public List ytwxyenb; + public String auhvjywewmo; + public List bbvsrb; + public List vzuftloqaal; + public List krjwsd; + public String gkihfkuve; + public String jikuil; + public String rhdmpjyccf; + public Integer mhrnx; + public String yobhtwzf; + public List xeyoj; + public Float cojoaar; + public Float bjfkxougmw; + public String geoilga; + public List xllrjzafquyu; + public Float xobveiffhsdo; + public List dknpewwdh; + public String oztdynn; + public Integer vgddb; + public String apiqmm; + public List dwjdwz; + public String wurbwztjp; + public Integer bseiv; + public Float zxlysfuokb; + public String qyfowxe; + public String iipwsfy; + public List owsejqfkehjn; + public List ztzcv; + public List keygodzfjjmr; + public List bfzfijxvwyb; + public List idhvg; + public Float sgzgfoadud; + public String mhzspwrd; + public Float yuldcj; + public String bjwnfb; + public String tlzzjt; + public List tgmul; + public Float pnsryayelzxt; + public Float afmdfca; + public String vxbalqkel; + public String gaqrvygvjili; + public Integer qhvoxqalg; + public String hegjib; + public String hvbxpgeqek; + public List lpkzkgnya; + public List tbtickvxvho; + public String mvbciywiejs; + public String ijcczoqij; + public String vddps; + public List qomzusabz; + public Float xqcsrts; + public Float zqafkvntsh; + public List byygmcw; + public Integer zwysdiaiev; + public Float dstftqztrl; + public List wvybkavzf; + public Integer ujoqlrrgflnf; + public List sbsmqzxj; + public List lkasladbez; + public String ydmgeywpquba; + public String vufcvrt; + public Integer jzhbuueld; + public List nminfrgyts; + public Integer rxtpyhghh; + public List xvncumabdfhq; + public Float ftjrvcptykxx; + public String torraglirgs; + public Integer jomkavscsf; + public String duvhc; + public String czxnlbt; + public List qloaj; + public String wlircmcfea; + public String tpbcqj; + public String otrjwwnsssd; + public String vkofzdftinz; + public Float ftinjqovg; + public String innprvmyj; + public String ynjqvcudywdy; + public Float rpdtnenuwr; + public List xiywwxjjhlc; + public Integer htuwbznbz; + public String kzqkncbcdcu; + public List xzhor; + public String sidrpoy; + public Float ltpmidzjd; + public List lwyuyni; + public List rdsab; + public List kmmoxpxw; + public Float qtcrtcarxhy; + public String nvdqgvebdvxw; + public List brvmir; + public List lhfsw; + public List fobff; + public Float wontvjkp; + public List vrsegwx; + public List mdbyf; + public Float anpevc; + public String krtrsevahzu; + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3082.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3082.java new file mode 100644 index 0000000000..7207c4de7b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3082.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.Map; + +public class Issue3082 extends TestCase { + public void test_for_issue_entry() throws Exception { + String str = "{\"k\":{\"k\":\"v\"}}"; + Map.Entry> entry = JSON.parseObject(str, new TypeReference>>() {}); + assertEquals("v", entry.getValue().getValue()); + } + + public void test_for_issue() throws Exception { + HashSet>> nestedSet = new HashSet>>(); + nestedSet.add(new AbstractMap.SimpleEntry>("a", new AbstractMap.SimpleEntry("b", "c"))); + nestedSet.add(new AbstractMap.SimpleEntry>("d", new AbstractMap.SimpleEntry("e", "f"))); + + String content = JSON.toJSONString(nestedSet); + + HashSet>> deserializedNestedSet; + Type type = new TypeReference>>>() {}.getType(); + deserializedNestedSet = JSON.parseObject(content, type); + assertEquals(nestedSet, deserializedNestedSet); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3083.kt b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3083.kt new file mode 100644 index 0000000000..29d277909f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3083.kt @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.issue_3000 + +import com.alibaba.fastjson.JSON + +class TestBean { + var is_subscribe = 0 + var subscribe = 0 + var isHave = 0 + var _have = 0 + var normal = 0 + var Abnormal = 0 +} + +fun main(args: Array) { + val s = "{'is_subscribe':1,'subscribe':2,'isHave':3, '_have':4, 'normal':5, 'Abnormal':6}" + val b = JSON.parseObject(s, TestBean::class.java) + println("${b.is_subscribe}--${b.subscribe}--${b.isHave}--${b._have}--${b.normal}--${b.Abnormal}") +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3093.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3093.java new file mode 100644 index 0000000000..c269e73120 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3093.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.sql.Timestamp; +import java.util.Calendar; + +public class Issue3093 extends TestCase { + public void test_for_issue() throws Exception { + Timestamp ts = new Timestamp(Calendar.getInstance().getTimeInMillis()); + System.out.println(ts.toString()); + String json = JSON.toJSONString(ts, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3138.java b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3138.java new file mode 100644 index 0000000000..99b15b4987 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3000/Issue3138.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_3000; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.util.Map; + +public class Issue3138 extends TestCase { + public void test_0() throws Exception { + VO vo = JSON.parseObject("{\"value\":{\"@type\":\"aa\"}}", VO.class); + } + + public static class VO { + @JSONField(parseFeatures = Feature.DisableSpecialKeyDetect) + public Map value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3109.java b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3109.java new file mode 100644 index 0000000000..fb127ac6d0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3109.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.issue_3100; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class Issue3109 extends TestCase { + public void test_for_issue() throws Exception { + ParserConfig config = new ParserConfig(); + config.addAccept("test"); + JSON.parseObject("{\"@type\":\"testxx\",\"dogName\":\"dog1001\"}", Dog.class, config); + } + + public static class Dog { + public String dogName; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3131.java b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3131.java new file mode 100644 index 0000000000..7fd675e0ca --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3131.java @@ -0,0 +1,130 @@ +package com.alibaba.json.bvt.issue_3100; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class Issue3131 extends TestCase { + public void test_for_issue() throws Exception { + List orgs = new ArrayList(); + UserOrg org = new UserOrg("111","222" ); + orgs.add(org); + String s = JSON.toJSONString(new Orgs("111", orgs)); + System.out.println(s); + Orgs userOrgs = JSON.parseObject(s, Orgs.class); + System.out.println(JSON.toJSONString(userOrgs)); + } + + public static class Orgs implements Serializable + { + /** + */ + private static final long serialVersionUID = -1L; + + private String name; + + private List orgs; + + public Orgs() { + + } + + public Orgs(String name, List orgs) + { + this.name = name; + this.orgs = orgs; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public List getOrgs() + { + return orgs; + } + + public void setOrgs(List orgs) + { + this.orgs = orgs; + } + + public void add(T org) { + if (orgs == null) { + orgs = new ArrayList(); + } + orgs.add(org); + } + } + + public static class UserOrg extends Org implements Serializable{ + + private String name; + + private String idcard; + + public UserOrg() { + + } + + public UserOrg(String name, String idcard) + { + super (name); + this.name = name; + this.idcard = idcard; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getIdcard() + { + return idcard; + } + + public void setIdcard(String idcard) + { + this.idcard = idcard; + } + } + + public static abstract class Org implements Serializable{ + + private String name; + + public Org() { + + } + + public Org(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3132.java b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3132.java new file mode 100644 index 0000000000..ba00953dad --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3132.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_3100; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.json.bvtVO.一个中文名字的包.User; +import junit.framework.TestCase; + +public class Issue3132 extends TestCase { + + public void test_for_issue() throws Exception { + User user = new User(); + user.setId(9); + user.setName("asdffsf"); + System.out.println(JSONObject.toJSONString(user)); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3150.java b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3150.java new file mode 100644 index 0000000000..f6276a6a92 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3150.java @@ -0,0 +1,75 @@ +package com.alibaba.json.bvt.issue_3100; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.AfterFilter; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +public class Issue3150 extends TestCase { + public void test_for_issue() throws Exception { + MyRefAfterFilter refAfterFilterTest = new MyRefAfterFilter(); + + List items = new ArrayList(2); + Category category = new Category("category"); + items.add(new Item("item1",category)); + items.add(new Item("item2",category)); + +// System.out.println(JSON.toJSONString(items)); + System.out.println(JSON.toJSONString(items, refAfterFilterTest)); + + } + + public static class MyRefAfterFilter extends AfterFilter { + + private Category category = new Category("afterFilterCategory"); + + @Override + public void writeAfter(Object object) { + if(object instanceof Item){ + this.writeKeyValue("afterFilterCategory", category); + } + } + + } + + public static class Item { + + private String name; + + private Category category; + + + public Item(String name,Category category){ + this.name = name; + this.category = category; + } + + public String getName() { + return name; + } + + public Category getcategory() { + return category; + } + } + + public static class Category { + + private String name; + + public Category(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3160.java b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3160.java new file mode 100644 index 0000000000..26517232d8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3100/Issue3160.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.issue_3100; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.util.IOUtils; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.lang.reflect.Field; + +public class Issue3160 extends TestCase { + + public void test_for_issue() throws Exception { + String str = createLargeBasicStr(); + SerializeWriter writer = new SerializeWriter(); + //写入大于12K的字符串 + writer.writeString(str); + writer.writeString(str); + byte[] bytes = writer.toBytes("UTF-8"); + writer.close(); + + //检查bytesLocal大小,如果缓存成功应该大于等于输出的bytes长度 + Field bytesBufLocalField = SerializeWriter.class.getDeclaredField("bytesBufLocal"); + bytesBufLocalField.setAccessible(true); + ThreadLocal bytesBufLocal = (ThreadLocal) bytesBufLocalField.get(null); + byte[] bytesLocal = bytesBufLocal.get(); + Assert.assertNotNull("bytesLocal is null", bytesLocal); + Assert.assertTrue("bytesLocal is smaller than expected", bytesLocal.length >= bytes.length); + + } + + private String createLargeBasicStr() { + String tmp = new String(IOUtils.DIGITS); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < 400; i++) { + builder.append(tmp); + } + return builder.toString(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3206.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3206.java new file mode 100644 index 0000000000..f0e270d1e9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3206.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.NameFilter; +import junit.framework.TestCase; + +public class Issue3206 extends TestCase { + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.date = new java.util.Date(1590819204293L); + + + assertEquals(JSON.toJSONString(vo), "{\"date\":\"2020-05-30\"}"); + + String str = JSON.toJSONString(vo, new NameFilter() { + public String process(Object object, String name, Object value) { + return name; + } + }); + assertEquals(str, "{\"date\":\"2020-05-30\"}"); + } + + public static class VO { + @JSONField(format="yyyy-MM-dd") + public java.util.Date date; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3217.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3217.java new file mode 100644 index 0000000000..2278ef1cab --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3217.java @@ -0,0 +1,72 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue3217 extends TestCase { + public void testException(){ + MyException myException = new MyException(); + myException.enumTest = EnumTest.FIRST; + TestClass testClass = new TestClass(); + testClass.setMyException(myException); + + String jsonString = JSON.toJSONString(testClass, SerializerFeature.NotWriteDefaultValue); + System.out.println(jsonString); + + TestClass testClass1 = JSON.parseObject(jsonString, TestClass.class); + System.out.println(testClass1); + } + + public static enum EnumTest{ + FIRST("111","111"), + SECOND("222","222"); + private String key; + private String value; + + EnumTest(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public static class MyException extends Exception { + private EnumTest enumTest; + + public EnumTest getEnumTest() { + return enumTest; + } + + public void setEnumTest(EnumTest enumTest) { + this.enumTest = enumTest; + } + } + + public static class TestClass{ + private MyException myException; + + public MyException getMyException() { + return myException; + } + + public void setMyException(MyException myException) { + this.myException = myException; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3227.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3227.java new file mode 100644 index 0000000000..8e289e09ee --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3227.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * @Author :Nanqi + * @Date :Created in 20:38 2020/6/27 + */ +public class Issue3227 extends TestCase { + public void test_for_issue() { + String json = "{\"code\":\"123\"}"; + if (!Child.class.getMethods()[0].getReturnType().getName().contains("Object")) { + System.out.println(Child.class.getMethods()[0].getReturnType().getName()); + } + Child child = JSON.parseObject(json, Child.class); + Assert.assertNotNull(child); + } + + static class Parent { + protected String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + protected T code; + + public T getCode() { + return code; + } + + public void setCode(T code) { + this.code = code; + } + } + + static class Child extends Parent{ + @Override + public Integer getCode() { + return code; + } + + @Override + public void setCode(Integer code) { + this.code = code; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3245.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3245.java new file mode 100644 index 0000000000..ae365000ac --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3245.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +public class Issue3245 extends TestCase { + public void test_for_issue() throws Exception { + JSONValidator v = JSONValidator.from("[]"); + v.validate(); + assertEquals(JSONValidator.Type.Array, v.getType()); + } + + public void test_for_issue_1() throws Exception { + assertEquals(JSONValidator.Type.Array, JSONValidator.from("[]").getType()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3246.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3246.java new file mode 100644 index 0000000000..12b84145e3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3246.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import lombok.Data; + +public class Issue3246 extends TestCase { + public void test_for_issue() throws Exception { + String jsonStr = "{\"d_id\":\"bphyean01\",\"isOpenMergeCode\":0,\"offlineOrder\":false,\"offlineOrderType\":-1,\"og\":0,\"pushIdFromRemote\":false,\"qrisAmountPrice\":22000,\"s_req\":0,\"s_t\":1,\"skr_id\":0,\"type\":1,\"c_id\":471,\"o_$\":5500.0,\"am\":4,\"$_tp\":\"bp\",\"o_t\":1,\"a_m\":3}"; + Order parseOrder = JSON.parseObject(jsonStr,Order.class); + assertEquals(Integer.valueOf(4), parseOrder.getAmount()); + assertEquals("3", parseOrder.getAddMoney()); + + } + + @Data + public static class Order { + @JSONField(name = "d_id", ordinal = 0) + private String deviceId; + @JSONField(name = "c_id", ordinal = 1) + private Integer commodityId; + @JSONField(name = "o_$", ordinal = 2) + private Double orderPrice; + @JSONField(name = "am", ordinal = 3) + private Integer amount; + @JSONField(name = "$_tp", ordinal = 4) + private String payType; + @JSONField(name = "wx_p_id", ordinal = 5) + private Long productId; + @JSONField(name = "ext_p_id", ordinal = 6) + private Long extraProductId; + @JSONField(name = "u_id", ordinal = 7) + private String userId; + @JSONField(name = "p_id", ordinal = 8) + private Long parentId; + @JSONField(name = "o_t", ordinal = 9) + private Integer orderType; + @JSONField(name = "ts", ordinal = 10) + private Integer tradeStatus; + @JSONField(name = "pn", ordinal = 11) + private String phoneNum; + @JSONField(name = "conf_id", ordinal = 12) + private Long configId; + @JSONField(name = "sku_id", ordinal = 13) + private Long skuCommodityId; + @JSONField(name = "c_ids", ordinal = 14) + private String commodityIds; + @JSONField(name = "a_m", ordinal = 15) + private String addMoney; + @JSONField(name = "skr_id", ordinal = 15) + private Long secKillRecordId; + @JSONField(name = "c_n", ordinal = 16) + private String clientOrderNum; + @JSONField(name = "s_t", ordinal = 16) + private Integer sceneType; + @JSONField(name = "t_t", ordinal = 16) + private Integer tradingType; + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3264.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3264.java new file mode 100644 index 0000000000..0331ac0775 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3264.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import org.junit.Assert; + +/** + * @Author :Nanqi + * @Date :Created in 21:25 2020/6/22 + */ +public class Issue3264 extends TestCase { + public void test_for_issue() throws Exception { + MyData data = MyData.builder().isTest(true).build(); + String string = JSON.toJSONString(data); + Assert.assertTrue(string.contains("is_test")); + } + + @Data + @Builder + @AllArgsConstructor + public static class MyData { + @JSONField(name = "is_test") + private Boolean isTest; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3266.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3266.java new file mode 100644 index 0000000000..36ddbe707e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3266.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue3266 extends TestCase { + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.type = Color.Black; + + String str = JSON.toJSONString(vo); + assertEquals("{\"type\":1003}", str); + + VO vo2 = JSON.parseObject(str, VO.class); + + } + + public static class VO { + public Color type; + } + + public enum Color { + Red(1001), + White(1002), + Black(1003), + Blue(1004); + + private final int code; + + private Color(int code) { + this.code = code; + } + + @JSONField + public int getCode() { + return code; + } + + @JSONCreator + public static Color from(int code) { + for (Color v : values()) { + if (v.code == code) { + return v; + } + } + + throw new IllegalArgumentException("code " + code); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3266_mixedin.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3266_mixedin.java new file mode 100644 index 0000000000..19a4e32c1b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3266_mixedin.java @@ -0,0 +1,63 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue3266_mixedin extends TestCase { + public void test_for_issue() throws Exception { + JSON.addMixInAnnotations(Color.class, ColorMixedIn.class); + + VO vo = new VO(); + vo.type = Color.Black; + + String str = JSON.toJSONString(vo); + assertEquals("{\"type\":1003}", str); + + VO vo2 = JSON.parseObject(str, VO.class); + } + + public static class VO { + public Color type; + } + + public enum Color { + Red(1001), + White(1002), + Black(1003), + Blue(1004); + + private final int code; + + private Color(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static Color from(int code) { + for (Color v : values()) { + if (v.code == code) { + return v; + } + } + + throw new IllegalArgumentException("code " + code); + } + } + + public static class ColorMixedIn { + @JSONField + public int getCode() { + return 0; + } + + @JSONCreator + public static Color from(int code) { + return null; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3267.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3267.java new file mode 100644 index 0000000000..6647ba728d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3267.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +public class Issue3267 extends TestCase { + public void test_for_issue() throws Exception { + JSONValidator v = JSONValidator.from("113{}[]"); + v.setSupportMultiValue(false); + assertFalse( + v.validate()); + + assertEquals(JSONValidator.Type.Value, v.getType()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3274.kt b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3274.kt new file mode 100644 index 0000000000..8797b804a6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3274.kt @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.issue_3200 + +import com.alibaba.fastjson.JSON +import junit.framework.Assert.assertEquals +import org.junit.Test +import java.util.* + +class TestFJ { + + @Test + fun test() { + val str = """ + {"data": {"id": "1", "name":"n1"}} + """.trimIndent() + + + val d1 = JSON.parseObject(str, Data2::class.java) + + val data = JSON.parseObject(str) + val d2 = data.getObject("data", Data::class.java) + + assertEquals(1, d1.data.id) + assertEquals(1, d2.id) + } +} + +data class Data( + val id: Int = 0, + val name: String = "", + val date: Date? = null +) +data class Data2( + val data: Data +) \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3279.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3279.java new file mode 100644 index 0000000000..1c41f1106a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3279.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class Issue3279 extends TestCase { + public void test_for_issue() throws Exception { + V0 v = JSON.parseObject("{\"id\":\" 1001 \"}", V0.class, Feature.TrimStringFieldValue); + assertEquals("1001", v.id); + + v = JSON.parseObject("{\"id\":\" 1001 \"}", V0.class); + assertEquals(" 1001 ", v.id); + } + + public void test_for_issue_1() throws Exception { + V1 v = JSON.parseObject("{\"id\":\" 1001 \"}", V1.class); + assertEquals("1001", v.id); + } + + public void test_for_issue_2() throws Exception { + V2 v = JSON.parseObject("{\"id\":\" 1001 \"}", V2.class); + assertEquals("1001", v.id); + } + + public static class V0 { + public String id; + } + + public static class V1 { + @JSONField(parseFeatures = Feature.TrimStringFieldValue) + public String id; + } + + @JSONType(parseFeatures = Feature.TrimStringFieldValue) + public static class V2 { + public String id; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3281.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3281.java new file mode 100644 index 0000000000..4ac5e75a2c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3281.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import org.junit.Assert; + +import java.util.Date; +import java.util.HashMap; + +/** + * @Author :Nanqi + * @Date :Created in 10:47 2020/6/22 + * @Description:补充测试用例 + */ +public class Issue3281 extends TestCase { + public void test_for_issue() { + ModelState modelBack = JSON.parseObject("{\"counterMap\":{\"0\":0,\"100\":0,\"200\":0,\"300\":0,\"400\":0," + + "\"500\":0,\"600\":0,\"700\":0,\"800\":0,\"900\":0,\"1000\":0},\"formatDate\":null," + + "\"modelName\":\"test\",\"modelScores\":{\"Test1-1000\":{\"max\":1.0997832999999515,\"min\":0.0," + + "\"recording\":false}},\"modelVersion\":\"1\",\"pit\":1592470429399,\"useCaseName\":\"test\"," + + "\"variableName\":\"v2\"}", ModelState.class); + Assert.assertNotNull(modelBack.getCounterMap()); + Assert.assertNotNull(modelBack.getModelScores()); + } + + @Builder + @Data + @AllArgsConstructor + public static class ModelState { + private HashMap counterMap; + + private Date formatDate; + + private HashMap modelScores; + + private String modelName; + + private Long modelVersion; + + private Long pit; + + private String useCaseName; + + private String variableName; + } + + @Builder + @Data + @AllArgsConstructor + public static class TGigest { + private Double max; + + private Double min; + + private Boolean recording; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3282.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3282.java new file mode 100644 index 0000000000..b422a75e66 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3282.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue3282 extends TestCase { + public void test_for_issue() { + Demo demo = JSON.parseObject("{'date':'2020-01-01 00:00:00 000'}", Demo.class); + assertNotNull(demo.date); + } + + public static class Demo { + public java.util.Date date; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3283.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3283.java new file mode 100644 index 0000000000..ff018657fa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3283.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue3283 extends TestCase { + public void test_for_issue() throws Exception { + VO v = new VO(); + v.v0 = 1001L; + v.v1 = 101; + + String str = JSON.toJSONString(v, SerializerFeature.WriteNonStringValueAsString); + + JSONObject object = JSON.parseObject(str); + assertEquals("1001", object.get("v0")); + assertEquals("101", object.get("v1")); + } + + public void test_for_issue_1() throws Exception { + VO v = new VO(); + v.v0 = 19007199254740991L; + + String str = JSON.toJSONString(v, SerializerFeature.BrowserCompatible); + assertEquals("{\"v0\":\"19007199254740991\"}", str); + } + + public static class VO { + public Long v0; + public Integer v1; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3293.java b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3293.java new file mode 100644 index 0000000000..a78dc4d56d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/Issue3293.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * @Author :Nanqi + * @Date :Created in 09:59 2020/6/24 + */ +public class Issue3293 extends TestCase { + public void test_for_issue() throws Exception { + JSONValidator jv = JSONValidator.from("{\"a\"}"); + Assert.assertFalse(jv.validate()); + + jv = JSONValidator.from("113{}[]"); + jv.setSupportMultiValue(false); + Assert.assertFalse(jv.validate()); + Assert.assertEquals(JSONValidator.Type.Value, jv.getType()); + + jv = JSONValidator.from("{\"a\":\"12333\"}"); + Assert.assertTrue(jv.validate()); + + jv = JSONValidator.from("{}"); + Assert.assertTrue(jv.validate()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3200/TestIssue3223.kt b/src/test/java/com/alibaba/json/bvt/issue_3200/TestIssue3223.kt new file mode 100644 index 0000000000..de312774d4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3200/TestIssue3223.kt @@ -0,0 +1,108 @@ +package com.alibaba.json.bvt.issue_3200; + +import com.alibaba.fastjson.JSON +import com.alibaba.fastjson.JSONObject +import com.alibaba.fastjson.parser.ParserConfig +import com.alibaba.fastjson.serializer.SerializerFeature +import org.junit.Assert +import org.junit.Test +import java.util.concurrent.atomic.AtomicInteger +import kotlin.properties.Delegates + +/** + * kotlin集合测试 + * @author 佐井 + * @since 2020-06-05 20:35 + */ + + +class TestIssue3223 { + + @Test + fun test() { + val cfg = ParserConfig.getGlobalInstance() + cfg.addAccept("com.") + cfg.addAccept("net.") + cfg.addAccept("java.") + cfg.addAccept("kotlin.") + cfg.addAccept("org.") + val n = NullableKotlin() + //nullable + n.nullableList = listOf("nullableList") + n.nullableMap = mapOf("nullableMap" to "nullableMap") + n.nullableSet = setOf("nullableSet") + //empty + n.emptyList = listOf("emptyList") + n.emptyMap = mapOf("emptyMap" to "emptyMap") + n.emptySet = setOf("emptySet") + //delegate + n.delegateList = listOf("delegateList") + n.delegateMap = mapOf("delegateMap" to "delegateMap") + n.delegateSet = setOf("delegateSet") + //basic + n.atomicInt = AtomicInteger(10) + n.longValue = 1 + n.json = JSON.parseObject(JSON.toJSONString(mapOf("a" to "b"))) + val raw = JSON.toJSONString(n, SerializerFeature.WriteClassName) + val d = JSON.parseObject(raw, NullableKotlin::class.java) + Assert.assertTrue(n == d) + + } + +} + + +class NullableKotlin { + //map + var nullableMap: Map? = null + var emptyMap: Map = emptyMap() + var delegateMap by Delegates.notNull>() + + //set + var nullableSet: Set? = null + var emptySet: Set = emptySet() + var delegateSet by Delegates.notNull>() + + //list + var nullableList: List? = null + var emptyList: List = emptyList() + var delegateList by Delegates.notNull>() + + //basic + var atomicInt: AtomicInteger? = null + var longValue: Long? = null + var json: JSONObject? = null + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as NullableKotlin + + if (nullableMap != other.nullableMap) return false + if (emptyMap != other.emptyMap) return false + if (nullableSet != other.nullableSet) return false + if (emptySet != other.emptySet) return false + if (nullableList != other.nullableList) return false + if (emptyList != other.emptyList) return false + if (atomicInt?.get() != other.atomicInt?.get()) return false + if (longValue != other.longValue) return false + if (json != other.json) return false + + return true + } + + override fun hashCode(): Int { + var result = nullableMap?.hashCode() ?: 0 + result = 31 * result + emptyMap.hashCode() + result = 31 * result + (nullableSet?.hashCode() ?: 0) + result = 31 * result + emptySet.hashCode() + result = 31 * result + (nullableList?.hashCode() ?: 0) + result = 31 * result + emptyList.hashCode() + result = 31 * result + (atomicInt?.hashCode() ?: 0) + result = 31 * result + (longValue?.hashCode() ?: 0) + result = 31 * result + (json?.hashCode() ?: 0) + return result + } + + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3217.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3217.java new file mode 100644 index 0000000000..e54e477751 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3217.java @@ -0,0 +1,98 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.AfterFilter; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +public class Issue3217 extends TestCase { + + public void test_for_issue() throws Exception { + RefAfterFilterTest refAfterFilterTest = new RefAfterFilterTest(); + + List items = new ArrayList(2); + Category category = new Category("category"); + items.add(new Item("item1",category)); + items.add(new Item("item2",category)); + + System.out.println(JSON.toJSONString(items,refAfterFilterTest)); + } + + public static class RefAfterFilterTest extends AfterFilter { + + private Category category = new Category("afterFilterCategory"); + + @Override + public void writeAfter(Object object) { + + if (object instanceof Item) { + + this.writeKeyValue("afterFilterCategory", category); + /*多加一个属性报错,原因是category是object也触发了writeAfter,当前线程变量serializer被设置为null了serializerLocal.set(null); + *这两个write换个顺序就不会报错 + */ + this.writeKeyValue("afterFilterTwo", "two"); + + } + } + } + + public static class Category { + + private String name; + + public Category(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class Item { + + private String name; + + private Category category; + + private String barcode; + + + public Item(String name,Category category){ + this.name = name; + this.category = category; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + public String getBarcode() { + return barcode; + } + + public void setBarcode(String barcode) { + this.barcode = barcode; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3309.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3309.java new file mode 100644 index 0000000000..b0d8f67253 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3309.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.Date; + +/** + * @Author :Nanqi + * @Date :Created in 16:27 2020/6/29 + */ +public class Issue3309 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject jsonObj = new JSONObject(); + jsonObj.put("formatDate","20200623 15:20:01"); + DateFormatTest dateFormatTest = jsonObj.toJavaObject(DateFormatTest.class); + JSON.toJSONString(dateFormatTest); + } + + static class DateFormatTest { + @JSONField(format = "yyyyMMdd HH:mm:ss") + private Date formatDate; + + public Date getFormatDate() { + return formatDate; + } + + public void setFormatDate(Date formatDate) { + this.formatDate = formatDate; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3313.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3313.java new file mode 100644 index 0000000000..a50faa25ad --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3313.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import lombok.Data; +import org.springframework.util.Assert; + +/** + * @Author :Nanqi + * @Date :Created in 21:54 2020/6/30 + */ +public class Issue3313 extends TestCase { + public void test_for_issue() throws Exception { + String jsonStr = "{\"NAME\":\"nanqi\",\"age\":18}"; + Model model = JSONObject.parseObject(jsonStr, Model.class); + Assert.notNull(model.getAGe()); + Assert.notNull(model.getName()); + } + + @Data + static class Model { + @JSONField(name = "NaMe") + private String name; + + @JSONField(name = "age") + private Integer aGe; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3314.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3314.java new file mode 100644 index 0000000000..2cf03bb6e4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3314.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Field; + +public class Issue3314 extends TestCase { + private Field field; + protected void setUp() throws Exception { + Class clazz = Class.forName("com.alibaba.fastjson.JSONObject$SecureObjectInputStream"); + field = clazz.getDeclaredField("fields_error"); + field.setAccessible(true); + field.set(null, true); + } + + protected void tearDown() throws Exception { + field.set(null, false); + } + + public void test_for_issue() throws Exception { + JSONArray array = new JSONArray(); + array.add(1); + array.add(null); + array.add("wenshaojin"); + + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(array); + objOut.flush(); + + + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(JSONArray.class, obj.getClass()); + assertEquals(array, obj); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3326.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3326.java new file mode 100644 index 0000000000..056e973861 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3326.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import junit.framework.TestCase; + +import java.util.HashMap; + +public class Issue3326 extends TestCase { + public void test_for_issue() throws Exception { + HashMap map = JSON.parseObject("{\"id\":10.0}" + , new TypeReference>() { + }.getType() + , 0); + assertEquals(10.0, map.get("id")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3329.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3329.java new file mode 100644 index 0000000000..7e0aa8a3bb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3329.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.IdentityHashMap; +import com.alibaba.fastjson.util.ParameterizedTypeImpl; +import junit.framework.TestCase; +import java.util.List; + +import java.lang.reflect.Type; + +public class Issue3329 extends TestCase { + public void test_for_issue() throws Exception { + ParserConfig config = new ParserConfig(); + IdentityHashMap deserializers = config.getDeserializers(); + int initSize = deserializers.size(); + for (int i = 0; i < 1000 * 10; ++i) { + assertEquals(123, + ((VO) JSON.parseObject("{\"value\":{\"id\":123}}", + new ParameterizedTypeImpl(new Type[] {User.class}, null, VO.class), + config + )).value.id + ); + } + + + assertEquals(2, deserializers.size() - initSize); + } + + public static class VO { + public T value; + } + + public static class User { + public int id; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3334.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3334.java new file mode 100644 index 0000000000..fac1ef433c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3334.java @@ -0,0 +1,104 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue3334 extends TestCase { + public void test_for_issue() throws Exception { + assertEquals(0, + JSON.parseObject("{\"id\":false}", VO.class).id); + + assertEquals(1, + JSON.parseObject("{\"id\":true}", VO.class).id); + + + assertEquals(0, + JSON.parseObject("{\"id64\":false}", VO.class).id64); + + assertEquals(1, + JSON.parseObject("{\"id64\":true}", VO.class).id64); + + assertEquals(0, + JSON.parseObject("{\"id16\":false}", VO.class).id16); + + assertEquals(1, + JSON.parseObject("{\"id16\":true}", VO.class).id16); + + + assertEquals(0, + JSON.parseObject("{\"id8\":false}", VO.class).id8); + + assertEquals(1, + JSON.parseObject("{\"id8\":true}", VO.class).id8); + + + assertEquals(0F, + JSON.parseObject("{\"floatValue\":false}", VO.class).floatValue); + + assertEquals(1F, + JSON.parseObject("{\"floatValue\":true}", VO.class).floatValue); + + assertEquals(0D, + JSON.parseObject("{\"doubleValue\":false}", VO.class).doubleValue); + + assertEquals(1D, + JSON.parseObject("{\"doubleValue\":true}", VO.class).doubleValue); + } + + public static class VO { + private byte id8; + private short id16; + private int id; + private long id64; + private Float floatValue; + private Double doubleValue; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public long getId64() { + return id64; + } + + public void setId64(long id64) { + this.id64 = id64; + } + + public short getId16() { + return id16; + } + + public void setId16(short id16) { + this.id16 = id16; + } + + public byte getId8() { + return id8; + } + + public void setId8(byte id8) { + this.id8 = id8; + } + + public Float getFloatValue() { + return floatValue; + } + + public void setFloatValue(Float floatValue) { + this.floatValue = floatValue; + } + + public Double getDoubleValue() { + return doubleValue; + } + + public void setDoubleValue(Double doubleValue) { + this.doubleValue = doubleValue; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3336.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3336.java new file mode 100644 index 0000000000..52313c3ddb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3336.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue3336 extends TestCase { + public void test_for_issue() throws Exception { + String s = "{\"schema\":{\"$ref\":\"#/definitions/URLJumpConfig\"}}"; + assertEquals(s, JSON.parseObject(s) + .toJSONString()); + + String s1 = "{\"schema\":{\"ref\":\"#/definitions/URLJumpConfig\"}}"; + assertEquals(s1, JSON.parseObject(s1) + .toJSONString()); + + String s2 = "{\"schema\":{\"$ref\":\"#/definitions/URLJumpConfig\"}}"; + assertEquals(s2, JSON.parseObject(s2) + .toJSONString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3338.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3338.java new file mode 100644 index 0000000000..82bc427def --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3338.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Author :Nanqi + * @Date :Created in 17:11 2020/7/11 + */ +public class Issue3338 extends TestCase { + public void test_for_issue() throws Exception { + Model model = new Model(); + Map map = new HashMap(); + map.put("nanqi", "因为相信,所以看见。"); + model.setMap(map); + + String jsonString = JSONObject.toJSONString(model); + assertTrue(jsonString.contains("因为相信,所以看见。")); + + Model modelBack = JSONObject.parseObject(jsonString, Model.class); + assertEquals("因为相信,所以看见。", modelBack.getMap().get("nanqi")); + } + + static class Model { + private Map map; + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3343.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3343.java new file mode 100644 index 0000000000..9b2ee0d605 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3343.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +public class Issue3343 extends TestCase { + public void test_for_issue() throws Exception { + assertFalse( + JSONValidator.from("{\"name\":\"999}") + .validate()); + + assertTrue( + JSONValidator.from("false") + .validate()); + assertEquals(JSONValidator.Type.Value, + JSONValidator.from("false") + .getType()); + + assertTrue( + JSONValidator.from("999").validate()); + assertEquals(JSONValidator.Type.Value, + JSONValidator.from("999") + .getType()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3344.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3344.java new file mode 100644 index 0000000000..dadf81df80 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3344.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.Date; +import java.util.TimeZone; + + +/** + * @Author :Nanqi + * @Date :Created in 18:28 2020/7/19 + */ +public class Issue3344 extends TestCase { + public void test_for_issue_timeZone() throws Exception { + TimeZone.setDefault(TimeZone.getTimeZone("GMT+1")); + String jsonStr = "{\"date\":1595154768}"; + Model model = JSONObject.parseObject(jsonStr, Model.class); + assertEquals("Mon Jan 19 12:05:54 GMT+01:00 1970", model.getDate().toString()); + } + + static class Model { + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3347.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3347.java new file mode 100644 index 0000000000..19aee81a82 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3347.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Author :Nanqi + * @Date :Created in 22:29 2020/7/15 + */ +public class Issue3347 extends TestCase { + public void test_for_issue() throws Exception { + Map map = new HashMap(); + map.put(1, "hello"); + String mapJSONString = JSON.toJSONString(map); + Map mapValues = JSONObject.parseObject(mapJSONString, Map.class); + Object mapKey = mapValues.keySet().iterator().next(); + assertTrue(mapKey instanceof Integer); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3351.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3351.java new file mode 100644 index 0000000000..ea4c82a44b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3351.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +/** + * @Author :Nanqi + * @Date :Created in 00:14 2020/7/18 + */ +public class Issue3351 extends TestCase { + public void test_for_issue() throws Exception { + String cString = "c110"; + boolean cValid = JSONValidator.from(cString).validate(); + assertFalse(cValid); + + String jsonString = "{\"forecast\":\"sss\"}"; + boolean jsonValid = JSONValidator.from(jsonString).validate(); + assertTrue(jsonValid); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3352.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3352.java new file mode 100644 index 0000000000..03fb7ea03a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3352.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.Map; +import java.util.UUID; + +public class Issue3352 extends TestCase { + public void test_for_issue() throws Exception { + UUID uuid = UUID.randomUUID(); + + JSONObject object = new JSONObject(); + Map map = object.getInnerMap(); + map.put("1", "1"); + map.put("A", "A"); + map.put("true", "true"); + map.put(uuid.toString(), uuid); + + assertTrue(object.containsKey(1)); + assertTrue(object.containsKey("1")); + assertTrue(object.containsKey('A')); + assertTrue(object.containsKey("A")); + assertTrue(object.containsKey(true)); + assertTrue(object.containsKey("true")); + assertTrue(object.containsKey(uuid)); + assertTrue(object.containsKey(uuid.toString())); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3356.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3356.java new file mode 100644 index 0000000000..a761a945c4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3356.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.util.UUID; + +public class Issue3356 extends TestCase { + public void test_for_issue() throws Exception { + UUID uuid = UUID.randomUUID(); + + JSONObject object = new JSONObject(); + object.put("1", "1"); + object.put(uuid.toString(), uuid.toString()); + object.put("A", "A"); + object.put("true", "true"); + assertEquals("1", object.get(1)); + assertEquals("true", object.get(true)); + assertEquals("A", object.get('A')); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3358.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3358.java new file mode 100644 index 0000000000..2ded7d0e40 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3358.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import junit.framework.TestCase; +import org.joda.time.LocalDateTime; + +/** + * @Author :Nanqi + * @Date :Created in 19:07 2020/7/21 + */ +public class Issue3358 extends TestCase { + public void test_for_issue() throws Exception { + Model validateCode = new Model("111", 600); + String jsonString = JSON.toJSONString(validateCode); + Model backModel = JSON.parseObject(jsonString, Model.class); + assertEquals(validateCode.getExpireTime(), backModel.getExpireTime()); + + jsonString = "{\"code\":\"111\"}"; + backModel = JSON.parseObject(jsonString, Model.class); + assertNull(backModel.getExpireTime()); + } + + public static class Model { + private String code; + + private LocalDateTime expireTime; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public LocalDateTime getExpireTime() { + return expireTime; + } + + public void setExpireTime(LocalDateTime expireTime) { + this.expireTime = expireTime; + } + + public Model(String code, int expireIn) { + this.code = code; + this.expireTime = LocalDateTime.now().plusSeconds(expireIn); + } + + @JSONCreator + public Model(String code, LocalDateTime expireTime) { + this.code = code; + this.expireTime = expireTime; + } + + public boolean isExpried() { + return LocalDateTime.now().isAfter(getExpireTime()); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3361.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3361.java new file mode 100644 index 0000000000..dde3f936fb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3361.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import junit.framework.TestCase; + +import java.util.Date; + +@Slf4j +public class Issue3361 extends TestCase { + private static String ORIGIN_JSON_DEFAULT_DATE_FORMAT; + + @Override + public void setUp() throws Exception { + ORIGIN_JSON_DEFAULT_DATE_FORMAT = JSON.DEFFAULT_DATE_FORMAT; + } + + public void test_for_issue() throws Exception { + Model model = new Model(); + model.setOldDate(new Date()); + log.info("{}", model); + + FastJsonConfig config = new FastJsonConfig(); + config.setSerializerFeatures(SerializerFeature.WriteMapNullValue); + config.setWriteContentLength(false); + JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS"; + config.setDateFormat(JSON.DEFFAULT_DATE_FORMAT); + String string = JSON.toJSONString(model, + config.getSerializeConfig(), + config.getSerializeFilters(), + config.getDateFormat(), + JSON.DEFAULT_GENERATE_FEATURE, + config.getSerializerFeatures()); + log.info("{}", string); + + Model model2 = JSON.parseObject(string, Model.class); + log.info("{}", model2); + + Model model3 = JSON.parseObject(string, new TypeReference() { + }.getType()); + log.info("{}", model3); + } + + @Override + public void tearDown() throws Exception { + JSON.DEFFAULT_DATE_FORMAT = ORIGIN_JSON_DEFAULT_DATE_FORMAT; + } + + @Getter + @Setter + @ToString + public static class Model { + + private Date oldDate; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3373.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3373.java new file mode 100644 index 0000000000..cbd6e39db6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3373.java @@ -0,0 +1,97 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.BeforeFilter; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +public class Issue3373 extends TestCase { + public void test_for_issue() throws Exception { + RefBeforeFilterTest refAfterFilterTest = new RefBeforeFilterTest(); + + List items = new ArrayList(2); + Category category = new Category("category"); + items.add(new Item("item1",category)); + items.add(new Item("item2",category)); + + System.out.println(JSON.toJSONString(items,refAfterFilterTest)); + } + + public static class RefBeforeFilterTest extends BeforeFilter { + + private Category category = new Category("afterFilterCategory"); + + @Override + public void writeBefore(Object object) { + + if (object instanceof Item) { + + this.writeKeyValue("afterFilterCategory", category); + /*多加一个属性报错,原因是category是object也触发了writeAfter,当前线程变量serializer被设置为null了serializerLocal.set(null); + *这两个write换个顺序就不会报错 + */ + this.writeKeyValue("afterFilterTwo", "two"); + + } + } + } + + public static class Category { + + private String name; + + public Category(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class Item { + + private String name; + + private Category category; + + private String barcode; + + + public Item(String name, Category category){ + this.name = name; + this.category = category; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + public String getBarcode() { + return barcode; + } + + public void setBarcode(String barcode) { + this.barcode = barcode; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3375.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3375.java new file mode 100644 index 0000000000..d9a95afcb9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3375.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author :Nanqi + * @Date :Created in 01:09 2020/8/2 + */ +public class Issue3375 extends TestCase { + public void test_for_issue() throws Exception { + List> models = new ArrayList>(); + Map map1 = new HashMap(); + map1.put("name", "nanqi01"); + models.add(map1); + + Map map2 = new HashMap(); + map2.put("name", "nanqi02"); + models.add(map2); + + for (Map model : models) { + String modelStr = JSON.toJSONString(model); + Model modelObj = JSON.parseObject(modelStr, Model.class); + assertTrue(modelObj.getName().contains("nanqi")); + } + } + + public static class Model { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3376.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3376.java new file mode 100644 index 0000000000..943ede86a1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3376.java @@ -0,0 +1,81 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +/** + * @Author :Nanqi + * @Date :Created in 01:25 2020/8/2 + */ +public class Issue3376 extends TestCase { + public void test_for_issue() throws Exception { + Model model = new Model(1, 1); + String modelString = JSON.toJSONString(model); + assertEquals("{}", modelString); + + Model2 model2 = new Model2(1, 1); + String model2String = JSON.toJSONString(model2); + assertEquals("{\"offset\":1,\"timestamp\":1}", model2String); + + Model3 model3 = new Model3(1, 1); + String model3String = JSON.toJSONString(model3); + assertEquals("{\"off\":1,\"timeStamp\":true,\"timestamp\":1}", model3String); + } + + public static class Model { + private final long offset; + private final long timestamp; + + public Model(long offset, long timestamp) { + this.offset = offset; + this.timestamp = timestamp; + } + + /** + * 这种 类似的 get 方法不正规,没办法确定那个方法才算是获取参数的接口,可以参考例子 3 + */ + public long timestamp() { + return timestamp; + } + + public long offset() { + return this.offset; + } + } + + public static class Model2 { + private final long offset; + private final long timestamp; + + public Model2(long offset, long timestamp) { + this.offset = offset; + this.timestamp = timestamp; + } + + public long getOffset() { + return offset; + } + + public long getTimestamp() { + return timestamp; + } + } + + public static class Model3 { + private final long offset; + public final long timestamp; + + public Model3(long offset, long timestamp) { + this.offset = offset; + this.timestamp = timestamp; + } + + public long getOff() { + return offset; + } + + public Boolean isTimeStamp() { + return true; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3397.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3397.java new file mode 100644 index 0000000000..f81aecd5cf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3397.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.time.LocalDateTime; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** + * @Author :Nanqi + * @Date :Created in 16:32 2020/8/16 + */ +public class Issue3397 extends TestCase { + @Override + public void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getDefault(); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + String text = "{\"date\":\"2020-08-16 16:35:18.188\"}"; + VO vo = JSON.parseObject(text, VO.class); + + JSONObject json = (JSONObject) JSONObject.toJSON(vo); + + Date date = json.getDate("date"); +// assertEquals("Sun Aug 16 16:35:18 CST 2020", date.toString()); + } + + public static class VO { + @JSONField(format = "yyyy-MM-dd HH:mm:ss.SSS") + private LocalDateTime date; + + public LocalDateTime getDate() { + return date; + } + + public void setDate(LocalDateTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3443.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3443.java new file mode 100644 index 0000000000..3e3605e516 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3443.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.serializer.*; +import junit.framework.TestCase; + +public class Issue3443 extends TestCase { + public void testCustomJsonSerializerAndAfterFilter() throws Exception { + SerializeWriter serializeWriter = new SerializeWriter(); + try { + JSONSerializer jsonSerializer = new JSONSerializer(serializeWriter, new SerializeConfig()); + + Parameter parameter = new Parameter(); + parameter.setParameterDesc(new ParameterDesc("vipExpireDate", "VIP expire date.")); + + jsonSerializer.config(SerializerFeature.DisableCircularReferenceDetect, true); + jsonSerializer.getAfterFilters().add(new CustomFilter()); + jsonSerializer.write(parameter); + assertEquals("{\"parameterDesc\":{\"ParameterDesc\":\"VIP expire date.\"}}", serializeWriter.toString()); + } finally { + serializeWriter.close(); + } + } + + static class Parameter { + private ParameterDesc parameterDesc; + + public ParameterDesc getParameterDesc() { + return parameterDesc; + } + + public void setParameterDesc(ParameterDesc parameterType) { + this.parameterDesc = parameterType; + } + } + + static class ParameterDesc { + private String parameterName; + private String parameterUsage; + // do some work... + + public ParameterDesc(String parameterName, String parameterUsage) { + this.parameterName = parameterName; + this.parameterUsage = parameterUsage; + } + + + } + + static class CustomFilter extends AfterFilter { + + @Override + public void writeAfter(Object object) { + if (object instanceof ParameterDesc) { + writeKeyValue("ParameterDesc", "VIP expire date."); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3448.java b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3448.java new file mode 100644 index 0000000000..90a1549cf7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/Issue3448.java @@ -0,0 +1,89 @@ +package com.alibaba.json.bvt.issue_3300; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +import junit.framework.TestCase; +import org.junit.Test; + +/** + * @author yumin.pym + */ +public class Issue3448 extends TestCase { + public static class SelfTypeReference { + + } + + @Test + public void test() { + List>> list = new ArrayList(4); + list.add(Collections.singletonMap("key1", Collections.singletonList("item"))); + String text = JSON.toJSONString(list); + System.out.println("text = " + text); + + List>> result = parseObject(text, + new SelfTypeReference>>() {}); + System.out.println("result = " + result); + TestCase.assertTrue(result.get(0) instanceof Map); + TestCase.assertTrue(result.get(0).get("key1").get(0) instanceof String); + } + + public List parseObject(String text, SelfTypeReference selfTypeReference) { + Type genericSuperclass = selfTypeReference.getClass().getGenericSuperclass(); + Type[] actualTypeArguments = ((ParameterizedType)genericSuperclass).getActualTypeArguments(); + return JSON.parseObject(text, new TypeReference>(actualTypeArguments) {}); + } + + @Test + public void test_1() { + List>> list = new ArrayList(4); + list.add(Collections.singletonMap("key1", Collections.singletonList("item"))); + String text = JSON.toJSONString(list); + System.out.println("text = " + text); + + List>> result = parseObject2(text, + new SelfTypeReference>>() { + }); + System.out.println("result = " + result); + } + + @Test + public void test2() { + List> list = new ArrayList(4); + list.add(Collections.singletonList("item")); + String text = JSON.toJSONString(list); + System.out.println("text = " + text); + + List> result = parseObject2(text, + new SelfTypeReference>() { + }); + System.out.println("result = " + result); + } + + @Test + public void test3() { + List list = new ArrayList(4); + list.add("item"); + String text = JSON.toJSONString(list); + System.out.println("text = " + text); + + List result = parseObject2(text, + new SelfTypeReference() { + }); + System.out.println("result = " + result); + } + + public List parseObject2(String text, SelfTypeReference selfTypeReference) { + Type genericSuperclass = selfTypeReference.getClass().getGenericSuperclass(); + Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments(); + return JSON.parseObject(text, new TypeReference>(actualTypeArguments) { + }); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3300/IssueForJSONFieldMatch.java b/src/test/java/com/alibaba/json/bvt/issue_3300/IssueForJSONFieldMatch.java new file mode 100644 index 0000000000..8115a089a9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3300/IssueForJSONFieldMatch.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.issue_3300; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class IssueForJSONFieldMatch extends TestCase { + public void test_for_issue() throws Exception { + assertEquals(123 + , JSON.parseObject("{\"user_Id\":123}", VO.class) + .userId); + assertEquals(123 + , JSON.parseObject("{\"userId\":123}", VO.class) + .userId); + assertEquals(123 + , JSON.parseObject("{\"user-id\":123}", VO.class) + .userId); + } + + public static class VO { + @JSONField(name = "user_id", alternateNames = {"userId", "user-id"}) + public int userId; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3436.java b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3436.java new file mode 100644 index 0000000000..8a61719194 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3436.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.issue_3400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONType; +import junit.framework.TestCase; +import org.springframework.core.io.FileSystemResource; + +public class Issue3436 extends TestCase { + public void test_for_issue() throws Exception { + JSON.addMixInAnnotations(FileSystemResource.class, FileSystemResourceMixedIn.class); + + FileSystemResource fileSystemResource = new FileSystemResource("E:\\my-code\\test\\test-fastjson.txt"); + + String json = JSON.toJSONString(fileSystemResource); + assertEquals("{\"path\":\"E:/my-code/test/test-fastjson.txt\"}", json); + + FileSystemResource fsr1 = JSON.parseObject(json, FileSystemResource.class); + assertEquals(fileSystemResource.getPath(), fsr1.getPath()); + System.out.println("file size after Serialize:" + fileSystemResource.getFile().length()); + } + + @JSONType(asm = false, includes = "path") + public static class FileSystemResourceMixedIn { + @JSONCreator + public FileSystemResourceMixedIn(String path) { + + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3452.java b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3452.java new file mode 100644 index 0000000000..0a21f7ff5f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3452.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_3400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class Issue3452 extends TestCase { + public void test_for_issue() throws Exception { + String s = "{ \"componentKey\" : \"CMDB_UPDATE_SERVER\"}"; + Step step = JSON.parseObject(s, Step.class); + assertEquals("CMDB_UPDATE_SERVER",step.getComponentKey()); + System.out.println(step.getComponentKey()); + } + + private static class Step { + @JSONField(name = "component_key", alternateNames = {"componentKey"}) + private String componentKey; + + public String getComponentKey() { + return componentKey; + } + + public void setComponentKey(String componentKey) { + this.componentKey = componentKey; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3453.java b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3453.java new file mode 100644 index 0000000000..66e51f612c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3453.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.issue_3400; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * Description:
+ * + * @author byw + * @create 2020/9/20 + */ +public class Issue3453 extends TestCase { + + public void test_for_issue() throws Exception { + String str = "[\n" + + " {\n" + + " \"altitude\": 109.0,\n" + + " \"angle\": 5.0,\n" + + " \"index\": 1,\n" + + " \"type\": 1\n" + + " },\n" + + " {\n" + + " \"altitude\": 1307.0,\n" + + " \"angle\": 5.0,\n" + + " \"index\": 2,\n" + + " \"type\": 1\n" + + " },\n" + + " {\n" + + " \"altitude\": 22.0,\n" + + " \"angle\": 7.0,\n" + + " \"index\": 3,\n" + + " \"type\": 1\n" + + " },\n" + + " {\n" + + " \"altitude\": 22.0,\n" + + " \"angle\": 7.0,\n" + + " \"index\": 4,\n" + + " \"type\": 2\n" + + " },\n" + + " {\n" + + " \"altitude\": 22.0,\n" + + " \"angle\": 7.0,\n" + + " \"index\": 5,\n" + + " \"type\": 2\n" + + " },\n" + + " {\n" + + " \"altitude\": 22.0,\n" + + " \"angle\": 7.0,\n" + + " \"index\": 6,\n" + + " \"type\": 2\n" + + " },\n" + + " {\n" + + " \"altitude\": 22.0,\n" + + " \"angle\": 7.0,\n" + + " \"index\": 7,\n" + + " \"type\": 2\n" + + " }\n" + + "]"; + JSONValidator validator = JSONValidator.from(str); + Assert.assertTrue(validator.validate()); + JSONValidator.Type type = validator.getType(); + Assert.assertEquals("Array",type.name()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3460.java b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3460.java new file mode 100644 index 0000000000..513fad5062 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3460.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.issue_3400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONValidator; +import com.alibaba.json.bvt.issue_3200.Issue3293; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * Description:
+ * + * @author byw + * @create 2020/9/20 + */ +public class Issue3460 extends TestCase { + + public void test_for_issue() throws Exception { + String body = "11{\"time\":" + System.currentTimeMillis() + "}"; + + assertFalse( + JSONValidator.from(body) + .validate()); + + assertTrue( + JSONValidator.from(body) + .setSupportMultiValue(true) + .validate()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3465.java b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3465.java new file mode 100644 index 0000000000..1e1ad6a986 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3465.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.issue_3400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue3465 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject jsonObj1 = new JSONObject(); + JSONObject sonJsonObj1 = new JSONObject(); + sonJsonObj1.put("dca0898f74b4cc6d0174b4cc77fd0005", "2ca0898f74b4cc6d0174b4cc77fd0005"); + jsonObj1.put("issue", sonJsonObj1); + String rst1 = JSON.toJSONString(jsonObj1, JSON.DEFAULT_GENERATE_FEATURE | SerializerFeature.WRITE_MAP_NULL_FEATURES); + System.out.println(rst1); + JSONObject parse1 = JSON.parseObject(rst1); + System.out.println(parse1.toJSONString()); + + + JSONObject jsonObj = new JSONObject(); + JSONObject sonJsonObj = new JSONObject(); + sonJsonObj.put("2ca0898f74b4cc6d0174b4cc77fd0005", "2ca0898f74b4cc6d0174b4cc77fd0005"); + jsonObj.put("issue", sonJsonObj); + String rst = JSON.toJSONString(jsonObj, JSON.DEFAULT_GENERATE_FEATURE | SerializerFeature.WRITE_MAP_NULL_FEATURES); + System.out.println(rst); + JSONObject parse = JSON.parseObject(rst); + System.out.println(parse.toJSONString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3470.java b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3470.java new file mode 100644 index 0000000000..614b40a242 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue3470.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.issue_3400; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue3470 extends TestCase { + public void test_for_issue() throws Exception { + String str = JSON.toJSONString(new Privacy().setPassword("test")); + assertEquals("{\"__password\":\"test\"}", str); + } + + public static class Privacy { + private String phone; //手机 + private String password; //登录密码,隐藏字段 + + public Privacy() { + super(); + } + + public String getPhone() { + return phone; + } + public Privacy setPhone(String phone) { + this.phone = phone; + return this; + } + + public String get__password() { + return password; + } + public Privacy setPassword(String password) { + this.password = password; + return this; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3400/Issue_20201016_01.java b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue_20201016_01.java new file mode 100644 index 0000000000..c7d9eb8e7c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3400/Issue_20201016_01.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt.issue_3400; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue_20201016_01 extends TestCase { + public void testToString() { + UserConfig user = new UserConfig(); + user.setAccount("account"); + user.setName("name"); + + Config config = new Config(); + config.setCreator(user); + config.setOwner(user); + + String s = JSON.toJSONString(config, SerializerFeature.WriteMapNullValue, + SerializerFeature.QuoteFieldNames, SerializerFeature.WriteNullListAsEmpty); + + System.out.println(s); + } + + + public void testFastJson() { + String s = "{\"agent\":null,\"creator\":{\"account\":\"account\",\"name\":\"name\",\"workid\":null},\"owner\":{\"$ref\":\"$.creator\"}}"; + + System.out.println( JSON.parseObject(s, Config.class)); + } + + public static class Config { + private UserConfig creator; + private UserConfig owner; + private UserConfig agent; + + public UserConfig getCreator() { + return creator; + } + public void setCreator(UserConfig creator) { + this.creator = creator; + } + public UserConfig getOwner() { + return owner; + } + public void setOwner(UserConfig owner) { + this.owner = owner; + } + public UserConfig getAgent() { + return agent; + } + public void setAgent(UserConfig agent) { + this.agent = agent; + } + } + + public static class UserConfig { + private String workid; + private String name; + private String account; + + public String getWorkid() { + return workid; + } + public void setWorkid(String workid) { + this.workid = workid; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getAccount() { + return account; + } + public void setAccount(String account) { + this.account = account; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3516.java b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3516.java new file mode 100644 index 0000000000..e12044c324 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3516.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt.issue_3500; + +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +public class Issue3516 extends TestCase { + public void test_for_issue() throws Exception { + JSONValidator validator = JSONValidator.from("{}"); + assertEquals(JSONValidator.Type.Object, validator.getType()); + assertTrue(validator.validate()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3539.java b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3539.java new file mode 100644 index 0000000000..ac8ee4a6c9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3539.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.issue_3500; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.time.Instant; + +public class Issue3539 extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\"date\":{\"nano\":140000000,\"epochSecond\":1605106869}}"; + Bean bean = JSON.parseObject(str, Bean.class); + assertNotNull(bean.date); + JSON.toJSONString(bean); + + JSON.parseObject(str) + .toJavaObject(Bean.class); + } + + public void test_for_issue_joda() throws Exception { + String str = "{\"date\":{\"epochSecond\":1605106869}}"; + JodaBean bean = JSON.parseObject(str, JodaBean.class); + assertNotNull(bean.date); + JSON.toJSONString(bean); + + JSON.parseObject(str) + .toJavaObject(JodaBean.class); + } + + public void test_for_issue_joda2() throws Exception { + String str = "{\"date\":{\"millis\":1605364826724}}"; + JodaBean bean = JSON.parseObject(str, JodaBean.class); + assertNotNull(bean.date); + JSON.toJSONString(bean); + + JSON.parseObject(str) + .toJavaObject(JodaBean.class); + } + + public static class Bean { + public Instant date; + } + + public static class JodaBean { + public org.joda.time.Instant date; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3544.java b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3544.java new file mode 100644 index 0000000000..65a818e17f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3544.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.issue_3500; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; + +public class Issue3544 extends TestCase { + + public void test_errorType() { + assertNull("", JSON.toJavaObject( + JSON.parseObject("{\"result\":\"\"}"), TestVO.class).result); + + assertNull("", JSON.toJavaObject( + JSON.parseObject("{\"result\":\"null\"}"), TestVO.class).result); + } + + @Getter + @Setter + static class TestVO { + + Map result; + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3571.java b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3571.java new file mode 100644 index 0000000000..5e3b8fe8f5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3571.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.issue_3500; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class Issue3571 extends TestCase { + public void test_for_issue() throws Exception { + Bean1 bean = new Bean1(); + bean.id1 = 101; + bean.id2 = 102; + bean.id3 = 103; + + assertEquals("{\"id1\":101,\"id2\":102,\"id3\":103}", JSON.toJSON(bean).toString()); + } + + public void test_for_issue_2() throws Exception { + Bean2 bean = new Bean2(); + bean.id1 = 101; + bean.id2 = 102; + bean.id3 = 103; + + assertEquals("{\"id1\":101,\"id2\":102,\"id3\":103}", JSON.toJSON(bean).toString()); + } + + @JSONType(serialzeFeatures = SerializerFeature.SortField) + public static class Bean1 { + public int id2; + public int id1; + public int id3; + } + + @JSONType(serialzeFeatures = SerializerFeature.MapSortField) + public static class Bean2 { + public int id2; + public int id1; + public int id3; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3579.java b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3579.java new file mode 100644 index 0000000000..8f5a3b0d81 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3500/Issue3579.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.issue_3500; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.math.BigDecimal; + +public class Issue3579 extends TestCase { + public void test_for_issue() throws Exception { + assertEquals("1", + JSON.toJSONString(new BigDecimal("1")) + ); + + assertEquals("1.", + JSON.toJSONString(new BigDecimal("1"), SerializerFeature.WriteClassName) + ); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3614.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3614.java new file mode 100644 index 0000000000..cdded5b5e9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3614.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +import java.io.ByteArrayOutputStream; +import java.io.*; +import java.util.Collections; +import java.util.zip.GZIPOutputStream; + +public class Issue3614 extends TestCase { + public void test_for_issue() throws Exception { + byte[] gzipBytes = gzip(JSON.toJSONString(Collections.singletonMap("key", "value")).getBytes()); + + Object o = JSON.parseObject(gzipBytes, JSONObject.class); + assertEquals("{\"key\":\"value\"}", JSON.toJSONString(o)); + } + + private static byte[] gzip(byte[] source) throws IOException { + if (source == null) return null; + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + GZIPOutputStream gzip = new GZIPOutputStream(bos); + gzip.write(source); + gzip.finish(); + byte[] bytes = bos.toByteArray(); + gzip.close(); + return bytes; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3628.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3628.java new file mode 100644 index 0000000000..1ff51aaac5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3628.java @@ -0,0 +1,11 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Issue3628 extends TestCase { + public void test_for_issue() throws Exception { + String json = "{\"admin\":3483706632,\"admins\":[],\"black\":{\"blackList\":[]},\"enable\":true,\"messages\":{\"adminChangeDown\":\"[mirai:at:%target%] 被撤销了管理~\",\"adminChangeUp\":\"恭喜 [mirai:at:%target%] 被升为管理员~\",\"blacelist\":\"[mirai:at:%target%]你被加入此群黑名单,不允许你进入本群\",\"clearnScreen\":\"清屏ing~~~\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n清屏完毕~~~\",\"join\":\"欢迎 [mirai:at:%target%] 进入本群~\",\"kick\":\"[mirai:at:%target%] 被 [mirai:at:%operator%] 踢出本群\",\"leave\":\"很遗憾, [mirai:at:%target%] 离开了本群\",\"mute\":\"[mirai:at:%target%] 被 [mirai:at:%operator%] 禁言 %time%\",\"talkative\":\"恭喜 [mirai:at:%target%] 成为本群龙王!\",\"title\":\"恭喜 [mirai:at:%target%] 获得群主授予的 %title% 头衔!\",\"unmute\":\"[mirai:at:%target%] 被 [mirai:at:%operator%] 解除禁言\",\"warn\":\"\"},\"requestConfig\":{\"keyWordRegex\":\"SINGLE\",\"keyWords\":[\"栗子\"],\"type\":\"PASS\"},\"select\":{\"adminChange\":true,\"autoParseRequest\":true,\"join\":true,\"kick\":true,\"leave\":true,\"mute\":true,\"talkative\":true,\"title\":true,\"unmute\":true},\"warn\":{\"count\":10,\"countBlack\":30,\"warnList\":[{\"count\":-9999,\"id\":123456}]}}"; + JSON.parse(json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3629.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3629.java new file mode 100644 index 0000000000..224a778b46 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3629.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSONPath; +import java.util.List; +import junit.framework.TestCase; + +public class Issue3629 extends TestCase { + public void test_for_issue() throws Exception { + String text1 = "[\n" + + " {\n" + + " \"author\": \"Nigel Rees\",\n" + + " \"category\": \"reference\",\n" + + " \"price\": 8.95,\n" + + " \"title\": \"Sayings of the Century\"\n" + + " },\n" + + " {\n" + + " \"author\": \"Evelyn Waugh\",\n" + + " \"category\": \"fiction\",\n" + + " \"price\": 12.99,\n" + + " \"title\": \"Sword of Honour\"\n" + + " },\n" + + " {\n" + + " \"author\": \"Herman Melville\",\n" + + " \"category\": \"fiction\",\n" + + " \"isbn\": \"0-553-21311-3\",\n" + + " \"price\": 8.99,\n" + + " \"title\": \"Moby Dick\"\n" + + " },\n" + + " {\n" + + " \"author\": \"J. R. R. Tolkien\",\n" + + " \"category\": \"fiction\",\n" + + " \"isbn\": \"0-395-19395-8\",\n" + + " \"price\": 22.99,\n" + + " \"title\": \"The Lord of the Rings\"\n" + + " }\n" + + "]"; + + + List extract = (List) JSONPath.extract(text1, "$..[?(@.price < 10)]"); + assertEquals(2, extract.size()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3631.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3631.java new file mode 100644 index 0000000000..0baaf22ea9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3631.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import junit.framework.TestCase; + +import java.util.Base64; + +public class Issue3631 extends TestCase { + public void test_issue_1() throws Exception { + try { + JSON.parse("{[-"); + } catch (JSONException unused) { + // skip + } + } + + public void test_issue_2() throws Exception { + try { + JSON.parse("TreeSet[[]"); + } catch (JSONException unused) { + // skip + } + } + + public void test_issue_3() throws Exception { + try { + JSON.parse(btoa("WywsIiIMLCIAAAAMAAAgAAAAdWUgdAAAAA1ubHUlbDMyMjIABAAAADIyMjISMjNbW1ukHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHiBUZA17W3tbCTg0DQooIHRleHQuIEFuZCAgNDRUBDQ0LCwoLCwsLCwsKSwsLCwsLCwsLCwsLCwsnf8sLCwsLCwsMiwsLG51bA9sLCwqLCwsLCwsLCwsLCwsLCwsLCwoLCwsLCwsKSx077+9LCwsLBAsLCwsLCwoLCwsLCwsKSx077+9LCwsLCwyLCwsLCwsLCwsLFtbW1uhpJ3/GiwsLCwsLDIsLCwsLCwsQSw8LCwsLHtbW1sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHtbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHsnw4QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWw1dLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW10AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW6Gknf8sLCwsLCwsLCwsLCwsWywsLCwsLCwsLCwsLCwsLCwsKCwsLCwsLCksLCwsLCwsLCwsLCwsLJ3/LCwsLCwsLDIsLCxudWxsLCwqLCwsLCwsLCwsLCwsLCwsLCwoLCwsLCwsKSx077+9LCwsLCwsLCwsLCwoLCwsLCwsKSx07zV1bmRlZmluZW5kACwsLCwsLFtbW1uhpJ3/GiwsLCwsLDIsLCwsLCwsQSw8LCwsLHtbW1tboaSd/ywsLCwsLCwsLCwsLCxbLCwsLCwsLCwsLCwsLCwsLCwsLEEsPCwsLCx7W1tbW6Gknf8sLCwsLCwsLCwsLCwsLCwsLCgsLCwsLCwpLCwsLCwsLCwsLCwsLCyd/ywsLCwsLCwyLCwsbnVsbCwsKiwsLCwsLCwsLCwsLCwsLCwsKCwsLCwsLCksdO+/vSwsLCwsMSwsLCwsLCwsLCxbW1tboaSd/xosLCwsLCwyLCwsLCwsLCwsLCws")); + } catch (JSONException unused) { + // skip + } + } + + public static String btoa(String base64) { + return new String(Base64.getDecoder().decode(base64)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3637.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3637.java new file mode 100644 index 0000000000..e608c73fa1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3637.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; + +import java.sql.Timestamp; + +public class Issue3637 extends TestCase { + public void test_for_issue() throws Exception { +// java.sql.Time.valueOf("01:00:00"); + JSON.parseObject("\"01:00:00\"", java.sql.Time.class); + TypeUtils.castToJavaBean("01:00:00", java.sql.Time.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3652.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3652.java new file mode 100644 index 0000000000..1d2e86ad46 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3652.java @@ -0,0 +1,89 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.PropertyNamingStrategy; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializeConfig; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.junit.Assert; +import org.junit.Test; + +public class Issue3652 { + + @Test + public void test_SerializeConfig_different_Class_Annotation() { + Object[] models = new Object[]{ + new Model1("hello,world"), + new Model2("hello,world"), + new Model3("hello,world"), + new Model4("hello,world"), + }; + for (int i = 0; i < 4; i++) { + String[] toStrings = new String[PropertyNamingStrategy.values().length]; + for (int j = 0; j < toStrings.length; j++) { + SerializeConfig config = new SerializeConfig(); + config.propertyNamingStrategy = PropertyNamingStrategy.values()[j]; + toStrings[j] = JSON.toJSONString(models[i], config); + } + for (int j = 1; j < toStrings.length; j++) { + Assert.assertEquals(toStrings[j], toStrings[j - 1]); + System.out.println(toStrings[j - 1]); + } + } + } + + @Test + public void test_different_Class_Annotation() { + Object[] models = new Object[]{ + new Model1("hello,world"), + new Model2("hello,world"), + new Model3("hello,world"), + new Model4("hello,world"), + }; + String[] JsonStrings = new String[]{ + "{\"goodBoy\":\"hello,world\"}", + "{\"GoodBoy\":\"hello,world\"}", + "{\"good_boy\":\"hello,world\"}", + "{\"good-boy\":\"hello,world\"}"}; + /* PS: Order is + CamelCase, + PascalCase, + SnakeCase, + KebabCase,*/ + for (int i = 0; i < models.length; i++) { + String[] toStrings = new String[PropertyNamingStrategy.values().length]; + toStrings[i] = JSON.toJSONString(models[i]); + Assert.assertEquals(JsonStrings[i], toStrings[i]); + } + } + + @JSONType(naming = PropertyNamingStrategy.CamelCase) + @Data + @AllArgsConstructor + public class Model1 { + private String goodBoy; + } + + @JSONType(naming = PropertyNamingStrategy.PascalCase) + @Data + @AllArgsConstructor + public class Model2 { + private String goodBoy; + } + + @JSONType(naming = PropertyNamingStrategy.SnakeCase) + @Data + @AllArgsConstructor + public class Model3 { + private String goodBoy; + } + + @JSONType(naming = PropertyNamingStrategy.KebabCase) + @Data + @AllArgsConstructor + public class Model4 { + private String goodBoy; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3655.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3655.java new file mode 100644 index 0000000000..6c888e1535 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3655.java @@ -0,0 +1,164 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.junit.Assert; +import org.junit.Test; + +public class Issue3655 { + private final static String jsonStr = + "{\"data\":\"\",\"data2\":\"\",\"data3\":\"\",\"data4\":\"\",\"data5\":\"\",\"data6\":\"\",\"data7\":\"\",\"data8\":\"\",\"data9\":\"\"}"; + + @Test + public void test_inherit_from_abstract_class_1() { + issue3655_b b = new issue3655_b(null, null, null, null, null, null, null, null, null); + String result = JSON.toJSONString(b, SerializerFeature.WriteNullStringAsEmpty); + System.out.println(result); + Assert.assertEquals(jsonStr, result); + } + + @Test + public void test_inherit_from_abstract_class_2() { + issue3655_c c = new issue3655_c(null, null, null, null, null, null, null, null, null); + String result = JSON.toJSONString(c, SerializerFeature.WriteNullStringAsEmpty); + System.out.println(result); + Assert.assertEquals(jsonStr, result); + } + + public static class issue3655_b extends issue3655_a { + private String data; + private String data2; + private String data3; + private String data4; + private String data5; + private String data6; + private String data7; + private String data8; + private String data9; + + public String getData() { + return data; + } + + public String getData2() { + return data2; + } + + public String getData3() { + return data3; + } + + public String getData4() { + return data4; + } + + public String getData5() { + return data5; + } + + public String getData6() { + return data6; + } + + public String getData7() { + return data7; + } + + public String getData8() { + return data8; + } + + public String getData9() { + return data9; + } + + public void setData(String data) { + this.data = data; + } + + public void setData2(String data2) { + this.data2 = data2; + } + + public void setData3(String data3) { + this.data3 = data3; + } + + public void setData4(String data4) { + this.data4 = data4; + } + + public void setData5(String data5) { + this.data5 = data5; + } + + public void setData6(String data6) { + this.data6 = data6; + } + + public void setData7(String data7) { + this.data7 = data7; + } + + public void setData8(String data8) { + this.data8 = data8; + } + + public void setData9(String data9) { + this.data9 = data9; + } + + public issue3655_b( + String data, String data2, String data3, String data4, String data5, + String data6, String data7, String data8, String data9) { + this.data = data; + this.data2 = data2; + this.data3 = data3; + this.data4 = data4; + this.data5 = data5; + this.data6 = data6; + this.data7 = data7; + this.data8 = data8; + this.data9 = data9; + } + } + + @Getter + @Setter + @AllArgsConstructor + public static class issue3655_c extends issue3655_a { + private String data; + private String data2; + private String data3; + private String data4; + private String data5; + private String data6; + private String data7; + private String data8; + private String data9; + } + + public static abstract class issue3655_a { + public abstract Object getData(); + + public abstract Object getData2(); + + public abstract Object getData3(); + + public abstract Object getData4(); + + public abstract Object getData5(); + + public abstract Object getData6(); + + public abstract Object getData7(); + + public abstract Object getData8(); + + public abstract Object getData9(); + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3671.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3671.java new file mode 100644 index 0000000000..00c997b7d3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3671.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONValidator; +import junit.framework.TestCase; + +public class Issue3671 extends TestCase { + public void test_for_issue() throws Exception { + String json = "[{\n" + + " \"filters\": [],\n" + + " \"id\": \"baidu_route2\",\n" + + " \"order\": 0,\n" + + " \"predicates\": [{\n" + + " \"args\": {\n" + + " \"pattern\": \"/baidu/**\"\n" + + " },\n" + + " \"name\": \"Path\"\n" + + " }],\n" + + " \"uri\": \"https://www.baidu.com\"\n" + + "}]\n"; + assertTrue(JSONValidator.from(json).validate()); + assertTrue(JSON.isValid(json)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3672.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3672.java new file mode 100644 index 0000000000..8a4d2685f5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3672.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.google.common.collect.Lists; +import lombok.Data; +import org.junit.Test; + +import java.util.ArrayList; + +import junit.framework.TestCase; + +public class Issue3672 extends TestCase { + public void test_for_issue() throws Exception { + Issue3672Root root = new Issue3672Root(); + Issue3672A a = new Issue3672A(); + Issue3672B b = new Issue3672B(); + Issue3672C c = new Issue3672C(); + Issue3672D d = new Issue3672D(); + root.setA(a); + a.setB(Lists.newArrayList(b).toArray()); + b.setC(c); + c.setD(d); + d.setE(Lists.newArrayList(c)); + String str1 = JSON.toJSONString(root, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue); + String str2 = JSON.toJSONString(root); + + JSONObject obj1 = JSON.parseObject(str1); + JSONObject obj2 = JSON.parseObject(str2); + assertEquals(obj1.toString(), obj2.toString()); + } + + @Data + private class Issue3672Root { + private Issue3672A a; + } + + @Data + private class Issue3672A { + private Object[] b; + } + + @Data + private class Issue3672B { + private Issue3672C c; + } + + @Data + private class Issue3672C { + private Issue3672D d; + } + + @Data + private class Issue3672D { + private ArrayList e; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3682.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3682.java new file mode 100644 index 0000000000..224cfa09be --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3682.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import lombok.Data; + +public class Issue3682 extends TestCase { + public void test_for_issue() throws Exception { + Cid cid = JSON.parseObject(SOURCE, Cid.class); + System.out.println(cid); + } + + @Data + static public class Cid { + + @JSONField(name = "/") + private String hash; + + } + + static final String SOURCE = "{\n" + + " \"jsonrpc\": \"2.0\",\n" + + " \"result\": {\n" + + " \"Version\": 0,\n" + + " \"To\": \"t1iceld4fv44xgjqfcx5lwz45pubheu3c7c2nmlua\",\n" + + " \"From\": \"t152xual7ze57jnnioucuv4lmtxarewtzhkqojboy\",\n" + + " \"Nonce\": 4,\n" + + " \"Value\": \"9999999938462317355\",\n" + + " \"GasLimit\": 609960,\n" + + " \"GasFeeCap\": \"101083\",\n" + + " \"GasPremium\": \"100029\",\n" + + " \"Method\": 0,\n" + + " \"Params\": null,\n" + + " \"CID\": {\n" + + " \"/\": \"bafy2bzacedgpr5pmkvu4rkq26uv4hidpfrn3gdvtgkp3hpxss3bgmodrgqtk6\"\n" + + " }\n" + + " },\n" + + " \"id\": 1\n" + + "}"; +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3689.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3689.java new file mode 100644 index 0000000000..befea78d12 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3689.java @@ -0,0 +1,90 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONException; +import org.junit.Test; + +public class Issue3689 { + + @Test(expected = JSONException.class) + public void test_without_type_0_meaningles_char() { + JSONArray.parseArray("dfdfdf"); + } + + @Test(expected = JSONException.class) + public void test_without_type_1_meaningles_char() { + JSONArray.parseArray("/dfdfdf"); + } + + @Test(expected = JSONException.class) + public void test_without_type_2_meaningles_char() { + JSONArray.parseArray("//dfdfdf"); + } + + @Test(expected = JSONException.class) + public void test_without_type_3_meaningles_char() { + JSONArray.parseArray("///dfdfdf"); + } + + @Test(expected = JSONException.class) + public void test_without_type_4_meaningles_char() { + JSONArray.parseArray("////dfdfdf"); + } + + @Test(expected = JSONException.class) + public void test_without_type_5_meaningles_char() { + JSONArray.parseArray("/////dfdfdf"); + } + + @Test(expected = JSONException.class) + public void test_without_type_6_meaningles_char() { + JSONArray.parseArray("//////dfdfdf"); + } + + @Test(expected = JSONException.class) + public void test_with_type_0_meaningles_char() { + JSONArray.parseArray("dfdfdf", String.class); + } + + @Test(expected = JSONException.class) + public void test_with_type_1_meaningles_char() { + JSONArray.parseArray("/dfdfdf", String.class); + } + + @Test(expected = JSONException.class) + public void test_with_type_2_meaningles_char() { + JSONArray.parseArray("//dfdfdf", String.class); + + } + + @Test(expected = JSONException.class) + public void test_with_type_3_meaningles_char() { + JSONArray.parseArray("///dfdfdf", String.class); + + } + + @Test(expected = JSONException.class) + public void test_with_type_4_meaningles_char() { + JSONArray.parseArray("////dfdfdf", String.class); + + } + + @Test(expected = JSONException.class) + public void test_with_type_5_meaningles_char() { + JSONArray.parseArray("/////dfdfdf", String.class); + + } + + @Test(expected = JSONException.class) + public void test_with_type_6_meaningles_char() { + JSONArray.parseArray("//////dfdfdf", String.class); + } + + @Test + public void test_for_issue() { + JSONArray.parseArray("[\"////dfdfdf\"]"); //不会抛异常 + JSONArray objects = JSONArray.parseArray("[\"dfdfdf\"]");//不会抛异常 + System.out.println(JSONArray.parseArray("[\"////dfdfdf\"]")); + System.out.println(JSONArray.parseArray("[\"dfdfdf\"]")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3693.java b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3693.java new file mode 100644 index 0000000000..195129a425 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3600/Issue3693.java @@ -0,0 +1,109 @@ +package com.alibaba.json.bvt.issue_3600; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import junit.framework.TestCase; + +import java.lang.reflect.Type; + +public class Issue3693 extends TestCase { + + public void test_for_issue() throws Exception { + Model model = new Model("hello 世界", new ModelProperties("红色", 66)); + String json = JSON.toJSONString(model); + assertEquals("{\"name\":\"hello 世界\",\"properties\":\"{\\\"color\\\":\\\"红色\\\",\\\"size\\\":66}\"}", json); + + Model deserializedModel = JSON.parseObject(json, new TypeReference>() { + }); + assertNotNull(deserializedModel); + assertEquals("hello 世界", deserializedModel.getName()); + assertNotNull(deserializedModel.getProperties()); + assertEquals("红色", deserializedModel.getProperties().getColor()); + assertEquals(66, deserializedModel.getProperties().getSize()); + } + + + static class Model { + private String name; + @JSONField(serializeUsing = MyCodec.class, deserializeUsing = MyCodec.class) + private T properties; + + Model() { + } + + Model(String name, T properties) { + this.name = name; + this.properties = properties; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public T getProperties() { + return this.properties; + } + + public void setProperties(T properties) { + this.properties = properties; + } + } + + + static class ModelProperties { + private String color; + private int size; + + ModelProperties() { + } + + ModelProperties(String color, int size) { + this.color = color; + this.size = size; + } + + public String getColor() { + return this.color; + } + + public void setColor(String color) { + this.color = color; + } + + public int getSize() { + return this.size; + } + + public void setSize(int size) { + this.size = size; + } + } + + + public static class MyCodec implements ObjectSerializer, ObjectDeserializer { + @Override + public int getFastMatchToken() { + return 0; + } + + @Override + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) { + serializer.write(JSON.toJSONString(object)); + } + + @Override + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + String json = parser.parseObject(String.class); + return JSON.parseObject(json, type); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/issue_3800/Issue3810.java b/src/test/java/com/alibaba/json/bvt/issue_3800/Issue3810.java new file mode 100644 index 0000000000..1662694338 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_3800/Issue3810.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.issue_3800; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.util.ParameterizedTypeImpl; +import junit.framework.TestCase; +import lombok.Data; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * https://github.com/alibaba/fastjson/issues/3810 + * + * @author hnyyghk + * @date 2021/06/30 18:40 + */ +public class Issue3810 extends TestCase { + @Data + static class TestA { + T a; + } + + @Data + static class TestB { + String b; + } + + private final static String json = "{\"a\":[{\"b\":\"b\"}]}"; + + public void test_for_issue() throws Exception { + ParameterizedTypeImpl inner = new ParameterizedTypeImpl(new Type[]{TestB.class}, List.class, List.class); + ParameterizedTypeImpl outer = new ParameterizedTypeImpl(new Type[]{inner}, TestA.class, TestA.class); + JSONObject jo = JSONObject.parseObject(json); + TestA> ret = jo.toJavaObject(outer); + + assertEquals(ArrayList.class.getName(), ret.getA().getClass().getName()); + assertEquals(TestB.class.getName(), ret.getA().get(0).getClass().getName()); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTest.java index f03054594c..222e5ba734 100644 --- a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTest.java +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTest.java @@ -1,6 +1,8 @@ package com.alibaba.json.bvt.jdk8; import java.time.LocalDate; +import java.util.Locale; +import java.util.TimeZone; import junit.framework.TestCase; @@ -9,6 +11,10 @@ import com.alibaba.fastjson.JSON; public class LocalDateTest extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } public void test_for_issue() throws Exception { VO vo = new VO(); @@ -21,6 +27,18 @@ public void test_for_issue() throws Exception { Assert.assertEquals(vo.getDate(), vo1.getDate()); } + /** + * 方法描述: 测试时间戳转换为 日期 + * @author wuqiong 2017/11/21 16:48 + */ + public void test_for_long() throws Exception { + String text= "{\"date\":1511248447740}"; + VO vo =JSON.parseObject(text,VO.class); + Assert.assertEquals(2017, vo.date.getYear()); + Assert.assertEquals(11, vo.date.getMonthValue()); + Assert.assertEquals(21, vo.date.getDayOfMonth()); + } + public static class VO { private LocalDate date; diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest.java index 3b0c309129..955223dfa1 100644 --- a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest.java +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest.java @@ -2,6 +2,7 @@ import java.time.LocalDateTime; +import com.alibaba.fastjson.serializer.SerializerFeature; import org.junit.Assert; import com.alibaba.fastjson.JSON; @@ -18,7 +19,44 @@ public void test_for_issue() throws Exception { VO vo1 = JSON.parseObject(text, VO.class); - Assert.assertEquals(vo.getDate(), vo1.getDate()); + Assert.assertEquals(JSON.toJSONString(vo.getDate()), JSON.toJSONString(vo1.getDate())); + } + + /** + * 方法描述: 测试LocalDateTime 转化时间戳等 操作 + * 问题点1、 LocalDateTime 进来的值无法确定其时区,所以此处统一按着系统时区走。 + * 问题点2、 如果设置 SerializerFeature.WriteDateUseDateFormat 时按着 "yyyy-MM-dd HH:mm:ss" 进行格式化 + * 问题点3: 如果设置 SerializerFeature.UseISO8601DateFormat 时按着ISO8601的标准 "yyyy-MM-dd'T'HH:mm:ss"进行格式化 + * 问题点4: + * 1)格式化LocalDateTime时, 默认格式成 时间戳格式, + * 2)如设置WriteDateUseDateFormat 按 "yyyy-MM-dd HH:mm:ss" 进行格式化 + * 3)如设置UseISO8601DateFormat 按ISO8601的标准 "yyyy-MM-dd'T'HH:mm:ss"进行格式化 + * 4)如设置WriteDateUseDateFormat、UseISO8601DateFormat 同时设置,则按ISO8601的标准 "yyyy-MM-dd'T'HH:mm:ss"进行格式化 + * @author wuqiong 2017/11/22 15:08 + */ + public void test_toJsonString_ofLong()throws Exception { + VO vo = new VO(); + vo.setDate(LocalDateTime.now()); + + VO vo1 = JSON.parseObject("{\"date\":1511334591189}", VO.class); + + String text2 = JSON.toJSONString(vo, SerializerFeature.WriteDateUseDateFormat); + System.out.println(text2);//{"date":"2017-11-22 15:09:51"} + VO vo2 = JSON.parseObject(text2, VO.class); + + String text3 = JSON.toJSONString(vo, SerializerFeature.UseISO8601DateFormat); + System.out.println(text3);//{"date":"2017-11-22T15:09:51"} + VO vo3 = JSON.parseObject(text3, VO.class); + + String text4 = JSON.toJSONString(vo, SerializerFeature.UseISO8601DateFormat, SerializerFeature.WriteDateUseDateFormat); + System.out.println(text4);//{"date":"2017-11-22T15:09:51"} + VO vo4 = JSON.parseObject(text4, VO.class); + } + + public void test_for_issue_1() throws Exception { + String text = "{\"date\":\"2018-08-03 22:38:33.145\"}"; + VO vo1 = JSON.parseObject(text, VO.class); + assertNotNull(vo1.date); } public static class VO { diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest4.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest4.java index 19158ea59b..4c6aab0059 100644 --- a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest4.java +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest4.java @@ -16,7 +16,7 @@ public void test_for_issue() throws Exception { vo.setDate(dateTime); String text = JSON.toJSONString(vo); - Assert.assertEquals("{\"date\":\"2016-05-06 09:03:16\"}", text); + Assert.assertEquals("{\"date\":\"2016-05-06T09:03:16\"}", text); VO vo1 = JSON.parseObject(text, VO.class); diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest5.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest5.java index f029f52093..ca3c5a08be 100644 --- a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest5.java +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest5.java @@ -1,9 +1,10 @@ package com.alibaba.json.bvt.jdk8; +import java.time.Instant; import java.time.LocalDateTime; import java.util.Locale; - -import org.junit.Assert; +import java.util.Random; +import java.util.TimeZone; import com.alibaba.fastjson.JSON; @@ -11,153 +12,169 @@ public class LocalDateTimeTest5 extends TestCase { + private static Random random = new Random(); + private Locale origin; + private TimeZone original = TimeZone.getDefault(); + private String[] zoneIds = TimeZone.getAvailableIDs(); + @Override protected void setUp() throws Exception { + int index = random.nextInt(zoneIds.length); + TimeZone timeZone = TimeZone.getTimeZone(zoneIds[index]); + TimeZone.setDefault(timeZone); + JSON.defaultTimeZone = timeZone; // While running mvn tests defaultTimeZone might already be initialized origin = Locale.getDefault(); } + @Override protected void tearDown() throws Exception { + TimeZone.setDefault(original); + JSON.defaultTimeZone = original; Locale.setDefault(origin); } public void test_for_long() throws Exception { - VO vo = JSON.parseObject("{\"date\":1322874196000}", VO.class); - - Assert.assertEquals(2011, vo.date.getYear()); - Assert.assertEquals(12, vo.date.getMonthValue()); - Assert.assertEquals(3, vo.date.getDayOfMonth()); -// Assert.assertEquals(9, vo.date.getHour()); - Assert.assertEquals(3, vo.date.getMinute()); - Assert.assertEquals(16, vo.date.getSecond()); - Assert.assertEquals(0, vo.date.getNano()); + long millis = 1322874196000L; + // using localDataTime instance so that different timeZones are tested + LocalDateTime localDateTime = LocalDateTime.ofInstant( + Instant.ofEpochMilli(millis), TimeZone.getDefault().toZoneId()); + VO vo = JSON.parseObject("{\"date\":" + millis + "}", VO.class); + + assertEquals("Not Matching year", localDateTime.getYear(), vo.date.getYear()); + assertEquals("Not Matching month", localDateTime.getMonthValue(), vo.date.getMonthValue()); + assertEquals("Not Matching day", localDateTime.getDayOfMonth(), vo.date.getDayOfMonth()); + assertEquals("Not Matching hour", localDateTime.getHour(), vo.date.getHour()); + assertEquals("Not Matching minute", localDateTime.getMinute(), vo.date.getMinute()); + assertEquals("Not Matching second", localDateTime.getSecond(), vo.date.getSecond()); + assertEquals("Not Matching nano", localDateTime.getNano(), vo.date.getNano()); } public void test_for_normal() throws Exception { VO vo = JSON.parseObject("{\"date\":\"2011-12-03 09:03:16\"}", VO.class); - Assert.assertEquals(2011, vo.date.getYear()); - Assert.assertEquals(12, vo.date.getMonthValue()); - Assert.assertEquals(3, vo.date.getDayOfMonth()); - Assert.assertEquals(9, vo.date.getHour()); - Assert.assertEquals(3, vo.date.getMinute()); - Assert.assertEquals(16, vo.date.getSecond()); - Assert.assertEquals(0, vo.date.getNano()); + assertEquals(2011, vo.date.getYear()); + assertEquals(12, vo.date.getMonthValue()); + assertEquals(3, vo.date.getDayOfMonth()); + assertEquals(9, vo.date.getHour()); + assertEquals(3, vo.date.getMinute()); + assertEquals(16, vo.date.getSecond()); + assertEquals(0, vo.date.getNano()); } public void test_for_iso() throws Exception { VO vo = JSON.parseObject("{\"date\":\"2011-12-03T09:03:16\"}", VO.class); - Assert.assertEquals(2011, vo.date.getYear()); - Assert.assertEquals(12, vo.date.getMonthValue()); - Assert.assertEquals(3, vo.date.getDayOfMonth()); + assertEquals(2011, vo.date.getYear()); + assertEquals(12, vo.date.getMonthValue()); + assertEquals(3, vo.date.getDayOfMonth()); - Assert.assertEquals(9, vo.date.getHour()); - Assert.assertEquals(3, vo.date.getMinute()); - Assert.assertEquals(16, vo.date.getSecond()); - Assert.assertEquals(0, vo.date.getNano()); + assertEquals(9, vo.date.getHour()); + assertEquals(3, vo.date.getMinute()); + assertEquals(16, vo.date.getSecond()); + assertEquals(0, vo.date.getNano()); } public void test_for_tw() throws Exception { VO vo = JSON.parseObject("{\"date\":\"2016/05/06 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); } public void test_for_jp() throws Exception { VO vo = JSON.parseObject("{\"date\":\"2016年5月6日 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); } public void test_for_cn() throws Exception { VO vo = JSON.parseObject("{\"date\":\"2016年5月6日 9时3分16秒\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); } public void test_for_kr() throws Exception { VO vo = JSON.parseObject("{\"date\":\"2016년5월6일 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); } public void test_for_us() throws Exception { VO vo = JSON.parseObject("{\"date\":\"05/26/2016 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(26, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(26, vo.date.getDayOfMonth()); } public void test_for_eur() throws Exception { VO vo = JSON.parseObject("{\"date\":\"26/05/2016 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(26, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(26, vo.date.getDayOfMonth()); } public void test_for_us_1() throws Exception { Locale.setDefault(Locale.US); VO vo = JSON.parseObject("{\"date\":\"05/06/2016 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(06, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(06, vo.date.getDayOfMonth()); } public void test_for_br() throws Exception { Locale.setDefault(new Locale("pt", "BR")); VO vo = JSON.parseObject("{\"date\":\"06/05/2016 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); } public void test_for_au() throws Exception { Locale.setDefault(new Locale("en", "AU")); VO vo = JSON.parseObject("{\"date\":\"06/05/2016 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); } public void test_for_de() throws Exception { Locale.setDefault(new Locale("pt", "BR")); VO vo = JSON.parseObject("{\"date\":\"06.05.2016 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); - Assert.assertEquals(9, vo.date.getHour()); - Assert.assertEquals(3, vo.date.getMinute()); - Assert.assertEquals(16, vo.date.getSecond()); - Assert.assertEquals(0, vo.date.getNano()); + assertEquals(9, vo.date.getHour()); + assertEquals(3, vo.date.getMinute()); + assertEquals(16, vo.date.getSecond()); + assertEquals(0, vo.date.getNano()); } public void test_for_in() throws Exception { VO vo = JSON.parseObject("{\"date\":\"06-05-2016 09:03:16\"}", VO.class); - Assert.assertEquals(2016, vo.date.getYear()); - Assert.assertEquals(5, vo.date.getMonthValue()); - Assert.assertEquals(6, vo.date.getDayOfMonth()); + assertEquals(2016, vo.date.getYear()); + assertEquals(5, vo.date.getMonthValue()); + assertEquals(6, vo.date.getDayOfMonth()); - Assert.assertEquals(9, vo.date.getHour()); - Assert.assertEquals(3, vo.date.getMinute()); - Assert.assertEquals(16, vo.date.getSecond()); - Assert.assertEquals(0, vo.date.getNano()); + assertEquals(9, vo.date.getHour()); + assertEquals(3, vo.date.getMinute()); + assertEquals(16, vo.date.getSecond()); + assertEquals(0, vo.date.getNano()); } public static class VO { diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalTimeTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalTimeTest.java index 5e7ce3649b..f2feb8ee55 100644 --- a/src/test/java/com/alibaba/json/bvt/jdk8/LocalTimeTest.java +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalTimeTest.java @@ -1,6 +1,8 @@ package com.alibaba.json.bvt.jdk8; import java.time.LocalTime; +import java.util.Locale; +import java.util.TimeZone; import junit.framework.TestCase; @@ -9,6 +11,10 @@ import com.alibaba.fastjson.JSON; public class LocalTimeTest extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } public void test_for_issue() throws Exception { VO vo = new VO(); @@ -22,6 +28,18 @@ public void test_for_issue() throws Exception { Assert.assertEquals(vo.getDate(), vo1.getDate()); } + /** + * 方法描述: 测试时间戳转换为 时间 + * @author wuqiong 2017/11/21 16:48 + */ + public void test_for_long() throws Exception { + String text= "{\"date\":1511248447740}"; + VO vo =JSON.parseObject(text,VO.class); + Assert.assertEquals(15, vo.date.getHour()); + Assert.assertEquals(14, vo.date.getMinute()); + Assert.assertEquals(07, vo.date.getSecond()); + } + public static class VO { private LocalTime date; diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/OptionalTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/OptionalTest.java index c0e67a639b..105f6d1d6f 100644 --- a/src/test/java/com/alibaba/json/bvt/jdk8/OptionalTest.java +++ b/src/test/java/com/alibaba/json/bvt/jdk8/OptionalTest.java @@ -74,4 +74,14 @@ public void test_optionalDouble() throws Exception { OptionalDouble val2 = JSON.parseObject(text, OptionalDouble.class); Assert.assertEquals(Double.toString(val.getAsDouble()), Double.toString(val2.getAsDouble())); } + + public void test_optional_parseNull() throws Exception { + assertSame(Optional.empty() + , JSON.parseObject("null", Optional.class)); + } + + public void test_optional_parseNull_2() throws Exception { + assertSame(Optional.empty() + , JSON.parseObject("null", new TypeReference>() {})); + } } diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_0.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_0.java new file mode 100644 index 0000000000..9d6f22464f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_0.java @@ -0,0 +1,71 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvt.jdk8.LocalDateTest2; +import junit.framework.TestCase; +import org.junit.Assert; + +import org.joda.time.LocalDate; +import java.util.Locale; +import java.util.TimeZone; + +public class JodaTest_0 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(LocalDate.now()); + + String text = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public void test_for_issue_1() throws Exception { + VO vo = JSON.parseObject("{\"date\":\"2016-05-06T20:24:28.484\"}", VO.class); + + Assert.assertEquals(2016, vo.date.getYear()); + Assert.assertEquals(2016, vo.date.getYear()); + Assert.assertEquals(5, vo.date.getMonthOfYear()); + Assert.assertEquals(6, vo.date.getDayOfMonth()); + } + + public void test_for_issue_2() throws Exception { + VO vo = JSON.parseObject("{\"date\":\"20160506\"}", VO.class); + + Assert.assertEquals(2016, vo.date.getYear()); + Assert.assertEquals(5, vo.date.getMonthOfYear()); + Assert.assertEquals(6, vo.date.getDayOfMonth()); + } + + /** + * 方法描述: 测试时间戳转换为 日期 + * @author wuqiong 2017/11/21 16:48 + */ + public void test_for_long() throws Exception { + String text= "{\"date\":1511248447740}"; + VO vo =JSON.parseObject(text, VO.class); + Assert.assertEquals(2017, vo.date.getYear()); + Assert.assertEquals(11, vo.date.getMonthOfYear()); + Assert.assertEquals(21, vo.date.getDayOfMonth()); + } + + public static class VO { + + private LocalDate date; + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_1_LocalDateTime.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_1_LocalDateTime.java new file mode 100644 index 0000000000..83a39bfe67 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_1_LocalDateTime.java @@ -0,0 +1,73 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; +import org.junit.Assert; + +import org.joda.time.LocalDateTime; + +public class JodaTest_1_LocalDateTime extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(LocalDateTime.now()); + + String text = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(JSON.toJSONString(vo.getDate()), JSON.toJSONString(vo1.getDate())); + } + + /** + * 方法描述: 测试LocalDateTime 转化时间戳等 操作 + * 问题点1、 LocalDateTime 进来的值无法确定其时区,所以此处统一按着系统时区走。 + * 问题点2、 如果设置 SerializerFeature.WriteDateUseDateFormat 时按着 "yyyy-MM-dd HH:mm:ss" 进行格式化 + * 问题点3: 如果设置 SerializerFeature.UseISO8601DateFormat 时按着ISO8601的标准 "yyyy-MM-dd'T'HH:mm:ss"进行格式化 + * 问题点4: + * 1)格式化LocalDateTime时, 默认格式成 时间戳格式, + * 2)如设置WriteDateUseDateFormat 按 "yyyy-MM-dd HH:mm:ss" 进行格式化 + * 3)如设置UseISO8601DateFormat 按ISO8601的标准 "yyyy-MM-dd'T'HH:mm:ss"进行格式化 + * 4)如设置WriteDateUseDateFormat、UseISO8601DateFormat 同时设置,则按ISO8601的标准 "yyyy-MM-dd'T'HH:mm:ss"进行格式化 + * @author wuqiong 2017/11/22 15:08 + */ + public void test_toJsonString_ofLong()throws Exception { + VO vo = new VO(); + vo.setDate(LocalDateTime.now()); + + VO vo1 = JSON.parseObject("{\"date\":1511334591189}", VO.class); + + String text2 = JSON.toJSONString(vo, SerializerFeature.WriteDateUseDateFormat); + System.out.println(text2);//{"date":"2017-11-22 15:09:51"} + VO vo2 = JSON.parseObject(text2, VO.class); + + String text3 = JSON.toJSONString(vo, SerializerFeature.UseISO8601DateFormat); + System.out.println(text3);//{"date":"2017-11-22T15:09:51"} + VO vo3 = JSON.parseObject(text3, VO.class); + + String text4 = JSON.toJSONString(vo, SerializerFeature.UseISO8601DateFormat, SerializerFeature.WriteDateUseDateFormat); + System.out.println(text4);//{"date":"2017-11-22T15:09:51"} + VO vo4 = JSON.parseObject(text4, VO.class); + } + + public void test_for_issue_1() throws Exception { + String text = "{\"date\":\"2018-08-03 22:38:33.145\"}"; + VO vo1 = JSON.parseObject(text, VO.class); + assertNotNull(vo1.date); + } + + public static class VO { + + private LocalDateTime date; + + public LocalDateTime getDate() { + return date; + } + + public void setDate(LocalDateTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_2_LocalDateTimeTest3_private.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_2_LocalDateTimeTest3_private.java new file mode 100644 index 0000000000..86551fd68e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_2_LocalDateTimeTest3_private.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Assert; + +import org.joda.time.LocalDateTime; + +public class JodaTest_2_LocalDateTimeTest3_private extends TestCase { + + public void test_for_issue() throws Exception { + String text = "{\"date\":\"20111203\"}"; + VO vo = JSON.parseObject(text, VO.class); + + assertEquals(2011, vo.date.getYear()); + assertEquals(12, vo.date.getMonthOfYear()); + assertEquals(03, vo.date.getDayOfMonth()); + assertEquals(0, vo.date.getHourOfDay()); + assertEquals(0, vo.date.getMinuteOfHour()); + assertEquals(0, vo.date.getSecondOfMinute()); + + assertEquals(text, JSON.toJSONString(vo)); + } + + private static class VO { + @JSONField(format="yyyyMMdd") + public LocalDateTime date; + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_3_LocalTimeTest.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_3_LocalTimeTest.java new file mode 100644 index 0000000000..6f93420a42 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_3_LocalTimeTest.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.junit.Assert; + +import org.joda.time.LocalTime; +import java.util.Locale; +import java.util.TimeZone; + +public class JodaTest_3_LocalTimeTest extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(LocalTime.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + /** + * 方法描述: 测试时间戳转换为 时间 + * @author wuqiong 2017/11/21 16:48 + */ + public void test_for_long() throws Exception { + String text= "{\"date\":1511248447740}"; + VO vo =JSON.parseObject(text,VO.class); + Assert.assertEquals(15, vo.date.getHourOfDay()); + Assert.assertEquals(14, vo.date.getMinuteOfHour()); + Assert.assertEquals(07, vo.date.getSecondOfMinute()); + } + + public static class VO { + + private LocalTime date; + + public LocalTime getDate() { + return date; + } + + public void setDate(LocalTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_4_InstantTest.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_4_InstantTest.java new file mode 100644 index 0000000000..84116fd0b2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_4_InstantTest.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.junit.Assert; + +import org.joda.time.Instant; + +public class JodaTest_4_InstantTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(Instant.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private Instant date; + + public Instant getDate() { + return date; + } + + public void setDate(Instant date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_5_DateTimeFormatter.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_5_DateTimeFormatter.java new file mode 100644 index 0000000000..b53e2d1e51 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_5_DateTimeFormatter.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.joda.time.format.*; + +public class JodaTest_5_DateTimeFormatter extends TestCase { + public void test_for_joda_0() throws Exception { + + String json = "{\"formatter\":\"yyyyMMdd\"}"; + Model m = JSON.parseObject(json, Model.class); + + assertEquals(DateTimeFormat.forPattern("yyyyMMdd"), m.formatter); + } + + public static class Model { + public DateTimeFormatter formatter; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_6_Duration.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_6_Duration.java new file mode 100644 index 0000000000..3d6cf2f97c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_6_Duration.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.joda.time.Duration; +import org.joda.time.Period; + +public class JodaTest_6_Duration extends TestCase { + public void test_for_joda_0() throws Exception { + + Model m = new Model(); + m.duration = new Duration(24L*60L*60L*1000L); + + String json = JSON.toJSONString(m); + + assertEquals("{\"duration\":\"PT86400S\"}", json); + + Model m1 = JSON.parseObject(json, Model.class); + assertEquals(m.duration, m1.duration); + } + + public static class Model { + public Duration duration; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_6_Period.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_6_Period.java new file mode 100644 index 0000000000..8b80a75a95 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_6_Period.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.joda.time.Period; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +public class JodaTest_6_Period extends TestCase { + public void test_for_joda_0() throws Exception { + + Model m = new Model(); + m.period = Period.days(3); + + String json = JSON.toJSONString(m); + + assertEquals("{\"period\":\"P3D\"}", json); + + Model m1 = JSON.parseObject(json, Model.class); + assertEquals(m.period, m1.period); + } + + public static class Model { + public Period period; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_7_DateTimeZone.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_7_DateTimeZone.java new file mode 100644 index 0000000000..85d97e79b7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_7_DateTimeZone.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.joda.time.DateTimeZone; + +public class JodaTest_7_DateTimeZone extends TestCase { + public void test_for_joda_0() throws Exception { + + Model m = new Model(); + m.zone = DateTimeZone.forID("Asia/Shanghai"); + + String json = JSON.toJSONString(m); + + assertEquals("{\"zone\":\"Asia/Shanghai\"}", json); + + Model m1 = JSON.parseObject(json, Model.class); + assertEquals(m.zone, m1.zone); + } + + public static class Model { + public DateTimeZone zone; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/joda/JodaTest_8_DateTimeTest.java b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_8_DateTimeTest.java new file mode 100644 index 0000000000..daa44fc33d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/joda/JodaTest_8_DateTimeTest.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.joda; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.joda.time.DateTime; +import org.joda.time.LocalTime; +import org.junit.Assert; + +import java.util.Locale; +import java.util.TimeZone; + +public class JodaTest_8_DateTimeTest extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.date = DateTime.now(); + + String text = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.date.toDate(), vo1.date.toDate()); + } + + /** + * 方法描述: 测试时间戳转换为 时间 + * @author wuqiong 2017/11/21 16:48 + */ + public void test_for_long() throws Exception { + String text= "{\"date\":1511248447740}"; + VO vo =JSON.parseObject(text,VO.class); + Assert.assertEquals("timeZone " + TimeZone.getDefault(), 15, vo.date.getHourOfDay()); + Assert.assertEquals(14, vo.date.getMinuteOfHour()); + Assert.assertEquals(07, vo.date.getSecondOfMinute()); + } + + public static class VO { + private DateTime date; + + public DateTime getDate() { + return date; + } + + public void setDate(DateTime date) { + this.date = date; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest2.java b/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest2.java index f4955f8077..1785e3e6bc 100644 --- a/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest2.java +++ b/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest2.java @@ -21,7 +21,7 @@ public void test_f() throws Exception { assertEquals(1, param.get("id")); assertEquals("idonans", param.get("name")); - String json = JSON.toJSONString(jsonpObject); - assertEquals("parent.callback({\"name\":\"idonans\",\"id\":1})", json); + String json = JSON.toJSONString(jsonpObject, SerializerFeature.MapSortField); + assertEquals("parent.callback({\"id\":1,\"name\":\"idonans\"})", json); } } diff --git a/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest3.java b/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest3.java index 646567b31e..8da261cad9 100644 --- a/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest3.java +++ b/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest3.java @@ -21,7 +21,7 @@ public void test_f() throws Exception { assertEquals(1, param.get("id")); assertEquals("ido)nans", param.get("name")); - String json = JSON.toJSONString(jsonpObject, SerializerFeature.BrowserSecure); - assertEquals("/**/parent.callback({\"name\":\"ido\\u0029nans\",\"id\":1},1,2)", json); + String json = JSON.toJSONString(jsonpObject, SerializerFeature.BrowserSecure, SerializerFeature.MapSortField); + assertEquals("/**/parent.callback({\"id\":1,\"name\":\"ido\\u0029nans\"},1,2)", json); } } diff --git a/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest4.java b/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest4.java new file mode 100644 index 0000000000..262ed7385b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jsonp/JSONPParseTest4.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.jsonp; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +/** + * Created by wenshao on 21/02/2017. + */ +public class JSONPParseTest4 extends TestCase { + public void test_f() throws Exception { + JSONPObject p = new JSONPObject(); + p.setFunction("f"); + assertEquals("f()", p.toJSONString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jsonpatch/JSONPatchTest_0.java b/src/test/java/com/alibaba/json/bvt/jsonpatch/JSONPatchTest_0.java new file mode 100644 index 0000000000..6e899dd939 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jsonpatch/JSONPatchTest_0.java @@ -0,0 +1,87 @@ +package com.alibaba.json.bvt.jsonpatch; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPatch; +import junit.framework.TestCase; + +public class JSONPatchTest_0 extends TestCase { + public void test_for_multi_0() throws Exception { + String original = "{\n" + + " \"baz\": \"qux\",\n" + + " \"foo\": \"bar\"\n" + + "}"; + + String patch = "[\n" + + " { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n" + + " { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n" + + " { \"op\": \"remove\", \"path\": \"/foo\" }\n" + + "]"; + + String result = JSONPatch.apply(original, patch); + assertEquals("{\"baz\":\"boo\",\"hello\":[\"world\"]}", result); + } + + public void test_for_add_1() throws Exception { + String original = "{}"; + + String patch = "{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }"; + + String result = JSONPatch.apply(original, patch); + assertEquals("{\"a\":{\"b\":{\"c\":[\"foo\",\"bar\"]}}}", result); + } + + public void test_for_remove_0() throws Exception { + String original = "{}"; + + String patch = "{ \"op\": \"remove\", \"path\": \"/a/b/c\" }\n"; + + String result = JSONPatch.apply(original, patch); + assertEquals("{}", result); + } + + public void test_for_remove_1() throws Exception { + String original = "{\"a\":{\"b\":{\"c\":[\"foo\",\"bar\"]}}}"; + + String patch = "{ \"op\": \"remove\", \"path\": \"/a/b/c\" }\n"; + + String result = JSONPatch.apply(original, patch); + assertEquals("{\"a\":{\"b\":{}}}", result); + } + + public void test_for_replace_1() throws Exception { + String original = "{\"a\":{\"b\":{\"c\":[\"foo\",\"bar\"]}}}"; + + String patch = "{ \"op\": \"replace\", \"path\": \"/a/b/c\", \"value\": 42 }"; + + String result = JSONPatch.apply(original, patch); + assertEquals("{\"a\":{\"b\":{\"c\":42}}}", result); + } + + public void test_for_move_0() throws Exception { + String original = "{\"a\":{\"b\":{\"c\":[\"foo\",\"bar\"]}}}"; + + String patch = "{ \"op\": \"move\", \"from\": \"/a/b/c\", \"path\": \"/a/b/d\" }"; + + String result = JSONPatch.apply(original, patch); + assertEquals("{\"a\":{\"b\":{\"d\":[\"foo\",\"bar\"]}}}", result); + } + + public void test_for_copy_0() throws Exception { + String original = "{\"a\":{\"b\":{\"c\":[\"foo\",\"bar\"]}}}"; + + String patch = "{ \"op\": \"copy\", \"from\": \"/a/b/c\", \"path\": \"/a/b/e\" }"; + + String result = JSONPatch.apply(original, patch); + assertEquals("{\"a\":{\"b\":{\"c\":[\"foo\",\"bar\"],\"e\":[\"foo\",\"bar\"]}}}", result); + } + + + public void test_for_test_0() throws Exception { + String original = "{\"a\":{\"b\":{\"c\":[\"foo\",\"bar\"]}}}"; + + String patch = "{ \"op\": \"test\", \"path\": \"/a/b/c\", \"value\": \"foo\" }"; + + String result = JSONPatch.apply(original, patch); + assertEquals("false", result); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/kotlin/DataClassSimpleTest.java b/src/test/java/com/alibaba/json/bvt/kotlin/DataClassSimpleTest.java index fd77d544bc..10c83fadc8 100644 --- a/src/test/java/com/alibaba/json/bvt/kotlin/DataClassSimpleTest.java +++ b/src/test/java/com/alibaba/json/bvt/kotlin/DataClassSimpleTest.java @@ -3,9 +3,6 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.util.ASMUtils; import junit.framework.TestCase; -import kotlin.reflect.KFunction; -import kotlin.reflect.KParameter; -import kotlin.reflect.jvm.internal.KClassImpl; import org.apache.commons.io.IOUtils; import java.io.ByteArrayInputStream; diff --git a/src/test/java/com/alibaba/json/bvt/kotlin/Issue1483.java b/src/test/java/com/alibaba/json/bvt/kotlin/Issue1483.java index b794992940..e8397cbb4c 100644 --- a/src/test/java/com/alibaba/json/bvt/kotlin/Issue1483.java +++ b/src/test/java/com/alibaba/json/bvt/kotlin/Issue1483.java @@ -1,6 +1,7 @@ package com.alibaba.json.bvt.kotlin; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; import junit.framework.TestCase; import org.apache.commons.io.IOUtils; @@ -10,10 +11,7 @@ /** * Created by wenshao on 05/08/2017. */ -public class - - -Issue1483 extends TestCase { +public class Issue1483 extends TestCase { public void test_user() throws Exception { ExtClassLoader classLoader = new ExtClassLoader(); @@ -22,12 +20,11 @@ public void test_user() throws Exception { String json = "{\"age\":99,\"name\":\"robohorse\",\"desc\":\"xx\"}"; Object obj = JSON.parseObject(json, clazz); assertSame(clazz, obj.getClass()); - - if ("{\"age\":99,\"desc\":\"[robohorse\",\"name\":\"xx]\"}".equals(JSON.toJSONString(obj))) { - return; +// + for (int i = 0; i < 10; ++i) { + String text = JSON.parseObject(JSON.toJSONString(obj), Feature.OrderedField).toJSONString(); + assertEquals("{\"age\":99,\"desc\":\"xx\",\"name\":\"robohorse\"}", text); } - - assertEquals("{\"age\":99,\"desc\":\"xx\",\"name\":\"robohorse\"}", JSON.toJSONString(obj)); } public static class ExtClassLoader extends ClassLoader { diff --git a/src/test/java/com/alibaba/json/bvt/kotlin/Issue1750.java b/src/test/java/com/alibaba/json/bvt/kotlin/Issue1750.java new file mode 100644 index 0000000000..4db82b3f59 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/kotlin/Issue1750.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.kotlin; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; + +public class Issue1750 extends TestCase { + public void test_user() throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("Issue1750_ProcessBO"); + + String json = "{\n" + + "\t\"masterId\": \"1111111111111\",\n" + + "\t\"processId\": \"222222222222222\",\n" + + "\t\"taskId\": \"33333333333333\",\n" + + "\t\"taskName\": \"44444444444444\"\n" + + "}"; + Object obj = JSON.parseObject(json, clazz); + String result = JSON.toJSONString(obj); + System.out.println(result); + assertEquals("{\"masterId\":\"1111111111111\",\"processId\":\"222222222222222\",\"taskId\":\"33333333333333\",\"taskName\":\"44444444444444\"}", result); + } + + private static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException { + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("kotlin/Issue1750_ProcessBO.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("Issue1750_ProcessBO", bytes, 0, bytes.length); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/kotlin/Issue_for_kotlin_20181203.java b/src/test/java/com/alibaba/json/bvt/kotlin/Issue_for_kotlin_20181203.java new file mode 100644 index 0000000000..b38b016c45 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/kotlin/Issue_for_kotlin_20181203.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.kotlin; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import junit.framework.TestCase; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; + +public class Issue_for_kotlin_20181203 extends TestCase { + public void test_user() throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("com.autonavi.falcon.data.service.vulpeData.ProjectItemCheckItemRelation1"); + + String str = " [{\n" + + " \"project_item\": \"1105067\",\n" + + " \"project_name\": \"明明想\",\n" + + " \"product_id_3\": \"0210202\",\n" + + " \"task_type_name\": \"黎明X\",\n" + + " \"product_id_2\": \"02102\",\n" + + " \"product_id_1\": \"021\",\n" + + " \"job_item_type\": \"高中\",\n" + + " \"product_name_1\": \"犀利\",\n" + + " \"product_name_2\": \"基础路网\",\n" + + " \"unit\": \"条\",\n" + + " \"product_name_3\": \"到底\",\n" + + " \"unitremark\": \"任务条数\",\n" + + " \"task_type\": \"57205\"\n" + + " }]"; + + System.out.println(JSON.VERSION); + + Object obj = JSONArray.parseArray(str, clazz); + String result = JSON.toJSONString(obj); + System.out.println(result); + assertEquals("[{\"job_item_type\":\"高中\",\"product_id_1\":\"021\",\"product_id_2\":\"02102\",\"product_id_3\":\"0210202\",\"product_name_1\":\"犀利\",\"product_name_2\":\"基础路网\",\"product_name_3\":\"到底\",\"project_item\":\"1105067\",\"project_name\":\"明明想\",\"task_type\":\"57205\",\"task_type_name\":\"黎明X\",\"unit\":\"条\",\"unitremark\":\"任务条数\"}]", result); + } + + private static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException { + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("kotlin/ProjectItemCheckItemRelation1.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("com.autonavi.falcon.data.service.vulpeData.ProjectItemCheckItemRelation1", bytes, 0, bytes.length); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/kotlin/Zoujing.java b/src/test/java/com/alibaba/json/bvt/kotlin/Zoujing.java new file mode 100644 index 0000000000..364ef4074e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/kotlin/Zoujing.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.kotlin; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; + +public class Zoujing extends TestCase { + public void test_user() throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("com.alidme.xrecharge.platform.common.data.NoticeData"); + + String json = "{\"benefitNoticeState\":1}"; + Object obj = JSON.parseObject(json, clazz); + String result = JSON.toJSONString(obj); + System.out.println(result); + assertEquals("{\"benefitNoticeState\":1,\"outId\":\"\"}", result); + } + + private static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException { + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("kotlin/zuojing/NoticeData.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("com.alidme.xrecharge.platform.common.data.NoticeData", bytes, 0, bytes.length); + } + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("kotlin/zuojing/NoticeDataKt.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("com.alidme.xrecharge.platform.common.data.NoticeDataKt", bytes, 0, bytes.length); + } + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("kotlin/zuojing/NoticeData_Companion.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("com.alidme.xrecharge.platform.common.data.NoticeData$Companion", bytes, 0, bytes.length); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/lombok/LomBokTest.java b/src/test/java/com/alibaba/json/bvt/lombok/LomBokTest.java new file mode 100644 index 0000000000..faa6d3998b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/lombok/LomBokTest.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.lombok; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class LomBokTest extends TestCase { + public void test_for_issue() throws Exception { + String str = "{\n" + + "\t\"target\": 1,\n" + + "\t\"current\": 0,\n" + + "\t\"step\": 1,\n" + + "\t\"uqcRule\": {\n" + + "\t\t\"ruleCode\": \"IND#PAY1212#NP1D#1\"\n" + + "\t},\n" + + "\t\"cycleRule\": {\n" + + "\t\t\"decision\": {\"@type\": \"com.alibaba.json.bvt.lombok.LomBokTest$DaysCycleExeDecision\",\"days\": 1\n" + + "\t\t}\n" + + "\t},\n" + + "\t\"dataSource\": {\n" + + "\t\t\"PAYLINK\": {\n" + + "\t\t\t\"target\": 0\n" + + "\t\t}\n" + + "\t}\n" + + "}"; + ParserConfig.getGlobalInstance().addAccept("com.alibaba.json.bvt.lombok.LomBokTest.DaysCycleExeDecision"); + JSONObject obj = JSON.parseObject(str); + IndicatorCycleRule cycleRule = obj.getObject("cycleRule", IndicatorCycleRule.class); + System.out.println(((DaysCycleExeDecision) cycleRule.decision).days); + } + + @lombok.Data + public static class DaysCycleExeDecision implements ExeDecision { + private int days; + } + + public static interface ExeDecision { + + } + + @lombok.Data + public static class IndicatorCycleRule { + + /** + * 周期决策器 + */ + private ExeDecision decision; + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixInRemovalTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixInRemovalTest.java new file mode 100644 index 0000000000..089beab32a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixInRemovalTest.java @@ -0,0 +1,69 @@ +package com.alibaba.json.bvt.mixins; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Assert; + +public class MixInRemovalTest extends TestCase { + static class BaseClass { + public int a; + public int b; + + public BaseClass() { + + } + + public BaseClass(int a, int b) { + this.a = a; + this.b = b; + } + } + + class MixIn1 { + @JSONField(name = "apple") + public int a; + @JSONField(name = "banana") + public int b; + } + + class MixIn2 { + @JSONField(name = "ariston") + public int a; + @JSONField(name = "brilliant") + public int b; + } + + public void test_mixInRemoval_serialize() throws Exception { + BaseClass base = new BaseClass(1, 2); + Assert.assertEquals("{\"a\":1,\"b\":2}", JSON.toJSONString(base)); + + JSON.addMixInAnnotations(BaseClass.class, MixIn1.class); + Assert.assertEquals("{\"apple\":1,\"banana\":2}", JSON.toJSONString(base)); + JSON.removeMixInAnnotations(BaseClass.class); + + JSON.addMixInAnnotations(BaseClass.class, MixIn2.class); + Assert.assertEquals("{\"ariston\":1,\"brilliant\":2}", JSON.toJSONString(base)); + JSON.removeMixInAnnotations(BaseClass.class); + + Assert.assertEquals("{\"a\":1,\"b\":2}", JSON.toJSONString(base)); + } + + public void test_mixInRemoval_deserialize() throws Exception { + BaseClass base = JSON.parseObject("{\"a\":1,\"b\":2}", BaseClass.class); + Assert.assertEquals(1, base.a); + Assert.assertEquals(2, base.b); + + JSON.addMixInAnnotations(BaseClass.class, MixIn1.class); + BaseClass base2 = JSON.parseObject("{\"apple\":3,\"banana\":4}", BaseClass.class); + Assert.assertEquals(3, base2.a); + Assert.assertEquals(4, base2.b); + JSON.removeMixInAnnotations(BaseClass.class); + + JSON.addMixInAnnotations(BaseClass.class, MixIn2.class); + BaseClass base3 = JSON.parseObject("{\"ariston\":5,\"brilliant\":6}", BaseClass.class); + Assert.assertEquals(5, base3.a); + Assert.assertEquals(6, base3.b); + JSON.removeMixInAnnotations(BaseClass.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinAPITest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinAPITest.java new file mode 100644 index 0000000000..fb88839192 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinAPITest.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.mixins; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Assert; + +public class MixinAPITest extends TestCase { + + static class BaseClass { + public int a; + public int b; + + public BaseClass() { + + } + + public BaseClass(int a, int b) { + this.a = a; + this.b = b; + } + } + + class MixIn1 { + @JSONField(name = "apple") + public int a; + @JSONField(name = "banana") + public int b; + } + + + public void test_mixIn_get_methods() throws Exception { + BaseClass base = new BaseClass(1, 2); + + JSON.addMixInAnnotations(BaseClass.class, MixIn1.class); + Assert.assertEquals("{\"apple\":1,\"banana\":2}", JSON.toJSONString(base)); + Assert.assertTrue(MixIn1.class == JSON.getMixInAnnotations(BaseClass.class)); + + JSON.clearMixInAnnotations(); + Assert.assertTrue(null == JSON.getMixInAnnotations(BaseClass.class)); + + JSON.removeMixInAnnotations(BaseClass.class); + } +} + diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinDeserForClassTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinDeserForClassTest.java new file mode 100644 index 0000000000..dfdf9c9bd9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinDeserForClassTest.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.mixins; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +import junit.framework.TestCase; + +public class MixinDeserForClassTest extends TestCase { + static class BaseClass { + @JSONField( deserialize = true ) + public String a; + + @JSONField( deserialize = false, name = "a" ) + public void setA( String v ) { + a = "XXX" + v; + } + } + + static class BaseClass1 { + @JSONField( deserialize = false ) + public String a; + + @JSONField( deserialize = true, name = "a" ) + public void setA( String v ) { + a = "XXX" + v; + } + } + + static class Mixin { + @JSONField( deserialize = false ) + public String a; + + @JSONField( deserialize = true, name = "a" ) + public void setA( String v ) { + } + } + + public void test_1() throws Exception { + BaseClass1 base = JSON.parseObject( "{\"a\":\"132\"}", BaseClass1.class ); + Assert.assertEquals( "XXX132", base.a ); + } + + public void test_2() throws Exception { + JSON.addMixInAnnotations(BaseClass.class, Mixin.class); + BaseClass base = JSON.parseObject( "{\"a\":\"132\"}", BaseClass.class ); + Assert.assertEquals( "XXX132", base.a ); + JSON.removeMixInAnnotations(BaseClass.class); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinDeserForMethodsTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinDeserForMethodsTest.java new file mode 100644 index 0000000000..b1071ff80f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinDeserForMethodsTest.java @@ -0,0 +1,65 @@ +package com.alibaba.json.bvt.mixins; + +import java.util.HashMap; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +import junit.framework.TestCase; + +public class MixinDeserForMethodsTest extends TestCase { + + static class BaseClass { + protected HashMap values = new HashMap(); + + @JSONCreator + public BaseClass( @JSONField( name = "name" ) String name,@JSONField( name = "age" ) String age, + @JSONField( name = "student" ) Object student ) { + values.put( "name", name ); + values.put( "age", age ); + values.put( "student", student ); + } + } + + static class BaseClass2 { + protected HashMap values = new HashMap(); + + public BaseClass2( String name,String age,Object student ) { + values.put( "name", name ); + values.put( "age", age ); + values.put( "student", student ); + } + } + + class MixIn { + @JSONCreator + MixIn( @JSONField( name = "name" ) String name,@JSONField( name = "age" ) String age, + @JSONField( name = "student" ) Object student ) { + }; + } + + public void test_0() throws Exception { + BaseClass result = JSON.parseObject( "{ \"name\" : \"David\", \"age\" : 13, \"student\" : true }", + BaseClass.class ); + Assert.assertNotNull( result ); + Assert.assertEquals( 3, result.values.size() ); + Assert.assertEquals( "David", result.values.get( "name" ) ); + Assert.assertEquals( "13", result.values.get( "age" ) ); + Assert.assertEquals( Boolean.TRUE, result.values.get( "student" ) ); + } + + public void test_1() throws Exception { + JSON.addMixInAnnotations(BaseClass2.class, MixIn.class); + BaseClass2 result = JSON.parseObject( "{ \"name\" : \"David\", \"age\" : 13, \"student\" : true }", + BaseClass2.class ); + Assert.assertNotNull( result ); + Assert.assertEquals( 3, result.values.size() ); + Assert.assertEquals( "David", result.values.get( "name" ) ); + Assert.assertEquals( "13", result.values.get( "age" ) ); + Assert.assertEquals( Boolean.TRUE, result.values.get( "student" ) ); + JSON.removeMixInAnnotations(BaseClass2.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinInheritanceTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinInheritanceTest.java new file mode 100644 index 0000000000..ce202d63ca --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinInheritanceTest.java @@ -0,0 +1,113 @@ +package com.alibaba.json.bvt.mixins; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Assert; + +public class MixinInheritanceTest extends TestCase { + static class Beano { + public int ido = 42; + public String nameo = "Bob"; + } + + static class BeanoMixinSuper { + @JSONField(name = "name") + public String nameo; + } + + static class BeanoMixinSub extends BeanoMixinSuper { + @JSONField(name = "id") + public int ido; + } + + static class Beano2 { + public int getIdo() { return 13; } + public String getNameo() { return "Bill"; } + } + + static abstract class BeanoMixinSuper2 extends Beano2 { + @Override + @JSONField(name = "name") + public abstract String getNameo(); + } + + static abstract class BeanoMixinSub2 extends BeanoMixinSuper2 { + @Override + @JSONField(name = "id") + public abstract int getIdo(); + } + + public void test_field() throws Exception { + JSON.addMixInAnnotations(Beano.class, BeanoMixinSub.class); + String str = JSON.toJSONString(new Beano()); + JSONObject result = JSONObject.parseObject(str); + assertEquals(2, result.size()); + if (!result.containsKey("id") + || !result.containsKey("name")) { + fail("Should have both 'id' and 'name', but content = " + result); + } + JSON.removeMixInAnnotations(Beano.class); + } + + public void test_method() throws Exception { + JSON.addMixInAnnotations(Beano2.class, BeanoMixinSub2.class); + String str = JSON.toJSONString(new Beano2()); + JSONObject result = JSONObject.parseObject(str); + assertEquals(2, result.size()); + assertTrue(result.containsKey("id")); + assertTrue(result.containsKey("name")); + JSON.removeMixInAnnotations(Beano2.class); + } + + static class BaseClass { + public int a; + public int b; + public int c; + + public BaseClass() { + + } + public BaseClass(int a, int b,int c) { + this.a = a; + this.b = b; + this.c = c; + } + } + + class BaseMixIn { + @JSONField(name = "apple") + public int a; + @JSONField(name = "banana") + public int b; + } + + class SubMixIn extends BaseMixIn { + @JSONField(name = "pear") + public int c; + } + + class SubMixIn1 extends SubMixIn { + @JSONField(name = "watermelon") + public int b; + } + + public void test_mixIn_extend() throws Exception { + BaseClass base = new BaseClass(1, 2,3); + Assert.assertEquals("{\"a\":1,\"b\":2,\"c\":3}", JSON.toJSONString(base)); + + JSON.addMixInAnnotations(BaseClass.class, SubMixIn.class); + Assert.assertEquals("{\"apple\":1,\"banana\":2,\"pear\":3}", JSON.toJSONString(base)); + JSON.removeMixInAnnotations(BaseClass.class); + } + + public void test_mixIn_extend1() throws Exception { + BaseClass base = new BaseClass(1, 2,3); + Assert.assertEquals("{\"a\":1,\"b\":2,\"c\":3}", JSON.toJSONString(base)); + + JSON.addMixInAnnotations(BaseClass.class, SubMixIn1.class); + Assert.assertEquals("{\"apple\":1,\"pear\":3,\"watermelon\":2}", JSON.toJSONString(base)); + JSON.removeMixInAnnotations(BaseClass.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinJSONTypeTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinJSONTypeTest.java new file mode 100644 index 0000000000..35b9b54c99 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinJSONTypeTest.java @@ -0,0 +1,146 @@ +package com.alibaba.json.bvt.mixins; + +import com.alibaba.fastjson.annotation.JSONPOJOBuilder; +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import junit.framework.TestCase; + +public class MixinJSONTypeTest extends TestCase { + public void test_1() { + User user1 = new User("zhangsan", "male", 19); + Assert.assertEquals("{\"age\":19,\"sex\":\"male\",\"userName\":\"zhangsan\"}", JSON.toJSONString(user1)); + + JSON.addMixInAnnotations(user1.getClass(), Mixin.class); + Assert.assertEquals("{\"age\":19,\"userName\":\"zhangsan\",\"sex\":\"male\"}", JSON.toJSONString(user1)); + + JSON.removeMixInAnnotations(user1.getClass()); + } + + public void test_2() { + User user1 = new User("lisi", "male", 20); + Assert.assertEquals("{\"age\":20,\"sex\":\"male\",\"userName\":\"lisi\"}", JSON.toJSONString(user1)); + + JSON.addMixInAnnotations(user1.getClass(), Mixin2.class); + Assert.assertEquals("{\"userName\":\"lisi\"}", JSON.toJSONString(user1)); + + JSON.removeMixInAnnotations(user1.getClass()); + } + + public void test_3() { + User user1 = new User("wangwu", "male", 31); + Assert.assertEquals("{\"age\":31,\"sex\":\"male\",\"userName\":\"wangwu\"}", JSON.toJSONString(user1)); + + JSON.addMixInAnnotations(user1.getClass(), Mixin3.class); + Assert.assertEquals("{\"age\":31,\"sex\":\"male\"}", JSON.toJSONString(user1)); + + JSON.removeMixInAnnotations(user1.getClass()); + } + + public void test_4() throws Exception { + JSON.addMixInAnnotations(VO.class, Mixin5.class); + JSON.addMixInAnnotations(VOBuilder.class, Mixin6.class); + + VO vo = JSON.parseObject("{\"id\":12304,\"name\":\"ljw\"}", VO.class); + + Assert.assertEquals(12304, vo.getId()); + Assert.assertEquals("ljw", vo.getName()); + + JSON.removeMixInAnnotations(VO.class); + JSON.removeMixInAnnotations(VOBuilder.class); + } + + @JSONType(serialzeFeatures = { SerializerFeature.QuoteFieldNames }) + public class User { + private String userName; + private String sex; + private int age; + + public User(String userName, String sex, int age) { + this.userName = userName; + this.sex = sex; + this.age = age; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + } + + @JSONType(orders = { "age", "userName", "sex" }) + interface Mixin { + } + + @JSONType(includes = { "userName" }) + interface Mixin2 { + } + + @JSONType(ignores = { "userName" }) + interface Mixin3 { + } + + @JSONType(serialzeFeatures = { SerializerFeature.PrettyFormat }) + interface Mixin4 { + } + + public static class VO { + private int id; + private String name; + + public int getId() { + return id; + } + + public String getName() { + return name; + } + } + + private static class VOBuilder { + + private VO vo = new VO(); + + public VO xxx() { + return vo; + } + + public VOBuilder withId(int id) { + vo.id = id; + return this; + } + + public VOBuilder withName(String name) { + vo.name = name; + return this; + } + } + + @JSONType(builder= VOBuilder.class) + class Mixin5{ } + @JSONPOJOBuilder(buildMethod="xxx") + class Mixin6{ } +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinMergingTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinMergingTest.java new file mode 100644 index 0000000000..6fa1fb0863 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinMergingTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.mixins; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class MixinMergingTest extends TestCase +{ + public interface Contact { + String getCity(); + } + + static class ContactImpl implements Contact { + @Override + public String getCity() { return "Seattle"; } + } + + static class ContactMixin implements Contact { + @Override + @JSONField + public String getCity() { return null; } + } + + public interface Person extends Contact {} + + static class PersonImpl extends ContactImpl implements Person {} + + static class PersonMixin extends ContactMixin implements Person {} + + public void test() throws Exception { + JSON.addMixInAnnotations(Person.class, PersonMixin.class); + assertEquals("{\"city\":\"Seattle\"}", JSON.toJSONString(new PersonImpl())); + JSON.removeMixInAnnotations(Person.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinSerForFieldsTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinSerForFieldsTest.java new file mode 100644 index 0000000000..da66236b81 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinSerForFieldsTest.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.mixins; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; + +import junit.framework.TestCase; + +public class MixinSerForFieldsTest extends TestCase { + static class BeanClass { + public String a; + public String b; + + public BeanClass(String a, String b) { + this.a = a; + this.b = b; + } + } + + abstract class MixIn { + @JSONField(serialize = false) + public String a; + @JSONField(name = "banana") + public String b; + } + + public void test() throws Exception{ + BeanClass bean = new BeanClass("1", "2"); + + JSON.addMixInAnnotations(BeanClass.class, MixIn.class); + String jsonString = JSON.toJSONString(bean); + JSONObject result = JSON.parseObject(jsonString); + assertEquals(1, result.size()); + assertEquals("2", result.get("banana")); + JSON.removeMixInAnnotations(BeanClass.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/mixins/MixinSerForMethodsTest.java b/src/test/java/com/alibaba/json/bvt/mixins/MixinSerForMethodsTest.java new file mode 100644 index 0000000000..21b3436022 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/mixins/MixinSerForMethodsTest.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.mixins; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; + +import junit.framework.TestCase; + +public class MixinSerForMethodsTest extends TestCase { + + @SuppressWarnings( "unused" ) + static class BaseClass { + private String a; + private String b; + + protected BaseClass() { + } + + public BaseClass( String a,String b ) { + this.a = a; + this.b = b; + } + + @JSONField( name = "b" ) + public String takeB() { + return b; + } + } + + static class BaseClass2 { + private String a; + private String b; + + protected BaseClass2() { + } + + public BaseClass2( String a,String b ) { + this.a = a; + this.b = b; + } + + @JSONField( name = "b" ) + public String takeB() { + return b; + } + + @JSONField( name = "a" ) + public String takeA() { + return a; + } + } + + abstract static class MixIn { + String a; + + @JSONField( name = "b2" ) + public abstract String takeB(); + + abstract String takeA(); + } + + public void test() throws Exception{ + BaseClass bean = new BaseClass( "a1", "b2" ); + + String jsonString = JSON.toJSONString( bean ); + JSONObject result = JSON.parseObject( jsonString ); + assertEquals( 1, result.size() ); + assertEquals( "b2", result.get( "b" ) ); + + BaseClass2 bean2 = new BaseClass2( "a1", "b2" ); + JSON.addMixInAnnotations( BaseClass2.class, MixIn.class ); + jsonString = JSON.toJSONString( bean2 ); + result = JSON.parseObject( jsonString ); + assertEquals( 2, result.size() ); + assertEquals( "b2", result.get( "b2" ) ); + assertEquals( "a1", result.get( "a" ) ); + JSON.removeMixInAnnotations( BaseClass.class ); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest0.java b/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest1.java b/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/AutoTypeCheckHandlerTest.java b/src/test/java/com/alibaba/json/bvt/parser/AutoTypeCheckHandlerTest.java new file mode 100644 index 0000000000..4de4aaeaa5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/AutoTypeCheckHandlerTest.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class AutoTypeCheckHandlerTest extends TestCase { + public void test_for_issue() throws Exception { + ParserConfig config = new ParserConfig(); + + String str = "{\"@type\":\"com.alibaba.json.bvt.parser.autoType.AutoTypeCheckHandlerTest$Model\"}"; + JSONException error = null; + try { + JSON.parse(str, config); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + + config.addAutoTypeCheckHandler(new ParserConfig.AutoTypeCheckHandler() { + @Override + public Class handler(String typeName, Class expectClass, int features) { + if ("com.alibaba.json.bvt.parser.autoType.AutoTypeCheckHandlerTest$Model".equals(typeName)) { + return Model.class; + } + return null; + } + }); + + JSON.parse(str, config); + } + + public static class Model { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ClassConstructorTest1.java b/src/test/java/com/alibaba/json/bvt/parser/ClassConstructorTest1.java new file mode 100644 index 0000000000..4962d07da8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ClassConstructorTest1.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.junit.Test; +import org.springframework.util.Assert; + +public class ClassConstructorTest1 extends TestCase { + public void test_error() throws Exception { + String modelJSON = "{\"age\":12, \"name\":\"nanqi\"}"; + Model model = JSON.parseObject(modelJSON, Model.class); +// Assert.notNull(model.getName()); + //skip + } + + public static class Model { + public Model(int age) { + this.age = age; + } + + private String name; + + private int age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ClassTest.java b/src/test/java/com/alibaba/json/bvt/parser/ClassTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DateParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql.java b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql_timestamp.java b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql_timestamp.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DateTest.java b/src/test/java/com/alibaba/json/bvt/parser/DateTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest.java old mode 100755 new mode 100644 index 857d5d2e26..0b133c60c1 --- a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest.java @@ -547,7 +547,7 @@ public void setAge(int age) { } public void setage(int age) { - throw new UnsupportedOperationException(); + this.age = age; } public void set(int age) { diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_0.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_1.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_2.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_3.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_4.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_5.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_6.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_7.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_7.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray.java old mode 100755 new mode 100644 index 93bc751d53..dd5400bad1 --- a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray.java @@ -5,10 +5,13 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Locale; +import java.util.TimeZone; import org.junit.Assert; import junit.framework.TestCase; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.parser.DefaultJSONParser; @@ -88,6 +91,7 @@ public void test_6() throws Exception { } public void test_7() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); DefaultJSONParser parser = new DefaultJSONParser("[\"2011-01-09T13:49:53.254\", \"xxx\", true, false, null, {}]"); parser.config(Feature.AllowISO8601DateFormat, true); ArrayList list = new ArrayList(); @@ -101,6 +105,7 @@ public void test_7() throws Exception { } public void test_8() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); DefaultJSONParser parser = new DefaultJSONParser("\"2011-01-09T13:49:53.254\""); parser.config(Feature.AllowISO8601DateFormat, true); Object value = parser.parse(); diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray_2.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest2.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest2.java old mode 100755 new mode 100644 index 045cf0db35..ddd5476fed --- a/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest2.java @@ -12,6 +12,19 @@ public class DefaultJSONParserTest2 extends TestCase { + public void test_empty() throws Exception { + String text = ""; + assertNull(JSON.parse(text)); + assertNull(JSON.parseObject(text)); + assertNull(JSON.parseObject(text, Object.class)); + assertNull(JSON.parseObject(text, Map.class)); + assertNull(JSON.parseObject(text, Entity.class)); + } + + public static class Entity { + + } + public void test_0() throws Exception { String text = "{}"; Map map = (Map) JSON.parse(text); diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_charArray.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_charArray.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_comma.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_comma.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_date.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_date.java old mode 100755 new mode 100644 index 2a402221ae..c2389f8ad8 --- a/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_date.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_date.java @@ -65,7 +65,7 @@ public void test_dateFormat() throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyy-DD-mm", JSON.defaultLocale); format.setTimeZone(JSON.defaultTimeZone); - parser.setDateFomrat(format); + parser.setDateFormat(format); parser.getDateFomartPattern(); parser.getDateFormat(); parser.parse(); diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_error.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_error.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/EmptyImmutableTest.java b/src/test/java/com/alibaba/json/bvt/parser/EmptyImmutableTest.java new file mode 100644 index 0000000000..07d5512223 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/EmptyImmutableTest.java @@ -0,0 +1,82 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.io.Serializable; +import java.util.*; + +public class EmptyImmutableTest extends TestCase { + public void test_0() throws Exception { + VO vo = JSON.parseObject("{\"values\":[],\"map\":{}}", VO.class); + } + + public static class VO { + private List values = new EmptyList(); + private Map map = new EmptyMap(); + + public List getValues() { + return values; + } + + public Map getMap() { + return map; + } + } + + private static class EmptyMap extends HashMap { + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + } + + private static class EmptyList + extends AbstractList + implements RandomAccess, Serializable { + private static final long serialVersionUID = 8842843931221139166L; + + public Iterator iterator() { + throw new UnsupportedOperationException(); + } + public ListIterator listIterator() { + throw new UnsupportedOperationException(); + } + + public boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + + public int size() {return 0;} + public boolean isEmpty() {return true;} + + public boolean contains(Object obj) {return false;} + public boolean containsAll(Collection c) { return c.isEmpty(); } + + public Object[] toArray() { return new Object[0]; } + + public T[] toArray(T[] a) { + if (a.length > 0) + a[0] = null; + return a; + } + + public E get(int index) { + throw new IndexOutOfBoundsException("Index: "+index); + } + + public boolean equals(Object o) { + return (o instanceof List) && ((List)o).isEmpty(); + } + + public int hashCode() { return 1; } + + public void sort(Comparator c) { + } + + + // Preserves singleton property + private Object readResolve() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/EnumParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/EnumParserTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/FastMatchCheckTest.java b/src/test/java/com/alibaba/json/bvt/parser/FastMatchCheckTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/FeatureCountTest.java b/src/test/java/com/alibaba/json/bvt/parser/FeatureCountTest.java new file mode 100644 index 0000000000..02c95c28ac --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/FeatureCountTest.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class FeatureCountTest extends TestCase { + public void testZ_0() throws Exception { + Feature[] features = Feature.class.getEnumConstants(); + System.out.println(features.length); + assertTrue(features.length < 32); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/FeatureParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/FeatureParserTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/FeatureTest.java b/src/test/java/com/alibaba/json/bvt/parser/FeatureTest.java old mode 100755 new mode 100644 index 2bf172bd68..bdaa10adbd --- a/src/test/java/com/alibaba/json/bvt/parser/FeatureTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/FeatureTest.java @@ -37,4 +37,8 @@ public void test_config() throws Exception { parser.config(Feature.InternFieldNames, false); Assert.assertEquals(false, parser.isEnabled(Feature.InternFieldNames)); } + + public void test_count() throws Exception { + assertTrue(Feature.values().length < 32); + } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/InetSocketAddressTest.java b/src/test/java/com/alibaba/json/bvt/parser/InetSocketAddressTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONArrayParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/JSONArrayParseTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ISO8601.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ISO8601.java old mode 100755 new mode 100644 index b98554969c..e2bd80f6fb --- a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ISO8601.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ISO8601.java @@ -14,7 +14,13 @@ public void test_0() throws Exception { Assert.assertEquals(false, new JSONScanner("2").scanISO8601DateIfMatch()); Assert.assertEquals(false, new JSONScanner("3").scanISO8601DateIfMatch()); Assert.assertEquals(true, new JSONScanner("3000-10-02").scanISO8601DateIfMatch()); - Assert.assertEquals(false, new JSONScanner("4000-10-02").scanISO8601DateIfMatch()); + Assert.assertEquals(true, new JSONScanner("4000-10-02").scanISO8601DateIfMatch()); + Assert.assertEquals(true, new JSONScanner("5000-10-02").scanISO8601DateIfMatch()); + Assert.assertEquals(true, new JSONScanner("6000-10-02").scanISO8601DateIfMatch()); + Assert.assertEquals(true, new JSONScanner("7000-10-02").scanISO8601DateIfMatch()); + Assert.assertEquals(true, new JSONScanner("8000-10-02").scanISO8601DateIfMatch()); + Assert.assertEquals(false, new JSONScanner("A000-10-02").scanISO8601DateIfMatch()); + Assert.assertEquals(false, new JSONScanner("a000-10-02").scanISO8601DateIfMatch()); Assert.assertEquals(false, new JSONScanner("1997").scanISO8601DateIfMatch()); Assert.assertEquals(false, new JSONScanner("1997-2-2").scanISO8601DateIfMatch()); Assert.assertEquals(true, new JSONScanner("1997-02-02").scanISO8601DateIfMatch()); diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__nextToken.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__nextToken.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__x.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__x.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_colon.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_colon.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_false.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_false.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ident.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ident.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_int.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_int.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_isEOF.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_isEOF.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_long.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_long.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_new.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_new.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_null.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_null.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldDouble.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldDouble.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldFloat.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldFloat.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldInt.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldInt.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldLong.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldLong.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldStringArray.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldStringArray.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanSymbol.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanSymbol.java old mode 100755 new mode 100644 index 393a5e5113..395ea6bbc0 --- a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanSymbol.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanSymbol.java @@ -1,5 +1,6 @@ package com.alibaba.json.bvt.parser; +import com.alibaba.fastjson.util.TypeUtils; import org.junit.Assert; import junit.framework.TestCase; @@ -7,6 +8,9 @@ import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.SymbolTable; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime; + /** * 测试字符':'的处理 * @@ -67,12 +71,40 @@ public void test_7() throws Exception { Assert.assertEquals(JSONScanner.NOT_MATCH, lexer.matchStat()); } + public void test_8() throws Exception { + JSONScanner lexer = new JSONScanner("\"value\": \"MINUTES\","); + long hashCode = lexer.scanFieldSymbol("\"value\":".toCharArray()); + assertEquals(189130438399835214L, hashCode); + Assert.assertEquals(JSONScanner.VALUE, lexer.matchStat()); + } + + public void test_9() throws Exception { + JSONScanner lexer = new JSONScanner("\"value\":\"MINUTES\","); + long hashCode = lexer.scanFieldSymbol("\"value\":".toCharArray()); + assertEquals(189130438399835214L, hashCode); + Assert.assertEquals(JSONScanner.VALUE, lexer.matchStat()); + } + + public void test_10() throws Exception { + JSONScanner lexer = new JSONScanner(" \"value\":\"MINUTES\","); + long hashCode = lexer.scanFieldSymbol("\"value\":".toCharArray()); + assertEquals(189130438399835214L, hashCode); + Assert.assertEquals(JSONScanner.VALUE, lexer.matchStat()); + } + + public void test_11() throws Exception { + JSONScanner lexer = new JSONScanner(" \"value\":\"A\","); + long hashCode = lexer.scanFieldSymbol("\"value\":".toCharArray()); + assertEquals(TypeUtils.fnv1a_64("A"), hashCode); + Assert.assertEquals(JSONScanner.VALUE, lexer.matchStat()); + } + static long fnv_hash(String text) { - long hash = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; for (int i = 0; i < text.length(); ++i) { char c = text.charAt(i); hash ^= c; - hash *= 0x100000001b3L; + hash *= fnv1a_64_magic_prime; } return hash; } diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_singQuoteString.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_singQuoteString.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_symbol.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_symbol.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_true.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_true.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/MapResetTest.java b/src/test/java/com/alibaba/json/bvt/parser/MapResetTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/MaximumLevelTest.java b/src/test/java/com/alibaba/json/bvt/parser/MaximumLevelTest.java new file mode 100644 index 0000000000..664dd00d27 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/MaximumLevelTest.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import junit.framework.TestCase; + +public class MaximumLevelTest extends TestCase { + public void test_for_maximum() throws Exception { + int[] chars = new int[] {0x5b, 0x7b}; + + for (int ch : chars) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 1000; ++i) { + sb.append((char) ch); + } + + Exception error = null; + try { + JSON.parseObject(sb.toString()); + } catch (JSONException ex) { + error = ex; + } + + assertNotNull(error); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/NullCheckTest.java b/src/test/java/com/alibaba/json/bvt/parser/NullCheckTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/ProductViewTest.java b/src/test/java/com/alibaba/json/bvt/parser/ProductViewTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyMapTest2.java b/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyMapTest2.java index 7da19935e3..c817de0ab8 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyMapTest2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyMapTest2.java @@ -14,7 +14,7 @@ public void test_readOnlyNullList() throws Exception { String text = "{\"values\":{\"a\":{}}}"; Entity entity = JSON.parseObject(text, Entity.class); Assert.assertNotNull(entity); - Assert.assertNull(entity.values); + Assert.assertNotNull(entity.values); } public static class Entity { diff --git a/src/test/java/com/alibaba/json/bvt/parser/SafeModeTest.java b/src/test/java/com/alibaba/json/bvt/parser/SafeModeTest.java new file mode 100644 index 0000000000..0dce0cfe85 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/SafeModeTest.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class SafeModeTest extends TestCase { + public void test_for_safeMode() throws Exception { + ParserConfig config = new ParserConfig(); + + String str = "{\"@type\":\"com.alibaba.json.bvt.parser.SafeModeTest$Entity\"}"; + JSON.parse(str); + + { + Exception error = null; + try { + JSON.parse(str, config, Feature.SafeMode); + } + catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + { + Exception error = null; + try { + config.setSafeMode(true); + JSON.parse(str, config); + } + catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + } + + @JSONType + public static class Entity { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TestException.java b/src/test/java/com/alibaba/json/bvt/parser/TestException.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty.java b/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty2.java b/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TestUTF8.java b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_2.java b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeReferenceTest.java b/src/test/java/com/alibaba/json/bvt/parser/TypeReferenceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest.java old mode 100755 new mode 100644 index fb6e118db9..c5f41c9934 --- a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest.java @@ -3,12 +3,14 @@ import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TimeZone; import junit.framework.TestCase; @@ -243,6 +245,11 @@ public void test_cast_to_Timestamp_null2() throws Exception { Assert.assertEquals(null, TypeUtils.castToTimestamp(null)); } + public void test_cast_to_Timestamp_1970_01_01_00_00_00() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + Assert.assertEquals(new Timestamp(0), TypeUtils.castToTimestamp("1970-01-01 08:00:00")); + } + public void test_cast_to_BigDecimal_same() throws Exception { BigDecimal value = new BigDecimal("123"); Assert.assertEquals(true, value == TypeUtils.castToBigDecimal(value)); @@ -291,9 +298,9 @@ public void test_cast_to_Timestamp_calendar() throws Exception { Assert.assertEquals(new java.sql.Timestamp(millis), json.getObject("date", java.sql.Timestamp.class)); } - public void test_cast_to_Timestamp_error() throws Exception { + public void test_cast_to_Timestamp_not_error() throws Exception { JSONObject json = new JSONObject(); - json.put("date", 0); + json.put("date", -1); JSONException error = null; try { @@ -301,7 +308,8 @@ public void test_cast_to_Timestamp_error() throws Exception { } catch (JSONException e) { error = e; } - Assert.assertNotNull(error); + Assert.assertNull(error); + Assert.assertEquals(new Timestamp(-1L), (java.sql.Timestamp) json.getObject("date", java.sql.Timestamp.class)); } public void test_cast_ab() throws Exception { @@ -375,7 +383,7 @@ public void test_3() throws Exception { public static class User { - private long id; + private long id; private String name; public long getId() { diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest2.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest3.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest3.java old mode 100755 new mode 100644 index 4caf7e88dc..0f30d5280b --- a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest3.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest3.java @@ -27,13 +27,7 @@ public void test_enum_2() throws Exception { } public void test_error() throws Exception { - Exception error = null; - try { - TypeUtils.castToEnum("\"A1\"", Type.class, null); - } catch (Exception ex) { - error = ex; - } - Assert.assertNotNull(error); + assertNull(TypeUtils.castToEnum("\"A1\"", Type.class, null)); } public void test_error_1() throws Exception { diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest4.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBigDecimal.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBigDecimal.java new file mode 100644 index 0000000000..3c73e72770 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBigDecimal.java @@ -0,0 +1,69 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * 强转BigDecimal测试用例 + */ +public class TypeUtilsTest_castToBigDecimal extends TestCase { + + /** + * NaN和正负无穷大的时候转BigDecimal都会报转换异常,修改为返回null + */ + public void test_FloatNanInfinite() throws Exception { + // 正无穷大 + assertNull(TypeUtils.castToBigDecimal(1.0f / 0.0f)); + // 负无穷大 + assertNull(TypeUtils.castToBigDecimal(-1.0f / 0.0f)); + // NaN + assertNull(TypeUtils.castToBigDecimal(0.0f / 0.0f)); + } + + /** + * NaN和正负无穷大的时候转BigDecimal都会报转换异常,修改为返回null + */ + public void test_DoubleNanInfinite() throws Exception { + // 正无穷大 + assertNull(TypeUtils.castToBigDecimal(1.0d / 0.0d)); + // 负无穷大 + assertNull(TypeUtils.castToBigDecimal(-1.0d / 0.0d)); + // NaN + assertNull(TypeUtils.castToBigDecimal(0.0d / 0.0d)); + } + + /** + * NaN和正负无穷大的时候转BigDecimal都会报转换异常,修改为返回null + */ + public void test_FloatNanInfinite_BigInteger() throws Exception { + // 正无穷大 + assertNull(TypeUtils.castToBigInteger(1.0f / 0.0f)); + // 负无穷大 + assertNull(TypeUtils.castToBigInteger(-1.0f / 0.0f)); + // NaN + assertNull(TypeUtils.castToBigInteger(0.0f / 0.0f)); + } + + /** + * NaN和正负无穷大的时候转BigDecimal都会报转换异常,修改为返回null + */ + public void test_DoubleNanInfinite_BigInteger() throws Exception { + // 正无穷大 + assertNull(TypeUtils.castToBigInteger(1.0d / 0.0d)); + // 负无穷大 + assertNull(TypeUtils.castToBigInteger(-1.0d / 0.0d)); + // NaN + assertNull(TypeUtils.castToBigInteger(0.0d / 0.0d)); + } + + public void test_nullString_biginteger() throws Exception { + assertNull(TypeUtils.castToBigInteger("")); + assertNull(TypeUtils.castToBigInteger("null")); + } + + public void test_nullString_bigdecimal() throws Exception { + assertNull(TypeUtils.castToBigDecimal("")); + assertNull(TypeUtils.castToBigDecimal("null")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBigInteger.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBigInteger.java new file mode 100644 index 0000000000..9e39bae434 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBigInteger.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; +import org.junit.Assert; + +/** + * 强转BigInteger测试用例 + */ +public class TypeUtilsTest_castToBigInteger extends TestCase { + + /** + * NaN和正负无穷大的时候转BigInteger都会报转换异常,修改为返回null + */ + public void test_FloatNanInfinite() throws Exception { + // 正无穷大 + Assert.assertNull(TypeUtils.castToBigInteger(1.0f / 0.0f)); + // 负无穷大 + Assert.assertNull(TypeUtils.castToBigInteger(-1.0f / 0.0f)); + // NaN + Assert.assertNull(TypeUtils.castToBigInteger(0.0f / 0.0f)); + } + + /** + * NaN和正负无穷大的时候转BigInteger都会报转换异常,修改为返回null + */ + public void test_DoubleNanInfinite() throws Exception { + // 正无穷大 + Assert.assertNull(TypeUtils.castToBigInteger(1.0d / 0.0d)); + // 负无穷大 + Assert.assertNull(TypeUtils.castToBigInteger(-1.0d / 0.0d)); + // NaN + Assert.assertNull(TypeUtils.castToBigInteger(0.0d / 0.0d)); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsToJSONTest.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsToJSONTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtils_parseDouble_Test.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtils_parseDouble_Test.java new file mode 100644 index 0000000000..46a04583f6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtils_parseDouble_Test.java @@ -0,0 +1,95 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; + +import java.util.Random; + +public class TypeUtils_parseDouble_Test extends TestCase { + public void test_0() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Float.toString(r.nextFloat()); + assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str)); + } + } + + public void test_0_d() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Double.toString(r.nextDouble()); + assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str)); + } + } + + + public void test_1() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Integer.toString(r.nextInt()); + assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str)); + } + } + + public void test_2() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Integer.toString(r.nextInt(1000000000)); + assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str)); + } + } + + public void test_3() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Long.toString(r.nextLong()); + assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str)); + } + } + + public void test_4() throws Exception { + String[] array = new String[] { + "0.34856254", + "1", + "12", + "123", + "1234", + "12345", + "123456", + "1234567", + "12345678", + "123456789", + "1234567890", + ".1" + ,"1.1" + ,"12.1" + , "123.1" + , "1234.1" + , "12345.1" + , "123456.1" + , "1234567.1" + , "12345678.1" + , "0.1" + , "0.12" + , "0.123" + , "0.1234" + , "0.12345" + , "0.123456" + , "0.1234567" + , "0.12345678" + , "0.123456789" + , "0.1234567891" + , "0.12345678901" + , "0.123456789012" + }; + + for (String str : array) { + assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str)); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtils_parseFloat_Test.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtils_parseFloat_Test.java new file mode 100644 index 0000000000..3db0fdd265 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtils_parseFloat_Test.java @@ -0,0 +1,85 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; + +import java.util.Random; + +public class TypeUtils_parseFloat_Test extends TestCase { + public void test_0() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Float.toString(r.nextFloat()); + assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str)); + } + } + + public void test_1() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Integer.toString(r.nextInt()); + assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str)); + } + } + + public void test_2() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Integer.toString(r.nextInt(1000000000)); + assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str)); + } + } + + public void test_3() throws Exception { + Random r = new Random(); + + for (int i = 0; i < 1000 * 1000; ++i) { + String str = Long.toString(r.nextLong()); + assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str)); + } + } + + public void test_4() throws Exception { + String[] array = new String[] { + "0.34856254", + "1", + "12", + "123", + "1234", + "12345", + "123456", + "1234567", + "12345678", + "123456789", + "1234567890", + ".1" + ,"1.1" + ,"12.1" + , "123.1" + , "1234.1" + , "12345.1" + , "123456.1" + , "1234567.1" + , "12345678.1" + , "0.1" + , "0.12" + , "0.123" + , "0.1234" + , "0.12345" + , "0.123456" + , "0.1234567" + , "0.12345678" + , "0.123456789" + , "0.1234567891" + , "0.12345678901" + , "0.123456789012" + }; + + for (String str : array) { + assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str)); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayLexerTest_symbol.java b/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayLexerTest_symbol.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayParseTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest.java b/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest.java new file mode 100644 index 0000000000..d0adbfe887 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest.java @@ -0,0 +1,97 @@ +package com.alibaba.json.bvt.parser.array; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class BeanToArrayAutoTypeTest extends TestCase { + public void test_for_issue_x() throws Exception { + String json = "[\"@type\":\"B\",\"chengchao\",1001]"; + A a = JSON.parseObject(json, A.class, Feature.SupportAutoType, Feature.SupportArrayToBean); + B b = (B) a; + } + + public void test_for_issue() throws Exception { + Model m = new Model(); + m.value = new B(1001, "chengchao"); + String json = JSON.toJSONString(m); + assertEquals("{\"value\":[\"@type\":\"B\",\"chengchao\",1001]}", json); + + Model m1 = JSON.parseObject(json, Model.class, Feature.SupportAutoType); + assertEquals(m.value.getClass(), m1.value.getClass()); + assertEquals(json, JSON.toJSONString(m1)); + } + + public void test_for_issue_1() throws Exception { + Model m = new Model(); + m.value = new C(1001, 58); + String json = JSON.toJSONString(m); + assertEquals("{\"value\":[\"@type\":\"C\",58,1001]}", json); + + Model m1 = JSON.parseObject(json, Model.class, Feature.SupportAutoType); + assertEquals(m.value.getClass(), m1.value.getClass()); + assertEquals(json, JSON.toJSONString(m1)); + } + + @JSONType(seeAlso = {B.class, C.class}) + public static class A { + protected int id; + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + } + + @JSONType(typeName = "B", orders = {"name", "id"}) + public static class B extends A { + private String name; + + public B() { + + } + + public B(int id, String name) { + this.id = id; + this.name = name; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + } + + @JSONType(typeName = "C", orders = {"age", "id"}) + public static class C extends A { + public int age; + + public C() { + + } + + public C(int id, int age) { + this.id = id; + this.age = age; + } + } + + public static class Model { + @JSONField(serialzeFeatures = {SerializerFeature.BeanToArray, SerializerFeature.WriteClassName} + , parseFeatures = Feature.SupportArrayToBean) + public A value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest2.java b/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest2.java new file mode 100644 index 0000000000..327d986327 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest2.java @@ -0,0 +1,77 @@ +package com.alibaba.json.bvt.parser.array; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class BeanToArrayAutoTypeTest2 + extends TestCase { + public void test_for_issue() throws Exception { + Model m = new Model(); + m.value = new B(1001, "chengchao"); + String json = JSON.toJSONString(m); + assertEquals("{\"value\":[\"@type\":\"B\",\"chengchao\",1001]}", json); + + Model m1 = JSON.parseObject(json, Model.class, Feature.SupportAutoType); + assertEquals(m.value.getClass(), m1.value.getClass()); + assertEquals(json, JSON.toJSONString(m1)); + } + + public void test_for_issue_1() throws Exception { + Model m = new Model(); + m.value = new C(1001, 58); + String json = JSON.toJSONString(m); + assertEquals("{\"value\":[\"@type\":\"C\",58,1001]}", json); + + Model m1 = JSON.parseObject(json, Model.class, Feature.SupportAutoType); + assertEquals(m.value.getClass(), m1.value.getClass()); + assertEquals(json, JSON.toJSONString(m1)); + } + + @JSONType(seeAlso = {B.class, C.class} + , serialzeFeatures = {SerializerFeature.BeanToArray, SerializerFeature.WriteClassName} + , parseFeatures = Feature.SupportArrayToBean) + public static class A { + public int id; + } + + @JSONType(typeName = "B", orders = {"name", "id"} + , serialzeFeatures = {SerializerFeature.BeanToArray, SerializerFeature.WriteClassName} + , parseFeatures = Feature.SupportArrayToBean) + public static class B extends A { + public String name; + + public B() { + + } + + public B(int id, String name) { + this.id = id; + this.name = name; + } + } + + @JSONType(typeName = "C", orders = {"age", "id"} + , serialzeFeatures = {SerializerFeature.BeanToArray, SerializerFeature.WriteClassName} + , parseFeatures = Feature.SupportArrayToBean) + public static class C extends A { + public int age; + + public C() { + + } + + public C(int id, int age) { + this.id = id; + this.age = age; + } + } + + public static class Model { + public A value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest3.java b/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest3.java new file mode 100644 index 0000000000..845e40e0ca --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/array/BeanToArrayAutoTypeTest3.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.parser.array; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.util.List; + +public class BeanToArrayAutoTypeTest3 + extends TestCase { + public void test_beanToArray() throws Exception { + Topology topology = JSON.parseObject("{\"maps\":[[\"@type\":\"Log\"]]}", Topology.class); + assertEquals(LogSourceMeta.class, topology.maps.get(0).getClass()); + } + + public void test_beanToArray1() throws Exception { + Topology topology = JSON.parseObject("{\"maps\":[[\"@type\":\"Log\",123]]}", Topology.class); + assertEquals(LogSourceMeta.class, topology.maps.get(0).getClass()); + assertEquals(123, ((LogSourceMeta) topology.maps.get(0)).id); + } + + @JSONType(typeName = "Log") + public static class LogSourceMeta extends MapTaskMeta { + public int id; + } + + @JSONType(seeAlso = {LogSourceMeta.class, OtherMeta.class}, parseFeatures = Feature.SupportArrayToBean) + public static class MapTaskMeta { + + } + + @JSONType(typeName = "Other") + public static class OtherMeta extends MapTaskMeta { + + } + + public static class Topology { + public List maps; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest0.java b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest0.java index 00da232b97..146d4f8e53 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest0.java +++ b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest0.java @@ -16,7 +16,29 @@ public void test_0() throws Exception { assertEquals(123, model2.id); } + public void test_nested() { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.autoType.AutoTypeTest0$ModelNested\",\"id\":123, \"nested\":{\"@type\":\"com.alibaba.json.bvt.parser.autoType.AutoTypeTest0$ModelNested\",\"id\":456, \"nested\":null}}"; + + ModelNested model = JSON.parseObject(text, ModelNested.class); + assertEquals(123, model.id); + ModelNested nested1 = model.nested; + assertEquals(456, nested1.id); + assertNull(nested1.nested); + + ModelNested model2 = (ModelNested) JSON.parse(text); + assertEquals(123, model2.id); + ModelNested nested2 = model2.nested; + assertEquals(456, nested2.id); + assertNull(nested2.nested); + } + + public static class Model { public int id; } + + public static class ModelNested { + public int id; + public ModelNested nested; + } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest3_deny.java b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest3_deny.java new file mode 100644 index 0000000000..cddbf67a76 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest3_deny.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.parser.autoType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class AutoTypeTest3_deny extends TestCase { + public void test_for_x() throws Exception { + Exception error = null; + try { + String json = "{\"@type\":\"java.util.logging.FileHandler\",\"pattern\":\"xxx.txt\"}"; + Object obj = JSON.parse(json, Feature.SupportAutoType); + } catch (Exception ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_for_jar() throws Exception { + Exception error = null; + try { + String json = "{\"@type\":\"java.util.jar.JarFile.JarFile\",\"name\":\"xxx.txt\"}"; + Object obj = JSON.parse(json, Feature.SupportAutoType); + } catch (Exception ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_for_array() throws Exception { + Exception error = null; + try { + String json = "{\"@type\":\"[java.util.jar.JarFile.JarFile\",\"name\":\"xxx.txt\"}"; + Object obj = JSON.parse(json, Feature.SupportAutoType); + } catch (Exception ex) { + ex.printStackTrace(); + error = ex; + } + assertNotNull(error); + } + + + public void test_for_array_1() throws Exception { + Exception error = null; + try { + String json = "{\"@type\":\"L[java.util.jar.JarFile.JarFile;\",\"name\":\"xxx.txt\"}"; + Object obj = JSON.parse(json, Feature.SupportAutoType); + } catch (Exception ex) { + ex.printStackTrace(); + error = ex; + } + assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest5.java b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest5.java new file mode 100644 index 0000000000..a6b0ee4b0e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest5.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.parser.autoType; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.util.TypeUtils; +import junit.framework.TestCase; + +import java.lang.reflect.Field; +import java.util.concurrent.ConcurrentMap; + +public class AutoTypeTest5 extends TestCase { + ConcurrentMap> mappings; + + private static int count_x = 0; + + protected void setUp() throws Exception { + Field field = TypeUtils.class.getDeclaredField("mappings"); + field.setAccessible(true); + + mappings = (ConcurrentMap>) field.get(null); + } + + public void test_0() throws Exception { + ParserConfig config = new ParserConfig(); + assertFalse(config.isAutoTypeSupport()); + JSON.parseObject("{\"value\":{\"@type\":\"com.alibaba.json.bvt.parser.autoType.AutoTypeTest5$V1\"}}", Model.class, config); + + int size = mappings.size(); + Exception error = null; + try { + JSON.parseObject("{\"value\":{\"@type\":\"com.alibaba.json.bvt.parser.autoType.AutoTypeTest5$X1\"}}", Model.class, config); + } catch (JSONException x) { + error = x; + } + assertNotNull(error); + assertEquals(0, count_x); + assertEquals(size, mappings.size()); + } + + public static class Model { + public V0 value; + } + + public static class V0 { + + } + + public static class V1 extends V0 { + + } + + public static class X1 { + static { + count_x++; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest6.java b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest6.java new file mode 100644 index 0000000000..37aba9d052 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest6.java @@ -0,0 +1,10 @@ +package com.alibaba.json.bvt.parser.autoType; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class AutoTypeTest6 extends TestCase { + public void test_0() throws Exception { + JSON.parseObject("{\"@type\":\"com.alibaba.fastjson.util.AntiCollisionHashMap\"}"); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest7.java b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest7.java new file mode 100644 index 0000000000..99719a3997 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/autoType/AutoTypeTest7.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.parser.autoType; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.springframework.cache.support.NullValue; + +public class AutoTypeTest7 extends TestCase { + public void test_0() throws Exception { + JSON.parseObject("{\"@type\":\"java.util.Collections$UnmodifiableMap\"}"); + } + + public void test_1() throws Exception { + JSON.parseObject("{\"@type\":\"java.util.Collections$UnmodifiableMap\",\"id\":123}"); + } + + public void test_2() throws Exception { + NullValue value = (NullValue) JSON.parseObject("{\"@type\":\"org.springframework.cache.support.NullValue\"}", Object.class); + assertNotNull(value); + } + + public void test_3() throws Exception { + Exception ex = (Exception) JSON.parseObject("{\"@type\":\"org.springframework.dao.CannotAcquireLockException\",\"message\":\"xxx\"}", Object.class); + assertEquals("xxx", ex.getMessage()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug0.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug2.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_changhao.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_changhao.java new file mode 100644 index 0000000000..17082e27f9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_changhao.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.parser.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.PropertyNamingStrategy; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import junit.framework.TestCase; + +public class Bug_for_changhao extends TestCase { + public void test_for_bug() throws Exception { + String s = "{\"intValue\":1,\"stringValue\":\"abc\"}"; + ParserConfig parseConfig = new ParserConfig(); + parseConfig.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase; + TestClass t = JSON.parseObject(s, TestClass.class, parseConfig, Feature.DisableFieldSmartMatch); + System.out.println(JSON.toJSONString(t)); + } + + static class TestClass { + String stringValue; + int intValue; + + /** + * Getter method for property stringValue. + * + * @return property value of stringValue + */ + public String getStringValue() { + return stringValue; + } + + /** + * Setter method for property stringValue. + * + * @param stringValue value to be assigned to property stringValue + */ + public TestClass setStringValue(String stringValue) { + this.stringValue = stringValue; + return this; + } + + /** + * Getter method for property intValue. + * + * @return property value of intValue + */ + public int getIntValue() { + return intValue; + } + + /** + * Setter method for property intValue. + * + * @param intValue value to be assigned to property intValue + */ + public TestClass setIntValue(int intValue) { + this.intValue = intValue; + return this; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_dingzhu.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_dingzhu.java new file mode 100644 index 0000000000..e4d4b0eabd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_dingzhu.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.parser.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.*; +import junit.framework.TestCase; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +public class Bug_for_dingzhu extends TestCase { + public void test_0() throws Exception { + HashMap params = new HashMap(); + params.put("notExitAfterVid", false); + params.put("VIData", "{\"config\":{\"noTokens\":\"Y\",\"stopReport\":\"Y\"}"); + StupidObject so = new StupidObject(); + so.setParams(params); + SerializeFilter[] filters = new SerializeFilter[] { new DumbValueFilter()}; + String jsonString = JSON.toJSONString(so, new SerializeConfig(), filters, + SerializerFeature.NotWriteDefaultValue, SerializerFeature.IgnoreErrorGetter, + SerializerFeature.QuoteFieldNames); + } + + private class DumbValueFilter implements ContextValueFilter { + public Object process(BeanContext context, Object object, String name, Object value) { + if (context == null) { + return object; + } + + Field field = context.getField(); + return value; + } + } + + private class StupidObject { + private Map params; + + public Map getParams() { + return params; + } + + public void setParams(Map params) { + this.params = params; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_guanxiu.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_guanxiu.java new file mode 100644 index 0000000000..b90b26f7fa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_guanxiu.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.parser.bug; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.List; + +/** + * 这个bug由李先锋反馈 + * @author wenshao + * + */ +public class Bug_for_guanxiu extends TestCase { + + public void test_long_list() throws Exception { + String str = "{\"tnt_inst_id\":\"MYBKC1CN\",\"interface_id\":\"ant.mybank.loantrade.existvalidloan.query @1.0.0\",\"template_id\":\"EX-SYNC-IN-\n" + + "\n" + + "OPEN-API\"}"; + + JSON.parseObject(str); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_kongmu.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_kongmu.java new file mode 100644 index 0000000000..9526534d99 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_kongmu.java @@ -0,0 +1,103 @@ +package com.alibaba.json.bvt.parser.bug; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class Bug_for_kongmu extends TestCase { + public void test_for_bug() throws Exception { + String JSON_STRING = "{\n" + + "\t\"body\":\"parentBody\",\n" + + "\t\"name\":\"child-1\",\n" + + "\t\"result\":{\n" + + "\t\t\"code\":11\n" + + "\t},\n" + + "\t\"toy\":{\n" + + "\t\t\"type\":\"toytype\"\n" + + "\t}\n" + + "}"; + + JSON.parseObject(JSON_STRING, Child.class); + + } + + + public static class BaseDO { + private String body; + private Result result; + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public Result getResult() { + return result; + } + + public void setResult(Result result) { + this.result = result; + } + + // 在1.2.27中能过,在1.2.48不能过 + public class Result { + + + // 在1.2.48中,必须为static + //public static class Result { + + public Result() { + this.code = 11; + } + + private int code; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + } + } + + public static class Child extends BaseDO { + public String name; + public Toy toy; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Toy getToy() { + return toy; + } + + public void setToy(Toy toy) { + this.toy = toy; + } + + // 这儿不是static,在1.2.27、1.2.48都能过 + public class Toy { + private String type; + + public Toy() { + this.type = "toyType"; + } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lingzhi.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lingzhi.java new file mode 100644 index 0000000000..590aa1e3dc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lingzhi.java @@ -0,0 +1,269 @@ +package com.alibaba.json.bvt.parser.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.List; + +public class Bug_for_lingzhi extends TestCase { + public void test_0() throws Exception { + String str = "[\n" + + "{\n" + + "\"isDefault\":false,\n" + + "\"msgId\": \"expireTransitionChange\",\n" + + "\"msgText\": \"xxx\",\n" + + "\"extMsgId\": \"promptInformation\",\n" + + "\"extMsgText\": \"xxx\",\n" + + "\"instChangeType\": 1,\n" + + "\"rule\": {\n" + + "\"aliUid\":[39314],\n" + + "\"regionNo\":[]\n" + + "}\n" + + "},\n" + + "{\n" + + "\"isDefault\":true,\n" + + "\"msgId\": \"expireTransitionUnChange\",\n" + + "\"msgText\": \"xxx\",\n" + + "\"extMsgId\": \"Prompt information\",\n" + + "\"extMsgText\": \"xxx\",\n" + + "\"instChangeType\": 0,\n" + + "\"rule\": {\n" + + "\"aliUid\":[],\n" + + "\"regionNo\":[]\n" + + "}\n" + + "},\n" + + "{\n" + + "\"isDefault\":false,\n" + + "\"msgId\": \"expireTransitionChange\",\n" + + "\"msgText\": \"xxx\",\n" + + "\"extMsgId\": \"Prompt information\",\n" + + "\"extMsgText\": \"你好B\",\n" + + "\"instChangeType\": 1,\n" + + "\"rule\": {\n" + + "\"aliUid\":[111],\n" + + "\"regionNo\":[]\n" + + "}\n" + + "}\n" + + "]"; + +// String pstr = JSON.toJSONString(JSON.parse(str), SerializerFeature.PrettyFormat); +// System.out.println(pstr); + + JSON.parseObject(str, new TypeReference>(){}); + } + + public static class EcsTransitionDisplayedMsgConfig { + + /** + * 是否默认文案 + */ + private Boolean isDefault; + + /** + * 展示的文案Id + */ + private String msgId; + + /** + * 展示的文案信息 + */ + private String msgText; + + /** + * 扩展文案Id + */ + private String extMsgId; + + /** + * 扩展文案信息 + */ + private String extMsgText; + + + private Integer instChangeType; + + /** + * 文案对应的规则 + */ + private EcsTransitionConfigRule rule; + + public String getMsgText() { + return msgText; + } + + public void setMsgText(String msgText) { + this.msgText = msgText; + } + + public String getMsgId() { + return msgId; + } + + public void setMsgId(String msgId) { + this.msgId = msgId; + } + + public EcsTransitionConfigRule getRule() { + return rule; + } + + public void setRule(EcsTransitionConfigRule rule) { + this.rule = rule; + } + + public Integer getInstChangeType() { + return instChangeType; + } + + public void setInstChangeType(Integer instChangeType) { + this.instChangeType = instChangeType; + } + + public Boolean getIsDefault() { + return this.isDefault; + } + + public void setIsDefault(Boolean isDefault) { + this.isDefault = isDefault; + } + + public String getExtMsgId() { + return extMsgId; + } + + public void setExtMsgId(String extMsgId) { + this.extMsgId = extMsgId; + } + + public String getExtMsgText() { + return extMsgText; + } + + public void setExtMsgText(String extMsgText) { + this.extMsgText = extMsgText; + } + } + + public static class EcsTransitionConfigRule { + + + /** 0 过保迁移, 1 非过保迁移 **/ + private List transType; + + /** 比如:cn-qingdao-cm5-a01 **/ + private List regionNo; + + private List aliUid; + + private List bid; + + /** ecs,disk **/ + private List resourceType; + + private List zoneId; + + private List targetZoneId; + + private List networkTransType; + + /** instance type 实例规格 **/ + private List instanceType; + + /** 磁盘类型 ioX **/ + private List ioX; + + private List instanceId; + + + public List getTransType() { + return transType; + } + + public void setTransType(List transType) { + this.transType = transType; + } + + public List getRegionNo() { + return regionNo; + } + + public void setRegionNo(List regionNo) { + this.regionNo = regionNo; + } + + public List getAliUid() { + return aliUid; + } + + public void setAliUid(List aliUid) { + this.aliUid = aliUid; + } + + public List getBid() { + return bid; + } + + public void setBid(List bid) { + this.bid = bid; + } + + public List getResourceType() { + return resourceType; + } + + public void setResourceType(List resourceType) { + this.resourceType = resourceType; + } + + public List getZoneId() { + return zoneId; + } + + public void setZoneId(List zoneId) { + this.zoneId = zoneId; + } + + public List getTargetZoneId() { + return targetZoneId; + } + + public void setTargetZoneId(List targetZoneId) { + this.targetZoneId = targetZoneId; + } + + public List getNetworkTransType() { + return networkTransType; + } + + public void setNetworkTransType(List networkTransType) { + this.networkTransType = networkTransType; + } + + public List getInstanceType() { + return instanceType; + } + + public void setInstanceType(List instanceType) { + this.instanceType = instanceType; + } + + public List getIoX() { + return ioX; + } + + public void setIoX(List ioX) { + this.ioX = ioX; + } + + public List getInstanceId() { + return instanceId; + } + + public void setInstanceId(List instanceId) { + this.instanceId = instanceId; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lixianfeng.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lixianfeng.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_yihaodian.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_yihaodian.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_zitao.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_zitao.java new file mode 100644 index 0000000000..50e7e014ec --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_zitao.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.BeanContext; +import com.alibaba.fastjson.serializer.ContextValueFilter; +import junit.framework.TestCase; + +public class Bug_for_zitao extends TestCase { + public void test_for_issue() throws Exception { + Model m = new Model(); + ContextValueFilter v = new ContextValueFilter() { + + public Object process(BeanContext context, Object object, String name, Object value) { + if (value == null && context != null && Number.class.isAssignableFrom(context.getFieldClass())) { + return -1; + } + return null; + } + }; + + String json = JSON.toJSONString(m, v); + assertEquals("{\"value\":-1}", json); + } + + public static class Model { + public Number value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorFactoryTest.java b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorFactoryTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest.java b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest10.java b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest10.java new file mode 100644 index 0000000000..c66f7bf714 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest10.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.parser.creator; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class JSONCreatorTest10 extends TestCase { + public void test_for_yk() throws Exception { + String jsonString = "{\"link\":\"http://lqgzs.org/fsqhwlnf\",\"text\":\"乐动力专享\"}"; + JSONObject headerJSON = JSONObject.parseObject(jsonString); + HeaderDTO headerDTO = headerJSON.toJavaObject(HeaderDTO.class); + + assertEquals("http://lqgzs.org/fsqhwlnf", headerDTO.link); + assertEquals("乐动力专享", headerDTO.title); + } + + public static class HeaderDTO { + private String title; + private String link; + + @JSONCreator + public HeaderDTO(@JSONField(name = "text") String title,@JSONField(name = "link") String link) { + this.title = title; + this.link = link; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest11.java b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest11.java new file mode 100644 index 0000000000..f8da51fc67 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest11.java @@ -0,0 +1,99 @@ +package com.alibaba.json.bvt.parser.creator; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.List; + +public class JSONCreatorTest11 extends TestCase { + public void test_for_yk() throws Exception { + String jsonString = "[{\"image\":\"https://gw.alicdn.com/tfs/TB1Dtk.ay6guuRjy1XdXXaAwpXa-204-154.png\"," + + "\"labelNot\":\"zh*179753,zh*179745,zh*179743,zh*178230,zh*180695\",\"link\":\"https://alimarket.m.taobao" + + ".com/markets/alisports/3_1weeklist\",\"title\":\"热卖榜单\",\"desc\":\"大家都在买\"}]"; + + JSONArray array = JSON.parseArray(jsonString); + List dtoList = array.toJavaList(RecommendDTO.class); + assertEquals("热卖榜单", dtoList.get(0).title); + + System.out.println(JSON.VERSION); + } + + public static class RecommendDTO { + private String image; + private String link; + private String title; + private String desc; + private String labels; + private String labelNot; + + + @JSONCreator + public RecommendDTO(@JSONField(name = "image") String image, @JSONField(name = "link") String link, + @JSONField(name = "title") String title, @JSONField(name = "desc") String desc, + @JSONField(name = "labels") String labels, @JSONField(name = "labelNot") String labelNot) { + final String PREFIX = "//"; + this.desc = desc; + this.title = title; + this.labelNot = labelNot; + this.labels = labels; + if (image.startsWith(PREFIX)) { + this.image = image.substring(2); + } + if (link.startsWith(PREFIX)) { + this.link = link.substring(2); + } + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getLabels() { + return labels; + } + + public void setLabels(String labels) { + this.labels = labels; + } + + public String getLabelNot() { + return labelNot; + } + + public void setLabelNot(String labelNot) { + this.labelNot = labelNot; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest4.java b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest4.java index d9b2174fb5..e4480a566c 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest4.java +++ b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest4.java @@ -12,20 +12,18 @@ public class JSONCreatorTest4 extends TestCase { public void test_create_error() throws Exception { - Exception error = null; - try { - JSON.parseObject("{\"id\":1001,\"name\":\"wenshao\",\"obj\":{\"$ref\":\"$\"}}", Entity.class); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); + Entity entity = JSON.parseObject("{\"id\":1001,\"name\":\"wenshao\",\"obj\":{\"$ref\":\"$\"}}", Entity.class); + assertNotNull(entity); + assertEquals(1001, entity.id); + assertEquals("wenshao", entity.name); + assertSame(entity, entity.obj); } public static class Entity { private final int id; private final String name; - private final Entity obj; + private Entity obj; @JSONCreator public Entity(@JSONField(name = "id") int id, @JSONField(name = "name") String name, @@ -47,6 +45,9 @@ public Entity getObj() { return obj; } + public void setObj(Entity obj) { + this.obj = obj; + } } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest9.java b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest9.java new file mode 100644 index 0000000000..2c82ee654b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/creator/JSONCreatorTest9.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.parser.creator; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class JSONCreatorTest9 extends TestCase { + public void test_for_yk() throws Exception { + String text = "{\"videoid\":\"XNzBxOCU0NjYxCg==\",\"videoName\":\"xxx\"}"; + + YoukuVideoDTO dto = JSON.parseObject(text, YoukuVideoDTO.class); + assertEquals("XNzBxOCU0NjYxCg==", dto.videoId); + assertEquals("xxx", dto.videoName); + + } + + public static class YoukuVideoDTO { + private String videoId; + + private String videoName; + + @JSONCreator + public YoukuVideoDTO(@JSONField(name = "videoid") String videoId) { + this.videoId = videoId; + } + + public String getVideoId() { + return videoId; + } + + public String getVideoName() { + return videoName; + } + + public void setVideoName(String videoName) { + this.videoName = videoName; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BigIntegerDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BigIntegerDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/CharArrayDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/CharArrayDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ClassTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ClassTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/CollectionFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/CollectionFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest4.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/EnumTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/EnumTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FactoryTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FactoryTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest1.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest5.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FloatDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FloatDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/GetOnlyCollectionTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/GetOnlyCollectionTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/InetAddressDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/InetAddressDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerParseTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/InterfaceParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/InterfaceParseTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/LocaleTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LocaleTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/LongDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LongDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/MapTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/MapTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/MultiArrayTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/MultiArrayTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/PatternDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/PatternDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/StackTraceElementDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/StackTraceElementDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TestEnum.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestEnum.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TestNull.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestNull.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TimeZoneDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeZoneDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TreeMapDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TreeMapDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/URIDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/URIDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/URLDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/URLDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/UUIDDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/UUIDDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASMEishay.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASMEishay.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_BigDecimal.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_BigDecimal.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Byte_0.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Byte_0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Date.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Date.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Integer.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Integer.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_List.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_List.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Long_0.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Long_0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Short_0.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_Short_0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_boolean.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_boolean.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_byte.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_byte.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_char.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_char.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_double.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_double.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_float.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_float.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_int.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_int.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_long.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_long.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_null.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_null.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_object.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_object.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_short.java b/src/test/java/com/alibaba/json/bvt/parser/deser/asm/TestASM_short.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/awt/ColorDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/awt/ColorDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/awt/FontDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/awt/FontDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/awt/PointDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/awt/PointDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/awt/RectangleDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/awt/RectangleDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/date/DateDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/date/DateDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/date/DateParseTest9.java b/src/test/java/com/alibaba/json/bvt/parser/deser/date/DateParseTest9.java index 804ad5889e..474fa27021 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/deser/date/DateParseTest9.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/date/DateParseTest9.java @@ -1,24 +1,49 @@ package com.alibaba.json.bvt.parser.deser.date; +import java.util.Calendar; import java.util.Date; +import java.util.Random; +import java.util.TimeZone; import junit.framework.TestCase; -import org.junit.Assert; - import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.serializer.CalendarCodec; -import com.alibaba.json.bvt.parser.deser.date.DateParseTest14.VO; +import com.alibaba.fastjson.serializer.SerializerFeature; public class DateParseTest9 extends TestCase { + + private static Random random = new Random(); + private TimeZone original = TimeZone.getDefault(); + private String[] zoneIds = TimeZone.getAvailableIDs(); + + @Override + public void setUp() { + int index = random.nextInt(zoneIds.length); + TimeZone timeZone = TimeZone.getTimeZone(zoneIds[index]); + TimeZone.setDefault(timeZone); + JSON.defaultTimeZone = timeZone; + } + + @Override + public void tearDown () { + TimeZone.setDefault(original); + JSON.defaultTimeZone = original; + } + public void test_date() throws Exception { String text = "\"/Date(1242357713797+0800)/\""; Date date = JSON.parseObject(text, Date.class); - Assert.assertEquals(date.getTime(), 1242357713797L); + assertEquals(date.getTime(), 1242357713797L); - Assert.assertEquals(JSONToken.LITERAL_INT, CalendarCodec.instance.getFastMatchToken()); + assertEquals(JSONToken.LITERAL_INT, CalendarCodec.instance.getFastMatchToken()); + + text = "\"/Date(1242357713797+0545)/\""; + date = JSON.parseObject(text, Date.class); + assertEquals(date.getTime(), 1242357713797L); + assertEquals(JSONToken.LITERAL_INT, CalendarCodec.instance.getFastMatchToken()); } public void test_error() throws Exception { @@ -28,7 +53,7 @@ public void test_error() throws Exception { } catch (Exception ex) { error = ex; } - Assert.assertNotNull(error); + assertNotNull(error); } public void test_error_1() throws Exception { @@ -38,6 +63,27 @@ public void test_error_1() throws Exception { } catch (Exception ex) { error = ex; } - Assert.assertNotNull(error); + assertNotNull(error); + } + + public void test_dates_different_timeZones() { + Calendar cal = Calendar.getInstance(); + Date now = cal.getTime(); + + VO vo = new VO(); + vo.date = now; + + String json = JSON.toJSONString(vo); + VO result = JSON.parseObject(json, VO.class); + assertEquals(vo.date, result.date); + + // with iso-format + json = JSON.toJSONString(vo, SerializerFeature.UseISO8601DateFormat); + result = JSON.parseObject(json, VO.class); + assertEquals(JSON.toJSONString(vo.date), JSON.toJSONString(result.date)); + } + + public static class VO { + public Date date; } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest.java index 3a52c33d40..f605f792db 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest.java @@ -30,6 +30,25 @@ public void test_0() throws Exception { JSON.parseObject(text, B.class, config, JSON.DEFAULT_PARSER_FEATURE); } + public void test_1() throws Exception { + String text = "{}"; + + ParserConfig config = new ParserConfig(); + + config.addDeny(null); + config.addDeny("com.alibaba.json.bvt.parser.deser.deny.DenyTest.B"); + + Exception error = null; + try { + JSON.parseObject("{\"@type\":\"LLLcom.alibaba.json.bvt.parser.deser.deny.DenyTest$B;;;\"}", Object.class, config, JSON.DEFAULT_PARSER_FEATURE); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + + JSON.parseObject(text, B.class, config, JSON.DEFAULT_PARSER_FEATURE); + } + public static class B { diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest11.java b/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest11.java index e07ab6a939..d77b5922c2 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest11.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest11.java @@ -20,6 +20,8 @@ protected void setUp() throws Exception { config.configFromPropety(properties); assertFalse(config.isAutoTypeSupport()); + + config.clearDeserializers(); } public void test_autoTypeDeny() throws Exception { diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest2.java index 10de00adab..e2eea5f8e6 100644 --- a/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/deny/DenyTest2.java @@ -29,6 +29,8 @@ public void test_0() throws Exception { error = ex; } Assert.assertNotNull(error); + + error.printStackTrace(); JSON.parseObject(text, B.class, config, JSON.DEFAULT_PARSER_FEATURE); } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest4.java b/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest5.java b/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest5.java new file mode 100644 index 0000000000..6f3eff6dc4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/generic/GenericTest5.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.parser.deser.generic; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import junit.framework.TestCase; + +public class GenericTest5 extends TestCase { + public void test_generic() { + Pair p1 = new Pair(); + p1.label = "p1"; + p1.value = 3L; + String p1Json = JSON.toJSONString(p1); + + JSON.parseObject(p1Json, LongPair.class); + JSON.parseObject(p1Json, StringPair.class); + + JSONObject p1Jobj = JSON.parseObject(p1Json); + + TypeReference> tr = new TypeReference>() {}; + Pair p2 = null; + p2 = JSON.parseObject(p1Json, tr); + assertNotNull(p2); // 基于JSON字符串的转化正常 + + p2 = p1Jobj.toJavaObject(tr); + assertNotNull(p2); + assertEquals(Long.valueOf(3), p2.value); + + + } + + public static class Pair { + private T value; + public String label; + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } + } + + public static class LongPair extends Pair { + + } + + public static class StringPair extends Pair { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayLisMapDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayLisMapDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListEnumFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListEnumFieldDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListStringDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListStringDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListTypeDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListTypeDeserializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListTypeFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ArrayListTypeFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ListFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ListFieldTest.java new file mode 100644 index 0000000000..ba3dd82190 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ListFieldTest.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.parser.deser.list; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +public class ListFieldTest extends TestCase { + public void test_for_list() throws Exception { + JSON.parseObject("{'data':['a','b']}", TestPojo.class); + } + + public static class TestPojo{ + public java.util.List getData(){ + return null; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/number/NumberValueTest_error_13.java b/src/test/java/com/alibaba/json/bvt/parser/number/NumberValueTest_error_13.java new file mode 100644 index 0000000000..11a5728d8a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/number/NumberValueTest_error_13.java @@ -0,0 +1,409 @@ +package com.alibaba.json.bvt.parser.number; + +import com.alibaba.fastjson.*; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Timestamp; +import java.util.concurrent.TimeUnit; + +public class NumberValueTest_error_13 extends TestCase { + + public void test_0() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v0\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertTrue(error.getCause() instanceof ArithmeticException); + } + + public void test_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v1\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertTrue(error.getCause() instanceof ArithmeticException); + } + + public void test_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v2\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertTrue(error.getCause() instanceof ArithmeticException); + } + + public void test_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v3\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertTrue(error.getCause() instanceof ArithmeticException); + } + + public void test_4() throws Exception { + BigDecimal b = new BigDecimal("49e999999999"); + + assertEquals("4.9E+1000000000", JSON.toJSONString(b, SerializerFeature.WriteBigDecimalAsPlain)); + assertEquals("{\"val\":4.9E+1000000000}", JSON.toJSONString(new M1(b), SerializerFeature.WriteBigDecimalAsPlain)); + } + + public void test_5() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v5\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertTrue(error.getCause() instanceof ArithmeticException); + } + + public void test_6() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v6\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertTrue(error.getCause() instanceof ArithmeticException); + } + + public void test_7() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v7\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertTrue(error.getCause() instanceof ArithmeticException); + } + + public void test_8() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v8\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals(NumberFormatException.class, error.getCause().getClass()); + } + + public void test_9() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v9\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals(ArithmeticException.class, error.getCause().getClass()); + } + + public void test_10() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v10\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals(ArithmeticException.class, error.getCause().getClass()); + } + + public void test_11() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v11\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals(ArithmeticException.class, error.getCause().getClass()); + } + + public void test_11_new() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v11\":new Date(49e99999999)}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_12() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v12\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals(ArithmeticException.class, error.getCause().getClass()); + } + + public void test_13() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v13\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals(ArithmeticException.class, error.getCause().getClass()); + } + + + public void test_14() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v14\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + assertEquals(UnsupportedOperationException.class, error.getCause().getClass()); + } + + public void test_15() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v15\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + + public void test_16() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v16\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_17() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v17\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_17_1() throws Exception { + Exception error = null; + try { + JSONObject jsonObject = JSON.parseObject("{\"v17\":49e99999999}"); + jsonObject.getObject("v17", TimeUnit.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + + public void test_18() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"v18\":49e99999999}", Model.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + + public void test_20() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"v\":49e99999999}"); + Exception error = null; + try { + jsonObject.getIntValue("v"); + } catch (ArithmeticException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_21() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"v\":49e99999999}"); + Exception error = null; + try { + jsonObject.getDate("v"); + } catch (ArithmeticException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_22() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"v\":49e99999999}"); + Exception error = null; + try { + jsonObject.getObject("v", java.sql.Date.class); + } catch (ArithmeticException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_23() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"v\":49e99999999}"); + Exception error = null; + try { + jsonObject.getObject("v", java.sql.Timestamp.class); + } catch (ArithmeticException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_24() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"v\":49e99999999}"); + Exception error = null; + try { + jsonObject.getObject("v", java.time.LocalDateTime.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_25() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"lineNumber\":49e99999999}"); + Exception error = null; + try { + jsonObject.toJavaObject(StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_26() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"v\":49e99999999}"); + Exception error = null; + try { + jsonObject.getObject("v", java.sql.Time.class); + } catch (ArithmeticException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_jsonpath() throws Exception { + JSONObject jsonObject = JSON.parseObject("{\"v\":0}"); + Exception error = null; + try { + JSONPath.eval(jsonObject, "$.v in (49e99999999)"); + } catch (JSONPathException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_jsonpath_1() throws Exception { + JSONArray jsonObject = JSON.parseArray("[{\"v\":49e99999999}]"); + JSONPath.eval(jsonObject, "[v=0]"); + } + + public void test_jsonpath_2() throws Exception { + Model[] array = JSON.parseObject("[{\"v2\":0}]", Model[].class); + JSONPath.eval(array, "[v='49e99999999']"); + } + + public void test_jsonpath_3() throws Exception { + Model[] array = JSON.parseObject("[{\"v2\":0}]", Model[].class); + Exception error = null; + try { + JSONPath.read("{\"a\":49e9999999}","[a in (123,2,3)]"); + } catch (Exception ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_jsonpath_4() throws Exception { + Model[] array = JSON.parseObject("[{\"v2\":0}]", Model[].class); + Exception error = null; + try { + JSONPath.read("{\"a\":49e9999999}","[a between 1 and 3]"); + } catch (Exception ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_27() throws Exception { + JSONObject object = JSON.parseObject("{\n" + + " \"connection_health\": {\"status\": \"good\", \"max_value\": 2.0, \"min_value\": 2.0, \"average_value\": 2.0}, \n" + + " \"qps_health\": {\"status\": \"good\", \"max_value\": 5.3, \"min_value\": 4.29, \"average_value\": 4.6},\n" + + " \"disksize_health\": {\"status\": \"good\", \"max_value\": 3089.0, \"min_value\": 3089.0, \"average_value\": 3089.0},\n" + + " \"cpu_health\": {\"status\": \"good\", \"max_value\": 0.0, \"min_value\": 0.0, \"average_value\": 0.0}, \n" + + " \"memory_health\": {\"status\": \"good\", \"max_value\": 17.1, \"min_value\": 17.1, \"average_value\": 17.1}, \n" + + " \"iops_health\": {\"status\": \"good\", \"max_value\": 0.09, \"min_value\": 0.07, \"average_value\": 0.08}\n" + + "}"); + + for(String key : object.keySet()) { + System.out.println("key = " + key); + System.out.println("vaue = " + object.getJSONObject(key).getIntValue("max_value")); + } + } + + public static class Model { + public byte v0; + public short v1; + public int v2; + public long v3; + public Byte v4; + + public Short v5; + public Integer v6; + public Long v7; + public BigInteger v8; + + public Timestamp v9; + public java.sql.Date v10; + public java.util.Date v11; + public java.util.Calendar v12; + public java.sql.Timestamp v13; + public java.time.LocalDateTime v14; + + public boolean v15; + public Boolean v16; + public TimeUnit v17; + public java.sql.Time v18; + } + + public static class M1 { + public BigDecimal val; + + public M1(BigDecimal val) { + this.val = val; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_5.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_5.java new file mode 100644 index 0000000000..83c91ad9f1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_5.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.parser.stream; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONReader; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +public class JSONReaderTest_5 extends TestCase { + public void test_read() throws Exception { + final int COUNT = 1000 * 10; + StringBuilder buf = new StringBuilder(); + buf.append('['); + for (int i = 0; i < COUNT; ++i) { + if (i != 0) { + buf.append(','); + } + buf.append("{\"id\":").append(i).append('}'); + } + buf.append(']'); + + + JSONReader reader = new JSONReader(new StringReader(buf.toString())); + + reader.startArray(); + Map map = new HashMap(); + int count = 0; + for (;;) { + if (reader.hasNext()) { + reader.startObject(); + String key = reader.readString(); + Long value = reader.readLong(); + reader.endObject(); + count++; + } else { + break; + } + } + assertEquals(COUNT, count); + + reader.endArray(); + + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/BookEvalTest.java b/src/test/java/com/alibaba/json/bvt/path/BookEvalTest.java new file mode 100644 index 0000000000..57917df12d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/BookEvalTest.java @@ -0,0 +1,105 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.util.IOUtils; +import junit.framework.TestCase; + +import java.io.InputStream; +import java.io.InputStreamReader; + +public class BookEvalTest extends TestCase { + private JSONObject root; + + protected void setUp() throws Exception { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("json/book.json"); + InputStreamReader reader = new InputStreamReader(is); + String json = IOUtils.readAll(reader); + IOUtils.close(reader); + + root = (JSONObject) JSON.parse(json, Feature.OrderedField); + } + + public void test_0() throws Exception { + assertEquals(4, JSONPath.eval(root, "$..book.length()")); + } + + public void test_1() throws Exception { + assertEquals("[\"reference\",\"Nigel Rees\",\"Sayings of the Century\",8.95,\"fiction\",\"Evelyn Waugh\",\"Sword of Honour\",12.99,\"fiction\",\"Herman Melville\",\"Moby Dick\",\"0-553-21311-3\",8.99,\"fiction\",\"J. R. R. Tolkien\",\"The Lord of the Rings\",\"0-395-19395-8\",22.99,\"red\",19.95,10]" + , JSON.toJSONString(JSONPath.eval(root, "$..*"))); + } + + public void test_2() throws Exception { + assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]", JSON.toJSONString(JSONPath.eval(root, "$.store.book[*].author"))); + } + + public void test_3() throws Exception { + assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]", JSON.toJSONString(JSONPath.eval(root, "$..author"))); + } + + public void test_4() throws Exception { + assertEquals("[8.95,12.99,8.99,22.99,19.95]", JSON.toJSONString(JSONPath.eval(root, "$..price"))); + } + + public void test_5() throws Exception { + assertEquals("[8.95,12.99,8.99,22.99]", JSON.toJSONString(JSONPath.eval(root, "$..book.price"))); + } + + public void test_6() throws Exception { + assertEquals("[[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}],{\"color\":\"red\",\"price\":19.95}]" + , JSON.toJSONString(JSONPath.eval(root, "$.store.*"))); + } + + public void test_7() throws Exception { + assertEquals("[8.95,12.99,8.99,22.99,19.95]" + , JSON.toJSONString(JSONPath.eval(root, "$.store..price"))); + } + + public void test_8() throws Exception { + assertEquals("{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}" + , JSON.toJSONString(JSONPath.eval(root, "$..book[2]"))); + } + + public void test_9() throws Exception { + assertEquals("{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}" + , JSON.toJSONString(JSONPath.eval(root, "$..book[-1]"))); + } + + public void test_10() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99}]" + , JSON.toJSONString(JSONPath.eval(root, "$..book[0,1]"))); + } + + public void test_11() throws Exception { + assertEquals("[{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}]" + , JSON.toJSONString(JSONPath.eval(root, "$..book[?(@.isbn)]"))); + } + + public void test_12() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}]" + , JSON.toJSONString(JSONPath.eval(root, "$.store.book[?(@.price < 10)]"))); + } + + public void test_13() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}]" + , JSON.toJSONString(JSONPath.eval(root, "$..book[?(@.price <= $['expensive'])]"))); + } + + public void test_14() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95}]" + , JSON.toJSONString(JSONPath.eval(root, "$..book[?(@.author =~ /.*REES/i)]"))); + } + + public void test_15() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95}]" + , JSON.toJSONString(JSONPath.eval(root, "$..book[?(@.author =~ /.*REES/i)]"))); + } + + public void test_16() throws Exception { + assertEquals("[{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}]" + , JSON.toJSONString(JSONPath.eval(root, "$.store.book[?(@.price < 10 && @.category == 'fiction')]"))); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/BookExtractTest.java b/src/test/java/com/alibaba/json/bvt/path/BookExtractTest.java new file mode 100644 index 0000000000..a1802ebbbf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/BookExtractTest.java @@ -0,0 +1,103 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.util.IOUtils; +import junit.framework.TestCase; + +import java.io.InputStream; +import java.io.InputStreamReader; + +public class BookExtractTest extends TestCase { + private String json; + + protected void setUp() throws Exception { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("json/book.json"); + InputStreamReader reader = new InputStreamReader(is); + json = IOUtils.readAll(reader); + IOUtils.close(reader); + } + + public void test_0() throws Exception { + assertEquals(4, JSONPath.extract(json, "$..book.length()")); + } + + public void test_1() throws Exception { + assertEquals("[\"reference\",\"Nigel Rees\",\"Sayings of the Century\",8.95,\"fiction\",\"Evelyn Waugh\",\"Sword of Honour\",12.99,\"fiction\",\"Herman Melville\",\"Moby Dick\",\"0-553-21311-3\",8.99,\"fiction\",\"J. R. R. Tolkien\",\"The Lord of the Rings\",\"0-395-19395-8\",22.99,\"red\",19.95,10]" + , JSON.toJSONString(JSONPath.extract(json, "$..*"))); + } + + public void test_2() throws Exception { + assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]", JSON.toJSONString(JSONPath.extract(json, "$.store.book[*].author"))); + } + + public void test_3() throws Exception { + assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]", JSON.toJSONString(JSONPath.extract(json, "$..author"))); + } + + public void test_4() throws Exception { + assertEquals("[8.95,12.99,8.99,22.99,19.95]", JSON.toJSONString(JSONPath.extract(json, "$..price"))); + } + + public void test_5() throws Exception { + assertEquals("[8.95,12.99,8.99,22.99]", JSON.toJSONString(JSONPath.extract(json, "$..book.price"))); + } + + public void test_6() throws Exception { + assertEquals("[[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}],{\"color\":\"red\",\"price\":19.95}]" + , JSON.toJSONString(JSONPath.extract(json, "$.store.*"))); + } + + public void test_7() throws Exception { + assertEquals("[8.95,12.99,8.99,22.99,19.95]" + , JSON.toJSONString(JSONPath.extract(json, "$.store..price"))); + } + + public void test_8() throws Exception { + assertEquals("{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}" + , JSON.toJSONString(JSONPath.extract(json, "$..book[2]"))); + } + + public void test_9() throws Exception { + assertEquals("{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}" + , JSON.toJSONString(JSONPath.extract(json, "$..book[-1]"))); + } + + public void test_10() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99}]" + , JSON.toJSONString(JSONPath.extract(json, "$..book[0,1]"))); + } + + public void test_11() throws Exception { + assertEquals("[{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}]" + , JSON.toJSONString(JSONPath.extract(json, "$..book[?(@.isbn)]"))); + } + + public void test_12() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}]" + , JSON.toJSONString(JSONPath.extract(json, "$.store.book[?(@.price < 10)]"))); + } + + public void test_13() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}]" + , JSON.toJSONString(JSONPath.extract(json, "$..book[?(@.price <= $['expensive'])]"))); + } + + public void test_14() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95}]" + , JSON.toJSONString(JSONPath.extract(json, "$..book[?(@.author =~ /.*REES/i)]"))); + } + + public void test_15() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95}]" + , JSON.toJSONString(JSONPath.extract(json, "$..book[?(@.author =~ /.*REES/i)]"))); + } + + public void test_16() throws Exception { + assertEquals("[{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}]" + , JSON.toJSONString(JSONPath.extract(json, "$.store.book[?(@.price < 10 && @.category == 'fiction')]"))); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/DLATest_0.java b/src/test/java/com/alibaba/json/bvt/path/DLATest_0.java new file mode 100644 index 0000000000..49f05b5df5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/DLATest_0.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.util.IOUtils; +import junit.framework.TestCase; + +import java.io.InputStream; +import java.io.InputStreamReader; + +public class DLATest_0 extends TestCase { + public void test_dla() throws Exception { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("json/dla_01.json"); + InputStreamReader reader = new InputStreamReader(is); + String json = IOUtils.readAll(reader); + Object object = JSON.parse(json, Feature.IgnoreAutoType, Feature.OrderedField); + Object result = JSONPath.eval(object, "$..elapsedTime"); + assertEquals("[\"1.48s\",1031,1031,1005,1005,1011,1011]", JSON.toJSONString(result)); + + Object result2 = JSONPath.eval(object, "$..self"); + assertEquals("[\"http://172.17.246.55:10001/v1/query/20181024_040507_3_f32vb\",\"http://172.17.246.55:10001/v1/stage/20181024_040507_3_f32vb.0\",\"http://172.17.246.56:14005/v1/task/20181024_040507_3_f32vb.0.0?shufferNettyServerPort=39524&commandNettyServerPort=37207\",\"http://172.17.246.55:10001/v1/stage/20181024_040507_3_f32vb.1\",\"http://172.17.246.55:14005/v1/task/20181024_040507_3_f32vb.1.0?shufferNettyServerPort=33921&commandNettyServerPort=45121\",\"http://172.17.246.56:14005/v1/task/20181024_040507_3_f32vb.1.1?shufferNettyServerPort=39524&commandNettyServerPort=37207\"]", JSON.toJSONString(result2)); + } + + public void test_dla_extract() throws Exception { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("json/dla_01.json"); + InputStreamReader reader = new InputStreamReader(is); + String json = IOUtils.readAll(reader); + + Object result = JSONPath.extract(json, "$..elapsedTime"); + assertEquals("[\"1.48s\",1031,1031,1005,1005,1011,1011]", JSON.toJSONString(result)); + + Object result2 = JSONPath.extract(json, "$..self"); + assertEquals("[\"http://172.17.246.55:10001/v1/query/20181024_040507_3_f32vb\",\"http://172.17.246.55:10001/v1/stage/20181024_040507_3_f32vb.0\",\"http://172.17.246.56:14005/v1/task/20181024_040507_3_f32vb.0.0?shufferNettyServerPort=39524&commandNettyServerPort=37207\",\"http://172.17.246.55:10001/v1/stage/20181024_040507_3_f32vb.1\",\"http://172.17.246.55:14005/v1/task/20181024_040507_3_f32vb.1.0?shufferNettyServerPort=33921&commandNettyServerPort=45121\",\"http://172.17.246.56:14005/v1/task/20181024_040507_3_f32vb.1.1?shufferNettyServerPort=39524&commandNettyServerPort=37207\"]", JSON.toJSONString(result2)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_0.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_0.java index 6c8d39fef9..2f0016a9df 100644 --- a/src/test/java/com/alibaba/json/bvt/path/JSONPath_0.java +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_0.java @@ -17,7 +17,7 @@ public void test_root() throws Exception { } public void test_null() throws Exception { - Assert.assertNull(new JSONPath("$").eval(null)); + Assert.assertNull(new JSONPath("$").extract(null)); } public void test_map() throws Exception { diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_10_contains.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_10_contains.java new file mode 100644 index 0000000000..0fdeed4a3b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_10_contains.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class JSONPath_10_contains extends TestCase { + + public void test(){ + String json = "{\n" + + " \"queryScene\":{\n" + + " \"scene\":[\n" + + " {\n" + + " \"innerSceneId\":3,\n" + + " \"name\":\"场景绑8测试-笑幽\",\n" + + " \"sceneSetId\":8,\n" + + " \"formInfo\":\"{}\",\n" + + " \"queryDataSet\":{\n" + + " \"dataSet\":[\n" + + " {\n" + + " \"id\":6,\n" + + " \"sceneId\":3,\n" + + " \"name\":\"测试商品集\",\n" + + " \"dataSetRuleCode\":null,\n" + + " \"resourceId\":null,\n" + + " \"udsOffer\":{\n" + + " \"offer\":[\n" + + "\n" + + " ]\n" + + " }\n" + + " },\n" + + " {\n" + + " \"id\":5,\n" + + " \"sceneId\":3,\n" + + " \"name\":\"测试卖家集\",\n" + + " \"dataSetRuleCode\":null,\n" + + " \"resourceId\":null,\n" + + " \"udsOffer\":{\n" + + " \"offer\":[\n" + + "\n" + + " ]\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + assertTrue(JSONPath.contains(JSON.parseObject(json), "$.queryScene.scene.queryDataSet.dataSet")); + assertFalse(JSONPath.contains(JSON.parseObject(json), "$.queryScene.scene.queryDataSet.dataSet.abcd")); + assertTrue(JSONPath.contains(JSON.parseObject(json), "$.queryScene.scene.queryDataSet.dataSet.name")); + } + +// public void test_path_2() throws Exception { +//// File file = new File("/Users/wenshao/Downloads/test"); +//// String json = FileUtils.readFileToString(file); +// String json = "{\"returnObj\":[{\"$ref\":\"$.subInvokes.com\\\\.alipay\\\\.cif\\\\.user\\\\.UserInfoQueryService\\\\@findUserInfosByCardNo\\\\(String[])[0].response[0]\"}]}"; +// JSON.parseObject(json); +// } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_11.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_11.java new file mode 100644 index 0000000000..e8e6ad2603 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_11.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_11 extends TestCase { + + public void test(){ + String json = "[\n" + + " [\n" + + " {\n" + + " \"CN\": \"t1c1CN\",\n" + + " \"FP\": \"t1c1FP\"\n" + + " },\n" + + " {\n" + + " \"CN\": \"t1c2CN\",\n" + + " \"FP\": \"t1c2FP\"\n" + + " }\n" + + " ],\n" + + " [\n" + + " {\n" + + " \"CN\": \"t2c1CN\",\n" + + " \"FP\": \"t2c1FP\"\n" + + " },\n" + + " {\n" + + " \"CN\": \"t2c2CN\",\n" + + " \"FP\": \"t2c2FP\"\n" + + " }\n" + + " ]\n" + + "]"; + + JSONArray array = JSON.parseArray(json); + System.out.println(JSONPath.eval(array, "$[0,1][CN='t1c1CN']")); + } + +// public void test_path_2() throws Exception { +//// File file = new File("/Users/wenshao/Downloads/test"); +//// String json = FileUtils.readFileToString(file); +// String json = "{\"returnObj\":[{\"$ref\":\"$.subInvokes.com\\\\.alipay\\\\.cif\\\\.user\\\\.UserInfoQueryService\\\\@findUserInfosByCardNo\\\\(String[])[0].response[0]\"}]}"; +// JSON.parseObject(json); +// } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_12.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_12.java new file mode 100644 index 0000000000..732a491b10 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_12.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_12 + extends TestCase { + + public void test(){ + JSONObject schemaResult = JSON.parseObject("{\n" + + " \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n" + + " \"title\": \"AE product schema\",\n" + + " \"description\": \"AE product schema\",\n" + + " \"type\": \"object\",\n" + + " \"required\": [\n" + + " \"category_attributes\"\n" + + " ],\n" + + " \"properties\": {\n" + + " \"category_attributes\": {\n" + + " \"title\": \"category attributes\",\n" + + " \"type\": \"object\",\n" + + " \"required\": [\n" + + " \"Brand Name\"\n" + + " ],\n" + + " \"properties\":{}\n" + + " }\n" + + " }\n" + + "}"); + String jsonPath = "$['properties']['category_attributes']['properties']"; + String attributeName = "Brand\\. Name"; // attribute name with dot + JSONObject attributeValue = JSON.parseObject("{\n" + + " \"title\": \"Brand Name\",\n" + + " \"type\": \"String\"\n" + + "}"); + assertTrue( + JSONPath.set(schemaResult, jsonPath + "['" + attributeName + "']" , attributeValue) + ); + + assertTrue(JSONPath.contains(schemaResult, jsonPath + "['" + attributeName + "']")); + JSONObject newAttribute = (JSONObject)JSONPath.eval(schemaResult, jsonPath); + System.out.println(schemaResult); + System.out.println(JSONPath.read(schemaResult.toJSONString(), jsonPath + "['" + attributeName + "']")); + assertTrue(newAttribute.containsKey("Brand. Name")); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_13.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_13.java new file mode 100644 index 0000000000..87268bfc30 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_13.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_13 + extends TestCase { + + public void test_0() { + JSONObject root = new JSONObject(); + root.put("company", new JSONObject()); + root.getJSONObject("company").put("id", 123); + root.getJSONObject("company").put("name", "jobs"); + + JSONPath.remove(root, "$..id"); + + assertEquals("{\"company\":{\"name\":\"jobs\"}}", root.toJSONString()); + } + + public void test_1() { + Root root = new Root(); + root.company = new Company(); + root.company.id = 123; + root.company.name = "jobs"; + + JSONPath.remove(root, "$..id"); + + assertEquals("{\"company\":{\"name\":\"jobs\"}}", JSON.toJSONString(root)); + } + + public static class Root { + public Company company; + } + + public static class Company { + public Integer id; + public String name; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_14.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_14.java new file mode 100644 index 0000000000..e024523a80 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_14.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class JSONPath_14 + extends TestCase { + + public void test_0() { + JSONObject sourceJson = JSON.parseObject("{\n" + + "\t\"boolean1\":true,\n" + + "\t\"boolean2\":false,\n" + + "\t\"boolean3\":true,\n" + + "\t\"boolean4\":true,\n" + + "\t\"name\":\"str\",\n" + + "\t\"name1\":\"str\"\n" + + "}"); + + sourceJson.put("enum1", TimeUnit.SECONDS); + sourceJson.put("character1", 'A'); + sourceJson.put("uuid1", UUID.randomUUID()); + + // 初始配置中,新增的字段添加的库中 + Map paths = JSONPath.paths(sourceJson); + System.out.println(JSON.toJSONString(paths)); + assertEquals(10, paths.size()); + + JSONObject destJson = JSON.parseObject("{\n" + + "\t\"boolean1\":true,\n" + + "\t\"boolean2\":false,\n" + + "\t\"name\":\"str\"\n" + + "}"); + + for (Map.Entry stringObjectEntry : paths.entrySet()) { + if(stringObjectEntry.getValue() instanceof JSONObject || stringObjectEntry.getValue() instanceof JSONArray){ + continue; + } + if (!JSONPath.contains(destJson, stringObjectEntry.getKey())) { + JSONPath.set(destJson, stringObjectEntry.getKey(), stringObjectEntry.getValue()); + System.out.println("key=" + stringObjectEntry.getKey() + " ,value=" + stringObjectEntry.getValue()); + } + } + + System.out.println(destJson.toJSONString()); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_15.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_15.java new file mode 100644 index 0000000000..69a3c1faf9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_15.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class JSONPath_15 + extends TestCase { + final static String a = "{code:1,msg:'Hello world',data:{list:[1,2,3,4,5], ary2:[{a:2},{a:3,b:{c:'ddd'}}]}}"; + final static String b = "[{b:{c:1}}, {b:{d:1}}, {b:{c:2}}, {b:{c:23}}]"; + final static String c = "[{c:'aaaa'}, {b:'cccc'}, {c:'cccaa'}]"; + + public void test_0() { + + JSONObject object = JSON.parseObject(a); + + List items = (List) JSONPath.eval(object, "data.ary2[*].b.c"); + assertEquals("[\"ddd\"]", JSON.toJSONString(items)); + } + + public void test_1() { + Object object = JSON.parse(b); + + List items = (List) JSONPath.eval(object, "$..b[?(@.c == 23)]"); + assertEquals("[{\"c\":23}]", JSON.toJSONString(items)); + } + + public void test_2() { + Object object = JSON.parse(b); + + Object min = JSONPath.eval(object, "$..c.min()"); + assertEquals("1", JSON.toJSONString(min)); + } + + public void test_3() { + Object object = JSON.parse(c); + + Object min = JSONPath.eval(object, "$[?(@.c =~ /a+/)]"); + assertEquals("[{\"c\":\"aaaa\"}]", JSON.toJSONString(min)); + } +// +// public void test_c() { +// Object object = JSON.parse(c); +// +// Object min = JSONPath.eval(object, "data.list[?(@ in $..ary2[0].a)]"); +// assertEquals("[{\"c\":\"aaaa\"}]", JSON.toJSONString(min)); +// } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_16.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_16.java new file mode 100644 index 0000000000..f6ff633bd3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_16.java @@ -0,0 +1,103 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class JSONPath_16 extends TestCase { + public void test_for_jsonpath() throws Exception { + String str = "[{\"id\":1001,\"salary\":4000,\"name\":\"jobs\",\"valid\":false},{\"id\":1001,\"salary\":5000}]"; + System.out.println(str); + assertEquals(2 + , JSONPath.extract(str, "$.size()")); + + assertEquals("array" + , JSONPath.extract(str, "$.type()")); + + assertEquals("object" + , JSONPath.extract(str, "$[0].type()")); + + assertEquals("number" + , JSONPath.extract(str, "$[0].id.type()")); + + assertEquals("string" + , JSONPath.extract(str, "$[0].name.type()")); + + assertEquals("boolean" + , JSONPath.extract(str, "$[0].valid.type()")); + + assertEquals("null" + , JSONPath.extract(str, "$[0].xx.type()")); + } + + public void test_for_jsonpath_type() throws Exception { + JSONObject root = new JSONObject(); + root.put("id", UUID.randomUUID()); + root.put("unit", TimeUnit.SECONDS); + + assertEquals("string" + , JSONPath.eval(root, "$.id.type()")); + + assertEquals("string" + , JSONPath.eval(root, "$.unit.type()")); + } + + public void test_for_jsonpath_1() throws Exception { + String str = "{\"id\":1001,\"salary\":4000}"; + assertNull( + JSONPath.extract(str, "$?( @.salary > 100000 )")); + + assertEquals(JSON.parseObject(str, Feature.OrderedField), + JSONPath.extract(str, "$?( @.salary > 1000 )")); + } + + public void test_for_jsonpath_2() throws Exception { + String str = "[[10,20],[100],{\"id\":1001}]"; + Object object = JSONPath.extract(str, "$.* ? (@.type() == \"array\")"); + assertEquals("[[10,20],[100]]", JSON.toJSONString(object)); + } + + public void test_for_jsonpath_3() throws Exception { + String str = "[[10,20],[100],{\"id\":1001}]"; + Object object = JSONPath.extract(str, "$.* ? (@.type() == \"array\" && @.size() > 1)"); + assertEquals("[[10,20]]", JSON.toJSONString(object)); + } + + public void test_for_jsonpath_4() throws Exception { + String str = "{ readings: [15.2, -22.3, 45.9] }"; + Object object = JSONPath.extract(str, "$.readings.floor()"); + assertEquals("[15,-23,45]", JSON.toJSONString(object)); + } + + public void test_for_jsonpath_5() throws Exception { + String str = "{ readings: [15.2, 13, -22.3, 45.9] }"; + assertEquals(BigDecimal.valueOf(15), JSONPath.extract(str, "$.readings[0].floor()")); + assertEquals(13, JSONPath.extract(str, "$.readings[1].floor()")); + } + + public void test_for_jsonpath_6() throws Exception { + JSONArray array = new JSONArray(); + array.add(1.1F); + array.add(2.2D); + array.add((byte) 3); + array.add((short) 4); + array.add(5); + array.add(6L); + array.add(BigInteger.valueOf(7)); + assertEquals(1D, JSONPath.eval(array, "$[0].floor()")); + assertEquals(2D, JSONPath.eval(array, "$[1].floor()")); + assertEquals((byte) 3, JSONPath.eval(array, "$[2].floor()")); + assertEquals((short) 4, JSONPath.eval(array, "$[3].floor()")); + assertEquals(5, JSONPath.eval(array, "$[4].floor()")); + assertEquals(6L, JSONPath.eval(array, "$[5].floor()")); + assertEquals(BigInteger.valueOf(7), JSONPath.eval(array, "$[6].floor()")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_17.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_17.java new file mode 100644 index 0000000000..11c39c2fb7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_17.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class JSONPath_17 extends TestCase { + public void test_for_jsonpath() throws Exception { + String input = "{\"b\":[{\"c\":{\"d\":{\"e\":\"978\"}},\"f\":{\"c\":{\"d\":{\"$ref\":\"$.b[0].c.d\"}}}}]}"; + Object obj = JSON.parse(input); + String oupput = JSON.parse(input).toString(); + assertEquals(obj, JSON.parse(oupput)); + } + + public void test_for_jsonpath_1() throws Exception { + assertEquals("[5]", JSONPath.extract("[1, 2, 3, 4, 5]", "$[last]").toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_5.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_5.java new file mode 100644 index 0000000000..5f86f701f4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_5.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.List; + +public class JSONPath_5 extends TestCase { + + public void test_path() throws Exception { + Model m = new Model(); + Value v = new Value(m); + m.values.add(v); + m.values.add(m.values); + m.values.add(m); + + String json = JSON.toJSONString(m); + System.out.println(json); + } + + public static class Model { + public List values = new ArrayList(); + } + + public static class Value { + public Model model = new Model(); + + public Value() { + + } + + public Value(Model model) { + this.model = model; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_6.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_6.java new file mode 100644 index 0000000000..04ebe2b75c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_6.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.apache.commons.io.FileUtils; +import org.glassfish.jersey.server.JSONP; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class JSONPath_6 extends TestCase { + + public void test_path() throws Exception { + String json = "{\"hello\":\"world\"}"; + JSONObject object = JSON.parseObject(json); + assertTrue(JSONPath.contains(object, "$.hello")); + assertTrue(JSONPath.contains(object, "hello")); + } + +// public void test_path_2() throws Exception { +//// File file = new File("/Users/wenshao/Downloads/test"); +//// String json = FileUtils.readFileToString(file); +// String json = "{\"returnObj\":[{\"$ref\":\"$.subInvokes.com\\\\.alipay\\\\.cif\\\\.user\\\\.UserInfoQueryService\\\\@findUserInfosByCardNo\\\\(String[])[0].response[0]\"}]}"; +// JSON.parseObject(json); +// } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_7.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_7.java new file mode 100644 index 0000000000..c34113d2d2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_7.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.glassfish.jersey.server.JSONP; + +public class JSONPath_7 extends TestCase { + + public void test_path() throws Exception { + Model[] array = new Model[] {new Model(101), new Model(202), new Model(303)}; + JSONArray values = (JSONArray) JSONPath.eval(array, "$.id"); + assertEquals(101, values.get(0)); + assertEquals(202, values.get(1)); + assertEquals(303, values.get(2)); + + assertEquals(3, JSONPath.eval(array, "$.length")); + } + + public static class Model { + public int id; + + public Model(int id) { + this.id = id; + } + } + +// public void test_path_2() throws Exception { +//// File file = new File("/Users/wenshao/Downloads/test"); +//// String json = FileUtils.readFileToString(file); +// String json = "{\"returnObj\":[{\"$ref\":\"$.subInvokes.com\\\\.alipay\\\\.cif\\\\.user\\\\.UserInfoQueryService\\\\@findUserInfosByCardNo\\\\(String[])[0].response[0]\"}]}"; +// JSON.parseObject(json); +// } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_8.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_8.java new file mode 100644 index 0000000000..8ca4420340 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_8.java @@ -0,0 +1,91 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.JSONPathException; +import junit.framework.TestCase; + +import java.util.Map; + +public class JSONPath_8 extends TestCase { + + public void test_path() throws Exception { + Model m = new Model(); + m.f0 = 101; + m.f1 = 102; + + JSONPath.remove(m, "$.f0"); + assertNull(m.f0); + + JSONPath.remove(m, "$.f1"); + assertNull(m.f1); + + + JSONPath.remove(m, "$.f2"); + + JSONPath.eval(m, "$.f2"); + } + + public void test_error() throws Exception { + Exception error = null; + + Model m = new Model(); + m.f0 = 101; + m.f1 = 102; + + try { + JSONPath.eval(m, "$.id"); + } catch (JSONPathException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_error_1() throws Exception { + Exception error = null; + + Model m = new Model(); + m.f0 = 101; + m.f1 = 102; + + try { + JSONPath.eval(m, "$..id"); + } catch (JSONPathException ex) { + error = ex; + } + assertNotNull(error); + } + + public void test_paths() throws Exception { + Model m = new Model(); + m.f0 = 101; + m.f1 = 102; + + Exception error = null; + try { + Map paths = JSONPath.paths(m); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + public static class Model { + public Integer f0; + public Integer f1; + + public Integer getId() { + throw new IllegalStateException(); + } + + } + +// public void test_path_2() throws Exception { +//// File file = new File("/Users/wenshao/Downloads/test"); +//// String json = FileUtils.readFileToString(file); +// String json = "{\"returnObj\":[{\"$ref\":\"$.subInvokes.com\\\\.alipay\\\\.cif\\\\.user\\\\.UserInfoQueryService\\\\@findUserInfosByCardNo\\\\(String[])[0].response[0]\"}]}"; +// JSON.parseObject(json); +// } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_9.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_9.java new file mode 100644 index 0000000000..82f97ef42b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_9.java @@ -0,0 +1,64 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.JSONPathException; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class JSONPath_9 extends TestCase { + + public void test_paths() throws Exception { + Model m = new Model(); + m.f0 = 101; + m.f1 = 102; + + Map paths = JSONPath.paths(m); + assertEquals(3, paths.size()); + } + + public void test_paths_1() throws Exception { + Map map = new HashMap(); + map.put("f0", 1001); + map.put("f1", 1002); + + Map paths = JSONPath.paths(map); + assertEquals(3, paths.size()); + } + + public void test_paths_2() throws Exception { + Map map = new HashMap(); + map.put("f0", 1001); + map.put("f1", 1002); + + JSONPath path = new JSONPath("$.f0"); + assertEquals("$.f0", path.getPath()); + assertEquals(1001, path.eval(map)); + + path.remove(null); + } + + public void test_paths_3() throws Exception { + JSONPath.paths(null); + JSONPath.paths(1); + JSONPath.paths("1"); + JSONPath.paths(TimeUnit.DAYS); + } + + public static class Model { + public Integer f0; + public Integer f1; + + } + +// public void test_path_2() throws Exception { +//// File file = new File("/Users/wenshao/Downloads/test"); +//// String json = FileUtils.readFileToString(file); +// String json = "{\"returnObj\":[{\"$ref\":\"$.subInvokes.com\\\\.alipay\\\\.cif\\\\.user\\\\.UserInfoQueryService\\\\@findUserInfosByCardNo\\\\(String[])[0].response[0]\"}]}"; +// JSON.parseObject(json); +// } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_length.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_length.java new file mode 100644 index 0000000000..a383f1bc2f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_length.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Collections; + +public class JSONPath_array_length extends TestCase { + public void test_list_size() throws Exception { + Assert.assertEquals(0, JSONPath.eval(new JSONArray(), "$.length")); + } + + public void test_list_size1() throws Exception { + Assert.assertEquals(0, JSONPath.eval(new Object[0], "$.length()")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_multi.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_multi.java index 3cffeb6b47..6d19db9e58 100644 --- a/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_multi.java +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_multi.java @@ -30,7 +30,8 @@ public void test_list_multi() throws Exception { } public void test_list_multi_negative() throws Exception { - List result = (List) new JSONPath("$[-1,-2,-100]").eval(list); + List result = (List) new JSONPath("$[-1,-2,-100]") + .eval(list); Assert.assertEquals(3, result.size()); Assert.assertSame(list[9], result.get(0)); Assert.assertSame(list[8], result.get(1)); diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_between_double.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_between_double.java new file mode 100644 index 0000000000..90a1876b1b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_between_double.java @@ -0,0 +1,69 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.List; + +public class JSONPath_between_double extends TestCase { + public void test_between() throws Exception { + List list = new ArrayList(); + list.add(new Entity(101, "kiki")); + list.add(new Entity(102, "ljw2083")); + list.add(new Entity(103, "ljw2083")); + List result = (List) JSONPath.eval(list, "$[id between 101 and 101]"); + Assert.assertEquals(1, result.size()); + Assert.assertSame(list.get(0), result.get(0)); + } + + public void test_between_2() throws Exception { + List list = new ArrayList(); + list.add(new Entity(101, "kiki")); + list.add(new Entity(102, "ljw2083")); + list.add(new Entity(103, "ljw2083")); + List result = (List) JSONPath.eval(list, "$[id between 101 and 102]"); + Assert.assertEquals(2, result.size()); + Assert.assertSame(list.get(0), result.get(0)); + Assert.assertSame(list.get(1), result.get(1)); + } + + public void test_between_not() throws Exception { + List list = new ArrayList(); + list.add(new Entity(101, "kiki")); + list.add(new Entity(102, "ljw2083")); + list.add(new Entity(103, "ljw2083")); + List result = (List) JSONPath.eval(list, "$[id not between 101 and 102]"); + Assert.assertEquals(1, result.size()); + Assert.assertSame(list.get(2), result.get(0)); + } + + public static class Entity { + + private Double id; + private String name; + + public Entity(int id, String name){ + this.id = Double.valueOf(id); + this.name = name; + } + + public Double getId() { + return id; + } + + public void setId(Double id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string.java index 75d98aca97..ac315f1b5b 100644 --- a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string.java +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import junit.framework.TestCase; import org.junit.Assert; @@ -126,7 +128,15 @@ public void test_list_le() throws Exception { Assert.assertSame(entities.get(0), result.get(0)); Assert.assertSame(entities.get(1), result.get(1)); } - + + public void test_eq() throws Exception { + JSONPath path = new JSONPath("$.*[?(@.name=='b')].id"); + + JSONArray array = JSON.parseArray("[{\"id\":\"1\",\"name\":\"a\"},{\"id\":\"2\",\"name\":\"b\"}]"); + Object result = path.eval(array); + System.out.println(result); + } + public static class Entity { private Integer id; diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_decimal.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_decimal.java new file mode 100644 index 0000000000..0c9f4ca399 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_decimal.java @@ -0,0 +1,139 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +public class JSONPath_field_access_filter_in_decimal extends TestCase { + + public void test_list_in() throws Exception { + JSONPath path = new JSONPath("[id in (1001)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_not_in() throws Exception { + JSONPath path = new JSONPath("[id not in (1001)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public void test_list_not_in_null() throws Exception { + JSONPath path = new JSONPath("[id not in (null)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(4, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + Assert.assertSame(entities.get(2), result.get(2)); + Assert.assertSame(entities.get(3), result.get(3)); + } + + public void test_list_in_2() throws Exception { + JSONPath path = new JSONPath("[id in (1001, 1003)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_in_3() throws Exception { + JSONPath path = new JSONPath("[id in (1001, 1003, 1004)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public void test_list_in_3_null() throws Exception { + JSONPath path = new JSONPath("[id in (1001, 1003, null)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public static class Entity { + + private BigDecimal id; + private String name; + + public Entity(Integer id, String name){ + if (id == null) { + this.id = null; + } else { + this.id = BigDecimal.valueOf(id); + } + + this.name = name; + } + + public BigDecimal getId() { + return id; + } + + public void setId(BigDecimal id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_int.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_int.java index 75c8c85a6e..4a1eaca909 100644 --- a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_int.java +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_int.java @@ -40,6 +40,22 @@ public void test_list_not_in() throws Exception { Assert.assertSame(entities.get(2), result.get(1)); Assert.assertSame(entities.get(3), result.get(2)); } + + public void test_list_nin() throws Exception { + JSONPath path = new JSONPath("[id nin (1001)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } public void test_list_not_in_null() throws Exception { JSONPath path = new JSONPath("[id not in (null)]"); diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_multi.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_multi.java index af7cc2d717..70b296e0e7 100644 --- a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_multi.java +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_multi.java @@ -19,6 +19,18 @@ public void test_list_map() throws Exception { Assert.assertSame(entity.getName(), result.get(1)); } + public void test_list_map2() throws Exception { + Entity entity = new Entity(123, "wenshao"); + JSONPath path = new JSONPath("$.entity['id','name']"); + + Root root = new Root(); + root.setEntity(entity); + + List result = (List) path.eval(root); + Assert.assertSame(entity.getId(), result.get(0)); + Assert.assertSame(entity.getName(), result.get(1)); + } + public static class Entity { private Integer id; @@ -46,4 +58,18 @@ public void setName(String name) { } } + + public static class Root { + private Entity entity; + + public Entity getEntity() + { + return entity; + } + + public void setEntity(Entity entity) + { + this.entity = entity; + } + } } diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter.java new file mode 100644 index 0000000000..c3c7571dba --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter.java @@ -0,0 +1,72 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.*; + +public class JSONPath_field_wildcard_filter extends TestCase { + + public void test_list_map_0() throws Exception { + JSONObject jsonObject = JSON.parseObject(text, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score>0]"); + assertEquals("[{\"score\":0.89513221556685012},{\"score\":0.7237896928683851},{\"score\":0.3467174233072834}]", JSON.toJSONString(array)); + } + + public void test_list_map_1() throws Exception { + JSONObject jsonObject = JSON.parseObject(text, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score<0]"); + assertEquals("[{\"score\":-0.3453003960431523}]", JSON.toJSONString(array)); + } + + public void test_list_map_2() throws Exception { + JSONObject jsonObject = JSON.parseObject(text, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score=0]"); + assertEquals("[{\"score\":0},{\"score\":0},{\"score\":0},{\"score\":0},{\"score\":0},{\"score\":0},{\"score\":0}]", JSON.toJSONString(array)); + } + + public static final String text = "{\n" + + "\t\"risk_sexy_trade_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"chemical_medicine_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"gambling_trade_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"politics_stream_plus\": {\n" + + "\t\t\"score\": 0.89513221556685012\n" + + "\t},\n" + + "\t\"risk_tool_gun_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"sex_model_stream_plus\": {\n" + + "\t\t\"score\": 0.7237896928683851\n" + + "\t},\n" + + "\t\"risk_tool_cheat_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"risk_tool_certif_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"gamble_model_stream_plus\": {\n" + + "\t\t\"score\": -0.3453003960431523\n" + + "\t},\n" + + "\t\"risk_tool_vpn_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"vpndetect_stream_plus\": {\n" + + "\t\t\"score\": 0.3467174233072834\n" + + "\t}\n" + + "}"; + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter_double.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter_double.java new file mode 100644 index 0000000000..6ad2607c8d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter_double.java @@ -0,0 +1,75 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.util.Collection; +import java.util.Map; + +public class JSONPath_field_wildcard_filter_double extends TestCase { + + public void test_list_map_0() throws Exception { + Map jsonObject = JSON.parseObject(text, new TypeReference>(){}, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score>0]"); + assertEquals("[{\"score\":0.8951322155668501},{\"score\":0.7237896928683851},{\"score\":0.3467174233072834}]", JSON.toJSONString(array)); + } + + public void test_list_map_1() throws Exception { + Map jsonObject = JSON.parseObject(text, new TypeReference>(){}, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score<0]"); + assertEquals("[{\"score\":-0.3453003960431523}]", JSON.toJSONString(array)); + } + + public void test_list_map_2() throws Exception { + Map jsonObject = JSON.parseObject(text, new TypeReference>(){}, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score=0]"); + assertEquals("[{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0}]", JSON.toJSONString(array)); + } + + public static class Value { + public double score; + } + + public static final String text = "{\n" + + "\t\"risk_sexy_trade_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"chemical_medicine_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"gambling_trade_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"politics_stream_plus\": {\n" + + "\t\t\"score\": 0.89513221556685012\n" + + "\t},\n" + + "\t\"risk_tool_gun_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"sex_model_stream_plus\": {\n" + + "\t\t\"score\": 0.7237896928683851\n" + + "\t},\n" + + "\t\"risk_tool_cheat_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"risk_tool_certif_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"gamble_model_stream_plus\": {\n" + + "\t\t\"score\": -0.3453003960431523\n" + + "\t},\n" + + "\t\"risk_tool_vpn_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"vpndetect_stream_plus\": {\n" + + "\t\t\"score\": 0.3467174233072834\n" + + "\t}\n" + + "}"; + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter_float.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter_float.java new file mode 100644 index 0000000000..fb60d2ff24 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard_filter_float.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.util.Collection; +import java.util.Map; + +public class JSONPath_field_wildcard_filter_float extends TestCase { + + public void test_list_map_0() throws Exception { + Map jsonObject = JSON.parseObject(text, new TypeReference>(){}, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score>0]"); + assertEquals("[{\"score\":0.89513224},{\"score\":0.7237897},{\"score\":0.34671742}]", JSON.toJSONString(array)); + } + + public void test_list_map_1() throws Exception { + Map jsonObject = JSON.parseObject(text, new TypeReference>(){}, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score<0]"); + assertEquals("[{\"score\":-0.3453004}]", JSON.toJSONString(array)); + } + + public void test_list_map_2() throws Exception { + Map jsonObject = JSON.parseObject(text, new TypeReference>(){}, Feature.OrderedField); + + Collection array = (Collection) JSONPath.eval(jsonObject, "$.*[score=0]"); + assertEquals("[{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0},{\"score\":0.0}]", JSON.toJSONString(array)); + } + + public static class Value { + public float score; + } + + public static final String text = "{\n" + + "\t\"risk_sexy_trade_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"chemical_medicine_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"gambling_trade_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"politics_stream_plus\": {\n" + + "\t\t\"score\": 0.89513221556685012\n" + + "\t},\n" + + "\t\"risk_tool_gun_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"sex_model_stream_plus\": {\n" + + "\t\t\"score\": 0.7237896928683851\n" + + "\t},\n" + + "\t\"risk_tool_cheat_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"risk_tool_certif_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"gamble_model_stream_plus\": {\n" + + "\t\t\"score\": -0.3453003960431523\n" + + "\t},\n" + + "\t\"risk_tool_vpn_stream_plus\": {\n" + + "\t\t\"score\": 0\n" + + "\t},\n" + + "\t\"vpndetect_stream_plus\": {\n" + + "\t\t\"score\": 0.3467174233072834\n" + + "\t}\n" + + "}"; + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_keySet.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_keySet.java new file mode 100644 index 0000000000..31b14e9d78 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_keySet.java @@ -0,0 +1,134 @@ +package com.alibaba.json.bvt.path; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.alibaba.fastjson.JSONPath; + +import junit.framework.TestCase; +import org.junit.Assert; + +public class JSONPath_keySet extends TestCase { + + public static final Set KEY_SET = new HashSet(); + + static { + KEY_SET.add("id"); + KEY_SET.add("name"); + } + + @SuppressWarnings("unchecked") + public void test_map() { + Map map1 = new HashMap(); + map1.put("id", 1); + map1.put("name", null); // null will be included + Assert.assertEquals(KEY_SET, JSONPath.eval(map1, "$.keySet()")); + Assert.assertEquals(KEY_SET, JSONPath.keySet(map1, "$")); + + Map map2 = new HashMap(); + map2.put(1L, "a"); + map2.put(2L, "b"); + Set keys2 = (Set)JSONPath.eval(map2, "$.keySet()"); + Assert.assertEquals(2, keys2.size()); + Assert.assertTrue(keys2.contains(1L)); + Assert.assertTrue(keys2.contains(2L)); + } + + @SuppressWarnings("unchecked") + public void test_object() { + Entity e = new Entity(); + e.id = 3L; + e.name = "hello"; + Collection result = null; + // age is null + result = (Collection)JSONPath.eval(e, "$.keySet()"); + Assert.assertEquals(KEY_SET, result); + + // age not null + e.age = 4L; + result = (Collection)JSONPath.eval(e, "$.keySet()"); + Assert.assertEquals(3, result.size()); + Assert.assertTrue(result.containsAll(KEY_SET)); + Assert.assertTrue(result.contains("age")); + } + + public void test_nested() { + Entity e = new Entity(); + e.id = 3L; + e.name = "hello"; + Object obj = Collections.singletonMap("obj", e); + Assert.assertEquals(KEY_SET, JSONPath.eval(obj, "$.obj.keySet()")); + Assert.assertEquals(KEY_SET, new JSONPath("$.obj").keySet(obj)); + } + + public void test_unsupported() { + Entity e = new Entity(); + e.id = 3L; + Entity[] array = {e}; + Map map = Collections.singletonMap("array", array); + Assert.assertEquals(array, JSONPath.eval(map, "$.array")); + Assert.assertNull(JSONPath.eval(map, "$.array.keySet()")); + Assert.assertNull(JSONPath.keySet(map, "$.array")); + Assert.assertNull(new JSONPath("$.array").keySet(map)); + } + + public void test_null() { + Assert.assertNull(JSONPath.eval(null, "$.keySet()")); + Set keySet = (Set)JSONPath.eval(new HashMap(), "$.keySet()"); + Assert.assertEquals(0, keySet.size()); + } + + /** + * Demo for wiki + */ + @SuppressWarnings("unchecked") + public void test_demo() { + Entity e = new Entity(); + e.setId(null); + e.setName("hello"); + Map map = Collections.singletonMap("e", e); + Collection result; + + // id is null, excluded by keySet + result = (Collection)JSONPath.eval(map, "$.e.keySet()"); + assertEquals(1, result.size()); + Assert.assertTrue(result.contains("name")); + + e.setId(1L); + result = (Collection)JSONPath.eval(map, "$.e.keySet()"); + Assert.assertEquals(2, result.size()); + Assert.assertTrue(result.contains("id")); // included + Assert.assertTrue(result.contains("name")); + + // Same result + Assert.assertEquals(result, JSONPath.keySet(map, "$.e")); + Assert.assertEquals(result, new JSONPath("$.e").keySet(map)); + } + + public static class Entity { + private Long id; + private String name; + public Long age; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_like.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_like.java new file mode 100644 index 0000000000..33f1e3beaa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_like.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.junit.Assert; + + +public class JSONPath_like extends TestCase { + public void test_like_not_match() throws Exception { + assertNull( + JSONPath.read("{\"table\":\"_order_base\"}", "[table LIKE 'order_base%']")); + } + + public void test_like_not_match_1() throws Exception { + assertEquals("{\"table\":\"_order_base\"}", + JSONPath.read("{\"table\":\"_order_base\"}", "[table LIKE '_order_base%']").toString()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_max.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_max.java new file mode 100644 index 0000000000..7087b7ba97 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_max.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +import java.math.BigDecimal; + +public class JSONPath_max extends TestCase { + public void test_max() throws Exception { + Object root = JSON.parse("[1,3,9, 5, 2, 4]"); + assertEquals(9, JSONPath.eval(root, "$.max()")); + } + + public void test_max_1() throws Exception { + Object root = JSON.parse("[1,6,7L,3,8,9.1, 5, 2L, 4]"); + assertEquals(new BigDecimal("9.1"), JSONPath.eval(root, "$.max()")); + } + + public void test_max_2() throws Exception { + Object root = JSON.parse("[1,6,7L,3,3.1D,8,9.1D, 5, 2L, 4]"); + assertEquals(9.1D, JSONPath.eval(root, "$.max()")); + } + + public void test_max_3() throws Exception { + Object root = JSON.parse("[1,6,7L,3,3.1F,8,9.1F, 5, 2L, 4]"); + assertEquals(9.1F, JSONPath.eval(root, "$.max()")); + } + + public void test_max_4() throws Exception { + Object root = JSON.parse("['1', '111', '2']"); + assertEquals("2", JSONPath.eval(root, "$.max()")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_min.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_min.java new file mode 100644 index 0000000000..73494cfff5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_min.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +import java.math.BigDecimal; + +public class JSONPath_min extends TestCase { + public void test_max() throws Exception { + Object root = JSON.parse("[1,3,9, 5, 2, 4]"); + assertEquals(1, JSONPath.eval(root, "$.min()")); + } + + public void test_max_1() throws Exception { + Object root = JSON.parse("[1,6,7L,3,8,9.1, 5, 2L, 4]"); + assertEquals(1, JSONPath.eval(root, "$.min()")); + } + + public void test_max_2() throws Exception { + Object root = JSON.parse("[1,6,7L,3,3.1D,8,9.1F, 5, 2L, 4]"); + assertEquals(1, JSONPath.eval(root, "$.min()")); + } + + public void test_max_3() throws Exception { + Object root = JSON.parse("[1,6,7L,3,3.1F,8,9.1F, 5, 2L, 4]"); + assertEquals(1, JSONPath.eval(root, "$.min()")); + } + + public void test_max_4() throws Exception { + Object root = JSON.parse("['1', '111', '2']"); + assertEquals("1", JSONPath.eval(root, "$.min()")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_object_filter.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_object_filter.java index c67ddc4ebf..2ef2976707 100644 --- a/src/test/java/com/alibaba/json/bvt/path/JSONPath_object_filter.java +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_object_filter.java @@ -22,7 +22,7 @@ public void test_object_filter_not_match() throws Exception { Entity entity = new Entity(123, "ljw2083"); Assert.assertNull(path.eval(entity)); } - + public static class Entity { private Integer id; diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_oracle_compatible_test.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_oracle_compatible_test.java new file mode 100644 index 0000000000..b568b8fce0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_oracle_compatible_test.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_oracle_compatible_test + extends TestCase +{ + public void test_reserve() throws Exception { + JSONObject object = JSON.parseObject(str); + + assertEquals("Sayings of the Century", JSONPath.eval(object, "$.store.book[0].title")); + assertEquals("Sayings of the Century", JSONPath.eval(object, "$['store']['book'][0]['title']")); + } + + + public static final String str = "{\n" + + " \"store\": {\n" + + " \"book\": [\n" + + " {\n" + + " \"category\": \"reference\",\n" + + "\n" + + " \"author\": \"Nigel Rees\",\n" + + "\n" + + " \"title\": \"Sayings of the Century\",\n" + + "\n" + + " \"price\": 8.95\n" + + " },\n" + + " {\n" + + " \"category\": \"fiction\",\n" + + " \"author\": \"Evelyn Waugh\",\n" + + " \"title\": \"Sword of Honour\",\n" + + " \"price\": 12.99\n" + + " },\n" + + " {\n" + + " \"category\": \"fiction\",\n" + + " \"author\": \"Herman Melville\",\n" + + " \"title\": \"Moby Dick\",\n" + + " \"isbn\": \"0-553-21311-3\",\n" + + " \"price\": 8.99\n" + + " },\n" + + " {\n" + + " \"category\": \"fiction\",\n" + + " \"author\": \"J. R. R. Tolkien\",\n" + + " \"title\": \"The Lord of the Rings\",\n" + + " \"isbn\": \"0-395-19395-8\",\n" + + " \"price\": 22.99\n" + + " }\n" + + " ],\n" + + " \"bicycle\": {\n" + + " \"color\": \"red\",\n" + + " \"price\": 19.95\n" + + " }\n" + + " },\n" + + " \"expensive\": 10\n" + + "}"; +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_reverse_test.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_reverse_test.java new file mode 100644 index 0000000000..c5ed175b48 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_reverse_test.java @@ -0,0 +1,43 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class JSONPath_reverse_test extends TestCase +{ + public void test_reserve() throws Exception { + JSONObject object = JSON.parseObject("{\"id\":1001,\"name\":\"ljw\",\"age\":50}"); + + assertEquals("[1001,\"ljw\"]", JSONPath.reserveToArray(object, "id", "name").toString()); + assertEquals("[\"ljw\",1001]", JSONPath.reserveToArray(object, "name", "id").toString()); + String text = JSON.toJSONString(JSONPath.reserveToArray(object, "name", "*"), SerializerFeature.MapSortField); + assertTrue(text.equals("[\"ljw\",[\"ljw\",1001,50]]") + || text.equals("[\"ljw\",[\"ljw\",50,1001]]") + || text.equals("[\"ljw\",[50,1001,\"ljw\"]]") + || text.equals("[\"ljw\",[1001,50,\"ljw\"]]") + || text.equals("[\"ljw\",[1001,\"ljw\",50]]") + || text.equals("[\"ljw\",[50,\"ljw\",1001]]")); + } + + public void test_reserve2() throws Exception { + JSONObject object = JSON.parseObject("{\"id\":1001,\"name\":\"ljw\",\"age\":50}"); + + assertEquals("{\"id\":1001,\"name\":\"ljw\"}", JSONPath.reserveToObject(object, "id", "name").toString()); + assertEquals("{\"name\":\"ljw\",\"id\":1001}", JSONPath.reserveToObject(object, "name", "id").toString()); + } + + + public void test_reserve3() throws Exception { + JSONObject object = JSON.parseObject("{\"player\":{\"id\":1001,\"name\":\"ljw\",\"age\":50}}"); + + String text = JSON.toJSONString(JSONPath.reserveToObject(object, "player.id", "player.name"), SerializerFeature.MapSortField); + assertEquals("{\"player\":{\"id\":1001,\"name\":\"ljw\"}}", text); + text = JSON.toJSONString(JSONPath.reserveToObject(object, "player.name", "player.id", "ab.c"), SerializerFeature.MapSortField); + assertEquals("{\"player\":{\"id\":1001,\"name\":\"ljw\"}}", text); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_set_test7.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_set_test7.java new file mode 100644 index 0000000000..4cf3616d86 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_set_test7.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_set_test7 extends TestCase { + public void test_jsonpath_1() throws Exception { + JSONObject aa= new JSONObject(); + aa.put("val", "false"); + JSONPath path = JSONPath.compile("$.val"); + + path.set(aa, true); + assertEquals(true, aa.getBoolean("val").booleanValue()); + + path.set(aa, false); + assertEquals(false, aa.getBoolean("val").booleanValue()); + } + + public void test_jsonpath_2() throws Exception { + VO aa = new VO(); + JSONPath path = JSONPath.compile("$.val"); + + path.set(aa, true); + assertEquals(true, aa.val); + + path.set(aa, false); + assertEquals(false, aa.val); + + path.set(aa, "true"); + assertEquals(true, aa.val); + + path.set(aa, "false"); + assertEquals(false, aa.val); + } + + + public static class VO { + public boolean val; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/TestSpecial_2.java b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_2.java new file mode 100644 index 0000000000..8412e67f83 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_2.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.HashMap; +import java.util.Map; + +public class TestSpecial_2 extends TestCase { + + public void test_special() throws Exception { + Model model = new Model(); + Value value = new Value(); + model.values.put("com.ibatis.sqlmap.client.SqlMapExecutor@queryForObject(String,Object)", value); + model.subInvokes.put("com.ibatis.sqlmap.client.SqlMapExecutor@queryForObject(String,Object)", value); + + String json = JSON.toJSONString(model); + System.out.println(json); + + Model m2 = JSON.parseObject(json, Model.class); + assertEquals(1, m2.values.size()); + assertEquals(1, m2.subInvokes.size()); + + assertSame(m2.values.values().iterator().next(), m2.subInvokes.values().iterator().next()); + } + + public static class Model { + public Map values = new HashMap(); + public Map subInvokes = new HashMap(); + } + + public static class Value { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/TestSpecial_3.java b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_3.java new file mode 100644 index 0000000000..59ba4bf3b7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_3.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.Map; + +public class TestSpecial_3 extends TestCase { + + public void test_special() throws Exception { + String json = "[{\"@type\":\"NAME_CORRECTION\",\"value\":23}]"; + JSONArray array = (JSONArray) JSON.parse(json, Feature.DisableSpecialKeyDetect); + Object obj = JSONPath.eval(array, "[\\@type='NAME_CORRECTION']"); + assertNotNull(obj); + } + + public void test_special_1() throws Exception { + String json = "[{\":lang\":\"NAME_CORRECTION\",\"value\":23}]"; + JSONArray array = (JSONArray) JSON.parse(json, Feature.DisableSpecialKeyDetect); + Object obj = JSONPath.eval(array, "[\\:lang='NAME_CORRECTION']"); + assertNotNull(obj); + } + + public void test_special_2() throws Exception { + String json = "{\"cpe-item\":{\"@name\":\"cpe:/a:google:chrome:4.0.249.19\",\"cpe-23:cpe23-item\":{\"@name\":\"cpe:2.3:a:google:chrome:4.0.249.19:*:*:*:*:*:*:*\"},\"title\":[{\"#text\":\"グーグル クローム 4.0.249.19\",\"@xml:lang\":\"ja-JP\"},{\"#text\":\"Google Chrome 4.0.249.19\",\"@xml:lang\":\"en-US\"}]}}"; + String path = "['cpe-item']['title'][\\@xml\\:lang='en-US']['#text'][0]"; + JSONObject object = (JSONObject) JSON.parse(json, Feature.DisableSpecialKeyDetect); + Object obj = JSONPath.eval(object, path); + assertNotNull(obj); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/TestSpecial_4.java b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_4.java new file mode 100644 index 0000000000..4a12a03a25 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_4.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.path; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; +import junit.framework.TestCase; + +public class TestSpecial_4 extends TestCase { + + public void test_special() throws Exception { + String json = "{\"大小\":123}"; + JSONObject object = JSON.parseObject(json); + Object obj = JSONPath.eval(object, "$.大小"); + assertEquals(123, obj); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_0.java b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_0.java new file mode 100644 index 0000000000..89d8d82685 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_0.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.path.extract; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_extract_0 extends TestCase { + public void test_0() throws Exception { + String json = "{\"id\":123,\"obj\":{\"id\":123}}"; + + assertEquals("{\"id\":123}" + , JSONPath.extract(json, "$.obj") + .toString()); + } + + public void test_1() throws Exception { + String json = "{\"f1\":1,\"f2\":2,\"f3\":3,\"f4\":4}"; + + assertEquals("2" + , JSONPath.extract(json, "$.f2") + .toString()); + } + + public void test_2() throws Exception { + assertEquals("{}" + , JSONPath.extract("{}", "$") + .toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_1.java b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_1.java new file mode 100644 index 0000000000..cf8a867696 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_1.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.path.extract; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +import java.net.InetSocketAddress; + +public class JSONPath_extract_1 extends TestCase { + public void test_0() throws Exception { + String json = "[{\"id\":1001},{\"id\":1002},{\"id\":1003},[1],123,-4,\"a\\\"bc\"]"; + + assertEquals("{\"id\":1001}" + , JSONPath.extract(json, "$.0") + .toString()); + + assertEquals("{\"id\":1002}" + , JSONPath.extract(json, "$.1") + .toString()); + + + assertEquals("{\"id\":1003}" + , JSONPath.extract(json, "$.2") + .toString()); + + assertEquals("[1]" + , JSONPath.extract(json, "$.3") + .toString()); + + assertEquals("123" + , JSONPath.extract(json, "$.4") + .toString()); + + assertEquals("-4" + , JSONPath.extract(json, "$.5") + .toString()); + + assertEquals("a\"bc" + , JSONPath.extract(json, "$.6") + .toString()); + } + + public void test_1() throws Exception { + String json = "[\"a\\\"bc\",123]"; + + assertEquals("a\"bc" + , JSONPath.extract(json, "$.0") + .toString()); + + assertEquals("123" + , JSONPath.extract(json, "$.1") + .toString()); + } + + public void test_2() throws Exception { + String json = "[\"a\\\\bc\",123]"; + + assertEquals("a\\bc" + , JSONPath.extract(json, "$.0") + .toString()); + + assertEquals("123" + , JSONPath.extract(json, "$.1") + .toString()); + } + + public void test_3() throws Exception { + String json = "[\"a\\\"b\\\\c\\\"d\\\"e\",123]"; + + assertEquals("a\"b\\c\"d\"e" + , JSONPath.extract(json, "$.0") + .toString()); + + assertEquals("123" + , JSONPath.extract(json, "$.1") + .toString()); + + assertNull(JSONPath.extract(json, "$.2")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_2_book.java b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_2_book.java new file mode 100644 index 0000000000..3da9e64b82 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_2_book.java @@ -0,0 +1,128 @@ +package com.alibaba.json.bvt.path.extract; + +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.util.IOUtils; +import junit.framework.TestCase; + +import java.io.InputStream; +import java.io.InputStreamReader; + +public class JSONPath_extract_2_book extends TestCase { + + public void test_0() throws Exception { + assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]" + , JSONPath.extract(json, "$.store.book.author") + .toString()); + } + + public void test_1() throws Exception { + assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]" + , JSONPath.extract(json, "$.store.book[*].author") + .toString()); + } + + public void test_2() throws Exception { + assertNull(JSONPath.extract(json, "$.author")); + } + + public void test_3() throws Exception { + assertEquals("[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]" + , JSONPath.extract(json, "$..author") + .toString()); + } + + public void test_4() throws Exception { + assertEquals("[[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}],{\"color\":\"red\",\"price\":19.95}]" + , JSONPath.extract(json, "$.store.*") + .toString()); + } + + public void test_5() throws Exception { + assertEquals("$.store..price", "[8.95,12.99,8.99,22.99,19.95]" + , JSONPath.extract(json, "$.store..price") + .toString()); + } + + public void test_6() throws Exception { + assertEquals("{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}" + , JSONPath.extract(json, "$..book[2]") + .toString()); + } + + public void test_7 () throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99}]" + , JSONPath.extract(json, "$..book[0,1]") + .toString()); + } + + public void test_8() throws Exception { + assertEquals("{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}" + , JSONPath.extract(json, "$..book[-2]") + .toString()); + } + + public void test_9() throws Exception { + assertEquals("Nigel Rees" + , JSONPath.extract(json, "$['store']['book'][0]['author']") + .toString()); + + assertEquals("Evelyn Waugh" + , JSONPath.extract(json, "$['store']['book'][1]['author']") + .toString()); + + assertEquals("Herman Melville" + , JSONPath.extract(json, "$['store']['book'][2]['author']") + .toString()); + + assertEquals("J. R. R. Tolkien" + , JSONPath.extract(json, "$['store']['book'][3]['author']") + .toString()); + } + + public void test_10() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}]" + , JSONPath.extract(json, "$.store.book[?(@.price < 10)]") + .toString()); + } + + public void test_11() throws Exception { + assertEquals("10" + , JSONPath.extract(json, "$.expensive") + .toString()); + } + + public void test_12() throws Exception { + assertNull(JSONPath.extract(json, "$.store.book.doesnt_exist")); + } + + public void test_13() throws Exception { + assertEquals("J. R. R. Tolkien", JSONPath.extract(json, "$.store.book[3].author")); + } + + public void test_14() throws Exception { + assertEquals("[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}]" + , JSONPath.extract(json, "$.store.book").toString()); + } + + public void test_15() throws Exception { + assertEquals("{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95}" + , JSONPath.extract(json, "$[\"store\"][\"book\"][0]").toString()); + } + + public void test_16() throws Exception { + assertNull(JSONPath.extract(json, "$.store.object.inner_object.array[0].inner_array[0].x")); + } + + public void test_17() throws Exception { + assertEquals(4, JSONPath.extract(json, "$..book.length()")); + } + + + private static String json; + static { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("json/book.json"); + InputStreamReader reader = new InputStreamReader(is); + json = IOUtils.readAll(reader); + IOUtils.close(reader); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_3.java b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_3.java new file mode 100644 index 0000000000..ff23cff683 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_3.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.path.extract; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_extract_3 extends TestCase { + + public void test_0() throws Exception { + assertEquals("male" + , JSONPath.extract(json, "$[0]['gender']") + .toString()); + } + + public void test_1() throws Exception { + assertNull(JSONPath.extract(json, "$[1]['gender']")); + } + + public void test_2() throws Exception { + assertEquals("ben" + , JSONPath.extract(json, "$[1]['name']").toString()); + } + + private static final String json = "[\n" + + " {\n" + + " \"name\" : \"john\",\n" + + " \"gender\" : \"male\"\n" + + " },\n" + + " {\n" + + " \"name\" : \"ben\"\n" + + " }\n" + + "]"; +} diff --git a/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_4_multi.java b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_4_multi.java new file mode 100644 index 0000000000..9a38cc216b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/extract/JSONPath_extract_4_multi.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.path.extract; + +import com.alibaba.fastjson.JSONPath; +import junit.framework.TestCase; + +public class JSONPath_extract_4_multi extends TestCase { + + public void test_0() throws Exception { + assertEquals("[\"male\",\"john\"]" + , JSONPath.extract(json, "$[0]['gender','name']") + .toString()); + } + public void test_1() throws Exception { + assertEquals("[\"john\",\"male\"]" + , JSONPath.extract(json, "$[0]['name','gender']") + .toString()); + } + + private static final String json = "[\n" + + " {\n" + + " \"name\" : \"john\",\n" + + " \"gender\" : \"male\"\n" + + " },\n" + + " {\n" + + " \"name\" : \"ben\"\n" + + " }\n" + + "]"; +} diff --git a/src/test/java/com/alibaba/json/bvt/proxy/TestProxy.java b/src/test/java/com/alibaba/json/bvt/proxy/TestProxy.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest11.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest11.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest12.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest12.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest13.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest13.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest14.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest14.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest15.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest15.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest16.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest16.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest17.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest17.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest23.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest23.java new file mode 100644 index 0000000000..e817e59793 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/RefTest23.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.ref; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +/** + * Created by wenshao on 16/8/23. + */ +public class RefTest23 extends TestCase { + public void test_ref() throws Exception { + String json = "{\"$ref\":\"tmall/item\",\"id\":123}"; + JSONObject root = JSON.parseObject(json); + assertEquals("tmall/item", root.get("$ref")); + assertEquals(123, root.get("id")); + } + + public void test_ref_1() throws Exception { + String json = "{\"$ref\":123}"; + JSONObject root = JSON.parseObject(json); + assertEquals(123, root.get("$ref")); + } + + public void test_ref_2() throws Exception { + String json = "{\n" + + "\t\"bbbb\\\"\":{\n" + + "\t\t\"x\":\"x\"\n" + + "\t},\n" + + "\t\"aaaa\\\"\":{\"$ref\":\"$.bbbb\\\\\\\"\"}\n" + + "}"; + System.out.println(json); + JSONObject root = JSON.parseObject(json); + assertSame(root.get("bbbb\\"), root.get("aaaa\\")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/RefTest24.java b/src/test/java/com/alibaba/json/bvt/ref/RefTest24.java new file mode 100644 index 0000000000..f5738c6138 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/RefTest24.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.ref; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Created by wenshao on 16/8/23. + */ +public class RefTest24 + extends TestCase { + public void test_ref() throws Exception { + ByteCodeDO codeDO = new ByteCodeDO(); + codeDO.id = 1001; + + Map data = new LinkedHashMap(); + Map m1 = new LinkedHashMap(); + m1.put("23\"299\\6 $85@47", codeDO); + Map m2 = new LinkedHashMap(); + m2.put("23299685@47", codeDO); + data.put("com.alibaba.extAppConfigs", m1); + data.put("com.alibaba.appConfigs", m2); + String str = JSON.toJSONString(data); + + Object o = JSON.parseObject(str, Feature.OrderedField); + + assertEquals(str, JSON.toJSONString(o, SerializerFeature.WriteMapNullValue)); + } + + public static class ByteCodeDO { + public int id; + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BooleanArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/BooleanArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest_primitive.java b/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BugTest0.java b/src/test/java/com/alibaba/json/bvt/serializer/BugTest0.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BugTest1.java b/src/test/java/com/alibaba/json/bvt/serializer/BugTest1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BugTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/BugTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/Bug_for_yegaofei.java b/src/test/java/com/alibaba/json/bvt/serializer/Bug_for_yegaofei.java new file mode 100644 index 0000000000..8b4779f194 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/Bug_for_yegaofei.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.FieldSerializer; +import com.alibaba.fastjson.serializer.JavaBeanSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.json.bvtVO.alipay.PlatformDepartmentVO; +import junit.framework.TestCase; + +import java.lang.reflect.Field; + +public class Bug_for_yegaofei extends TestCase { + public void test_0() throws Exception { + PlatformDepartmentVO vo = new PlatformDepartmentVO(); + vo.setId("xx"); + JSON.toJSONString(vo); + JavaBeanSerializer serializer = (JavaBeanSerializer) SerializeConfig.globalInstance.getObjectWriter(PlatformDepartmentVO.class); + Field field = JavaBeanSerializer.class.getDeclaredField("getters"); + field.setAccessible(true); + FieldSerializer[] getters = (FieldSerializer[]) field.get(serializer); + for (FieldSerializer getter : getters) { + assertNotNull(getter); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayFieldSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ByteArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ByteArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/CharArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/CharTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/CharsetSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharsetSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/CharsetTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharsetTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/CircularReferencesTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CircularReferencesTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ClobSeriliazerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ClobSerializerTest.java similarity index 98% rename from src/test/java/com/alibaba/json/bvt/serializer/ClobSeriliazerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ClobSerializerTest.java index 1faf861033..e620b0c578 100644 --- a/src/test/java/com/alibaba/json/bvt/serializer/ClobSeriliazerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ClobSerializerTest.java @@ -15,7 +15,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; -public class ClobSeriliazerTest extends TestCase { +public class ClobSerializerTest extends TestCase { public void test_clob() throws Exception { Assert.assertEquals("\"abcdefg中国\"", JSON.toJSONString(new MockClob("abcdefg中国"))); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/CollectionSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CollectionSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ColorSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ColorSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest5.java b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest5.java index 99a532d4ba..00fac8a7a1 100644 --- a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest5.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest5.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import com.alibaba.fastjson.serializer.SerializeConfig; import junit.framework.TestCase; import org.junit.Assert; @@ -18,7 +19,7 @@ public class ConcurrentHashMapTest5 extends TestCase { public void test_concurrentHashmap() throws Exception { OffsetSerializeWrapper wrapper = new OffsetSerializeWrapper(); wrapper.offsetTable.put(new MessageQueue(), new WeakReference(new A(true))); - String text = JSON.toJSONString(wrapper); + String text = JSON.toJSONString(wrapper, new SerializeConfig()); Assert.assertEquals("{\"offsetTable\":{{\"items\":[]}:{\"value\":true}}}", text); OffsetSerializeWrapper wrapper2 = JSON.parseObject(text, OffsetSerializeWrapper.class); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DoubleArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/DoubleArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest.java b/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ErrorGetterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ErrorGetterTest.java new file mode 100644 index 0000000000..ce55216471 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ErrorGetterTest.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import junit.framework.TestCase; + +public class ErrorGetterTest extends TestCase { + + public void test_0() throws Exception { + Model m = new Model(); + + Exception error = null; + try { + JSON.toJSONString(m); + } catch (JSONException ex) { + error = ex; + } + assertNotNull(error); + } + + private static class Model { + public int getValue() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ExtendsTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ExtendsTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/FileTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FileTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/FloatArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FloatArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/FloatTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FloatTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/FontSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FontSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/IgoreGetterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IgoreGetterTest.java new file mode 100644 index 0000000000..5bcc0615d5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/IgoreGetterTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; + +public class IgoreGetterTest extends TestCase { + public void test_for_issue() throws Exception { + VO vo = new VO(); + assertEquals("{}", JSON.toJSONString(vo)); + } + + public static class VO { + public InputStream getInputStream() { + throw new UnsupportedOperationException(); + } + + public Reader getReader() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/InetAddressTest.java b/src/test/java/com/alibaba/json/bvt/serializer/InetAddressTest.java old mode 100755 new mode 100644 index c39f686745..c06d56b5dc --- a/src/test/java/com/alibaba/json/bvt/serializer/InetAddressTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/InetAddressTest.java @@ -2,6 +2,7 @@ import java.net.InetAddress; +import com.alibaba.fastjson.parser.ParserConfig; import org.junit.Assert; import junit.framework.TestCase; @@ -18,6 +19,7 @@ public void test_inetAddress() throws Exception { InetAddress address2 = JSON.parseObject(text, InetAddress.class); Assert.assertEquals(address, address2); + ParserConfig.getGlobalInstance().getDeserializer(InetAddress.class); } public void test_null() throws Exception { diff --git a/src/test/java/com/alibaba/json/bvt/serializer/InetSocketAddressTest.java b/src/test/java/com/alibaba/json/bvt/serializer/InetSocketAddressTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/IntArrayEncodeTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntArrayEncodeTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayEncodeTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayEncodeTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayFieldSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/IntegerSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntegerSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/InterfaceTest.java b/src/test/java/com/alibaba/json/bvt/serializer/InterfaceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest6.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest6.java new file mode 100644 index 0000000000..7e9cb2c023 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest6.java @@ -0,0 +1,121 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import java.util.HashMap; +import java.util.Map; +import junit.framework.TestCase; + +public class JSONFieldTest6 extends TestCase { + + public void test_for_issue1() + { + NonStringMap nonStringMap = new NonStringMap(); + Map map1 = new HashMap(); + map1.put( 111,666 ); + nonStringMap.setMap1( map1 ); + String json = JSON.toJSONString( nonStringMap ); + assertEquals( "{\"map1\":{\"111\":666}}", json ); + } + + public void test_for_issue2() + { + NonStringMap nonStringMap = new NonStringMap(); + Map map2 = new HashMap(); + map2.put( 222,888 ); + nonStringMap.setMap2( map2 ); + String json = JSON.toJSONString( nonStringMap ); + assertEquals( "{\"map2\":{222:\"888\"}}", json ); + } + + public void test_for_issue3() + { + NonStringMap nonStringMap = new NonStringMap(); + Map map3 = new HashMap(); + map3.put( 333,999 ); + nonStringMap.setMap3( map3 ); + String json = JSON.toJSONString( nonStringMap ); + assertEquals( "{\"map3\":{\"333\":\"999\"}}", json ); + } + + public void test_for_issue4() + { + NonStringMap nonStringMap = new NonStringMap(); + Bean person = new Bean(); + person.setAge( 23 ); + nonStringMap.setPerson( person ); + String json = JSON.toJSONString( nonStringMap ); + assertEquals( "{\"person\":{\"age\":\"23\"}}", json ); + } + + class NonStringMap + { + @JSONField( serialzeFeatures = {SerializerFeature.WriteNonStringKeyAsString} ) + private Map map1; + + public Map getMap1() + { + return map1; + } + + public void setMap1( Map map1 ) + { + this.map1 = map1; + } + + @JSONField( serialzeFeatures = {SerializerFeature.WriteNonStringValueAsString} ) + private Map map2; + + public Map getMap2() + { + return map2; + } + + public void setMap2( Map map2 ) + { + this.map2 = map2; + } + + @JSONField( serialzeFeatures = {SerializerFeature.WriteNonStringKeyAsString, SerializerFeature.WriteNonStringValueAsString} ) + private Map map3; + + public Map getMap3() + { + return map3; + } + + public void setMap3( Map map3 ) + { + this.map3 = map3; + } + + @JSONField( serialzeFeatures = {SerializerFeature.WriteNonStringValueAsString} ) + private Bean person; + + public Bean getPerson() + { + return person; + } + + public void setPerson( Bean person ) + { + this.person = person; + } + } + + class Bean { + private int age; + + public int getAge() + { + return age; + } + + public void setAge( int age ) + { + this.age = age; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest_unwrapped_6.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest_unwrapped_6.java new file mode 100644 index 0000000000..679bb99c83 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest_unwrapped_6.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.List; + +public class JSONFieldTest_unwrapped_6 extends TestCase { + + public void test_jsonField() throws Exception { + Health vo = new Health(); + List cities = new ArrayList(); + cities.add("Beijing"); + cities.add("Shanghai"); + vo.id = 123; + vo.cities = cities; + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"cities\":[\"Beijing\",\"Shanghai\"],\"id\":123}", text); + + Health vo2 = JSON.parseObject(text, Health.class); + assertNotNull(vo2.cities); + assertEquals("Beijing", vo2.cities.get(0)); + assertEquals("Shanghai", vo2.cities.get(1)); + + } + + public void test_null() throws Exception { + Health vo = new Health(); + vo.id = 123; + vo.cities = null; + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"id\":123}", text); + } + + public void test_empty() throws Exception { + Health vo = new Health(); + vo.id = 123; + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"id\":123}", text); + } + + public static class Health { + @JSONField(unwrapped = true) + public int id; + + @JSONField(unwrapped = true) + public List cities; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest_unwrapped_7.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest_unwrapped_7.java new file mode 100644 index 0000000000..a5f89017da --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest_unwrapped_7.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.List; + +public class JSONFieldTest_unwrapped_7 extends TestCase { + + public void test_jsonField() throws Exception { + String str = "{\"s\":\"[\\\"123\\\",\\\"xyz\\\"]\"}"; + System.out.println(str); + + A a = JSON.parseObject(str, A.class); + System.out.println(a.getS()); + + } + public static class A { + private List s; + + public List getS() { + return s; + } + + @JSONField(unwrapped = true) + public void setS(List s) { + this.s = s; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerFeatureTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerFeatureTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerMapTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerMapTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest1.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest1.java old mode 100755 new mode 100644 index 9a8ecc38a6..81bda64e50 --- a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest1.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest1.java @@ -1,11 +1,17 @@ package com.alibaba.json.bvt.serializer; +import com.alibaba.fastjson.JSON; import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.SerializeWriter; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + public class JSONSerializerTest1 extends TestCase { public void test_0 () throws Exception { SerializeWriter out = new SerializeWriter(); @@ -22,4 +28,43 @@ public void test_0 () throws Exception { serializer.writeWithFormat("123", null); } + + public void test_1() throws Exception { + SerializeWriter out = new SerializeWriter(); + JSONSerializer serializer = new JSONSerializer(out); + + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(2019, Calendar.SEPTEMBER, 5); + Date date = calendar.getTime(); + + String dateFormatPattern = "yyyy/MM/dd"; + SimpleDateFormat sdf = new SimpleDateFormat(dateFormatPattern); + + serializer.writeWithFormat(date, dateFormatPattern); + + assertEquals("\"" + sdf.format(date) + "\"", serializer.out.toString()); + } + + public void test_2() throws Exception { + SerializeWriter out = new SerializeWriter(); + JSONSerializer serializer = new JSONSerializer(out); + + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(2019, Calendar.SEPTEMBER, 5); + Date date = calendar.getTime(); + + String dateFormatPattern = "yyyy.MM.dd"; + String temp = JSON.DEFFAULT_DATE_FORMAT; + JSON.DEFFAULT_DATE_FORMAT = dateFormatPattern; + + SimpleDateFormat sdf = new SimpleDateFormat(JSON.DEFFAULT_DATE_FORMAT); + //传入null时调用JSON.DEFFAULT_DATE_FORMAT + serializer.writeWithFormat(date, null); + + JSON.DEFFAULT_DATE_FORMAT = temp; + + assertEquals("\"" + sdf.format(date) + "\"", serializer.out.toString()); + } } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java old mode 100755 new mode 100644 index c32529640f..5a70a316b1 --- a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java @@ -15,6 +15,7 @@ public class JSONSerializerTest2 extends TestCase { public void test_0() throws Exception { JSONSerializer serializer = new JSONSerializer(); + serializer.getMapping().clearSerializers(); int size = JSONSerializerMapTest.size(serializer.getMapping()); serializer.config(SerializerFeature.WriteEnumUsingToString, false); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ListTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ListTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/LocalTest.java b/src/test/java/com/alibaba/json/bvt/serializer/LocalTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/LongArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/LongArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/MapSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/MapSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/MapTest.java b/src/test/java/com/alibaba/json/bvt/serializer/MapTest.java old mode 100755 new mode 100644 index 37a070ff6b..380a3c4836 --- a/src/test/java/com/alibaba/json/bvt/serializer/MapTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/MapTest.java @@ -1,5 +1,6 @@ package com.alibaba.json.bvt.serializer; +import com.alibaba.fastjson.annotation.JSONField; import org.junit.Assert; import junit.framework.TestCase; @@ -10,6 +11,9 @@ import com.alibaba.fastjson.serializer.SerializeWriter; import com.alibaba.fastjson.serializer.SerializerFeature; +import java.util.HashMap; +import java.util.Map; + public class MapTest extends TestCase { public void test_no_sort() throws Exception { @@ -44,4 +48,27 @@ public static final String toJSONString(Object object) { out.close(); } } + + public void test_onJSONField() { + Map map = new HashMap(); + map.put("Ariston", null); + MapNullValue mapNullValue = new MapNullValue(); + mapNullValue.setMap( map ); + String json = JSON.toJSONString( mapNullValue ); + assertEquals("{\"map\":{\"Ariston\":null}}", json); + } + + class MapNullValue { + @JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue}) + private Map map; + + public Map getMap() { + return map; + } + + public void setMap( Map map ) { + this.map = map; + } + } + } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/NoneStringKeyTest.java b/src/test/java/com/alibaba/json/bvt/serializer/NoneStringKeyTest.java index 2f12959bb2..25c1295834 100644 --- a/src/test/java/com/alibaba/json/bvt/serializer/NoneStringKeyTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NoneStringKeyTest.java @@ -3,6 +3,7 @@ import java.util.HashMap; import java.util.Map; +import com.alibaba.fastjson.parser.Feature; import junit.framework.TestCase; import org.junit.Assert; @@ -47,4 +48,27 @@ public void test_3() throws Exception { Assert.assertEquals("{\"null\":101}", JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString)); } + + public void test_4() throws Exception { + SubjectDTO dto = new SubjectDTO(); + dto.getResults().put(3, new Result()); + + String json = JSON.toJSONString(dto); + assertEquals("{\"results\":{3:{}}}", json); + + SubjectDTO dto2 = JSON.parseObject(json, SubjectDTO.class, Feature.NonStringKeyAsString); + System.out.println(JSON.toJSONString(dto2.getResults())); + } + + public static class Result { + + } + + public static class SubjectDTO { + private Map results = new HashMap(); + + public Map getResults() { + return results; + } + } } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ObjectArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ObjectArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ParserConfigTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ParserConfigTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PatternTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PatternTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PointSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PointSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PrettyFormatTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PrettyFormatTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PrettyFormatTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/PrettyFormatTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PrimitiveTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PrimitiveTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RectangleSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/RectangleSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerialContextTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerialContextTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeConfigTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeConfigTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_1.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_2.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_3.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_4.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_5.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_6.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_6.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_7.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_7.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializerFeatureTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializerFeatureTest.java old mode 100755 new mode 100644 index 1f970f6533..986d028e53 --- a/src/test/java/com/alibaba/json/bvt/serializer/SerializerFeatureTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializerFeatureTest.java @@ -22,4 +22,9 @@ public void test_1 () throws Exception { feature = SerializerFeature.config(feature, SerializerFeature.BrowserSecure, false); Assert.assertEquals(false, SerializerFeature.isEnabled(feature, SerializerFeature.BrowserSecure)); } + + public void test_assert_cnt() throws Exception { + int len = SerializerFeature.values().length; + assertTrue(len <= 32); + } } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerilaizeFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerilaizeFilterTest.java new file mode 100644 index 0000000000..0314054627 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerilaizeFilterTest.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.PropertyFilter; +import com.alibaba.fastjson.serializer.ValueFilter; +import junit.framework.TestCase; + +public class SerilaizeFilterTest extends TestCase { + public void test_for_jsonField() throws Exception { + Model m = new Model(); + String json = JSON.toJSONString(m); + System.out.println(json); + } + + public static class MyValueFilter implements ValueFilter { + + public Object process(Object object, String name, Object value) { + if (name.equals("id")) { + return 123; + } + + return null; + } + } + + @JSONType(serialzeFilters = MyValueFilter.class) + public static class Model { + + public int id; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ShortArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ShortArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ShortFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ShortFieldSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ShortSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ShortSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SimpleDataFormatSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SimpleDataFormatSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SimplePropertyPreFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SimplePropertyPreFilterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SpecicalStringTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SpecicalStringTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/StringArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/StringArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/StringSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/StringSerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass.java b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass1.java b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass2.java b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestPivateStaticClass.java b/src/test/java/com/alibaba/json/bvt/serializer/TestPivateStaticClass.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSortField.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSortField.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial6.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial6.java new file mode 100644 index 0000000000..7ba8f3d156 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial6.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.junit.Assert; + +public class TestSpecial6 extends TestCase { + + public void test_1() throws Exception { + + VO vo = new VO(); + vo.setValue("马䶮"); + + String text = JSON.toJSONString(vo); + VO vo2 = JSON.parseObject(text, VO.class); + Assert.assertEquals(vo.value, vo2.value); + + assertEquals("{\"value\":\"马䶮\"}", text); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TimeZoneTest.java b/src/test/java/com/alibaba/json/bvt/serializer/TimeZoneTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TransientTest.java b/src/test/java/com/alibaba/json/bvt/serializer/TransientTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TreeSetTest.java b/src/test/java/com/alibaba/json/bvt/serializer/TreeSetTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/URITest.java b/src/test/java/com/alibaba/json/bvt/serializer/URITest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/URLTest.java b/src/test/java/com/alibaba/json/bvt/serializer/URLTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/UUIDTest.java b/src/test/java/com/alibaba/json/bvt/serializer/UUIDTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/WriteClassNameTest.java b/src/test/java/com/alibaba/json/bvt/serializer/WriteClassNameTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/WriteNullListAsEmptyTest.java b/src/test/java/com/alibaba/json/bvt/serializer/WriteNullListAsEmptyTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest.java b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest4.java b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest4.java new file mode 100644 index 0000000000..e7c2216eb9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest4.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.serializer.date; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Date; + +public class DateTest4 extends TestCase { + + public void test_date() throws Exception { + assertNotNull( + JSON.parseObject( + "{\"gmtCreate\":\"1970-01-01 00:00:00\"}" + , VO.class) + .gmtCreate + ); + + assertNotNull( + JSON.parseObject( + "{\"gmtCreate\":\"1970-01-01 00:00:00.000\"}" + , VO.class) + .gmtCreate + ); + + assertNotNull( + JSON.parseObject( + "{\"gmtCreate\":\"1960-01-01 00:00:00.000\"}" + , VO.class) + .gmtCreate + ); + } + + public static class VO { + public Date gmtCreate; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest4_indian.java b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest4_indian.java new file mode 100644 index 0000000000..ae570c64fc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest4_indian.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.serializer.date; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class DateTest4_indian extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_date() throws Exception { + Date date1 = JSON.parseObject("{\"gmtCreate\":\"2018-09-11T21:29:34+0530\"}", VO.class).getGmtCreate(); + assertNotNull(date1); + Date date2 = JSON.parseObject("{\"gmtCreate\":\"2018-09-11T21:29:34+0500\"}", VO.class).getGmtCreate(); + Date date3 = JSON.parseObject("{\"gmtCreate\":\"2018-09-11T21:29:34+0545\"}", VO.class).getGmtCreate(); + Date date4 = JSON.parseObject("{\"gmtCreate\":\"2018-09-11T21:29:34+1245\"}", VO.class).getGmtCreate(); + Date date5 = JSON.parseObject("{\"gmtCreate\":\"2018-09-11T21:29:34+1345\"}", VO.class).getGmtCreate(); + + long delta_2_1 = date2.getTime() - date1.getTime(); + assertEquals(1800000, delta_2_1); + + long delta_3_1 = date3.getTime() - date1.getTime(); + assertEquals(-900000, delta_3_1); + + long delta_4_3 = date4.getTime() - date3.getTime(); + assertEquals(-25200000, delta_4_3); + + long delta_5_4 = date5.getTime() - date4.getTime(); + assertEquals(-3600000, delta_5_4); + + } + + public static class VO { + + private Date gmtCreate; + + public Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest5_iso8601.java b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest5_iso8601.java new file mode 100644 index 0000000000..1af740a245 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/date/DateTest5_iso8601.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.serializer.date; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class DateTest5_iso8601 extends TestCase { + protected void setUp() throws Exception { + JSON.defaultTimeZone = TimeZone.getTimeZone("Asia/Shanghai"); + JSON.defaultLocale = Locale.CHINA; + } + + public void test_date() throws Exception { + Date date1 = JSON.parseObject("{\"gmtCreate\":\"2018-09-12\"}", VO.class).getGmtCreate(); + assertNotNull(date1); + Date date2 = JSON.parseObject("{\"gmtCreate\":\"2018-09-12T15:10:19+00:00\"}", VO.class).getGmtCreate(); + Date date3 = JSON.parseObject("{\"gmtCreate\":\"2018-09-12T15:10:19Z\"}", VO.class).getGmtCreate(); + Date date4 = JSON.parseObject("{\"gmtCreate\":\"20180912T151019Z\"}", VO.class).getGmtCreate(); + Date date5 = JSON.parseObject("{\"gmtCreate\":\"2018-09-12T15:10:19Z\"}", VO.class).getGmtCreate(); + Date date6 = JSON.parseObject("{\"gmtCreate\":\"20180912\"}", VO.class).getGmtCreate(); + + long delta_2_1 = date2.getTime() - date1.getTime(); + assertEquals(83419000, delta_2_1); + + long delta_3_1 = date3.getTime() - date1.getTime(); + assertEquals(83419000, delta_3_1); + + long delta_4_3 = date4.getTime() - date3.getTime(); + assertEquals(0, delta_4_3); + + long delta_5_4 = date5.getTime() - date4.getTime(); + assertEquals(0, delta_5_4); + + long delta_6_1 = date6.getTime() - date1.getTime(); + assertEquals(0, delta_6_1); + + + } + + public static class VO { + + private Date gmtCreate; + + public Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest.java b/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest.java old mode 100755 new mode 100644 index e25f6d7ded..dc6faba320 --- a/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest.java @@ -24,4 +24,13 @@ public void test_enum() throws Exception { Assert.assertEquals("'Small'", JSON.toJSONString(Type.Small, SerializerFeature.UseSingleQuotes)); // "Small" } + public void test_empty() throws Exception { + Model model = JSON.parseObject("{\"type\":\"\"}", Model.class); + assertNull(model.type); + } + + public static class Model { + public Type type; + } + } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest4.java b/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest4.java new file mode 100644 index 0000000000..ef94fe0352 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/enum_/EnumTest4.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.serializer.enum_; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +public class EnumTest4 extends TestCase { + public void test_for_enum() throws Exception { + assertEquals("101", JSON.toJSONString(Type.Big)); + assertEquals("101", JSON.toJSONString(Type1.Big)); + } + + public enum Type { + Big(101), Small(102); + + @JSONField + public final int code; + + Type(int code) { + this.code = code; + } + } + + public enum Type1 { + Big(101), Small(102); + + private final int code; + + @JSONField + public int getCode() { + return code; + } + + Type1(int code) { + this.code = code; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/exception/RuntimeExceptionTest.java b/src/test/java/com/alibaba/json/bvt/serializer/exception/RuntimeExceptionTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/features/WriteBigDecimalAsPlainTest.java b/src/test/java/com/alibaba/json/bvt/serializer/features/WriteBigDecimalAsPlainTest.java index 64aeb2dbc5..bf9550ed20 100644 --- a/src/test/java/com/alibaba/json/bvt/serializer/features/WriteBigDecimalAsPlainTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/features/WriteBigDecimalAsPlainTest.java @@ -6,6 +6,7 @@ import org.junit.Assert; import java.math.BigDecimal; +import java.math.BigInteger; /** * Created by wenshao on 16/8/9. @@ -17,4 +18,43 @@ public void test_for_feature() throws Exception { Assert.assertEquals("1E-8", JSON.toJSONString(value)); Assert.assertEquals("0.00000001", JSON.toJSONString(value, SerializerFeature.WriteBigDecimalAsPlain)); } + + public void test_1() throws Exception { + Model m = new Model(); + m.value = new BigDecimal("0.00000001"); + + Assert.assertEquals("{\"value\":1E-8}", JSON.toJSONString(m)); + Assert.assertEquals("{\"value\":0.00000001}", JSON.toJSONString(m, SerializerFeature.WriteBigDecimalAsPlain)); + } + + public void test_for_feature_BigInteger() throws Exception { + BigInteger value = new BigInteger("2020020700826004000000000000"); + + Assert.assertEquals("2020020700826004000000000000", JSON.toJSONString(value)); + Assert.assertEquals("2020020700826004000000000000", JSON.toJSONString(value, SerializerFeature.WriteBigDecimalAsPlain)); + } + + public static class Model { + private BigDecimal value; + + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + } + + public static class ModelBigInteger { + private BigInteger value; + + public BigInteger getValue() { + return value; + } + + public void setValue(BigInteger value) { + this.value = value; + } + } } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/AppendableTest.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/AppendableTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/ArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/ArraySerializerTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/ContextValueClassLevelTest.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/ContextValueClassLevelTest.java index 779ab0cb5e..1d0c43e27c 100644 --- a/src/test/java/com/alibaba/json/bvt/serializer/filters/ContextValueClassLevelTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/filters/ContextValueClassLevelTest.java @@ -19,7 +19,6 @@ public void test_0() throws Exception { config.addFilter(ModelA.class, // new ContextValueFilter() { - @Override public Object process(BeanContext context, Object object, String name, Object value) { return 30001; } @@ -27,7 +26,6 @@ public Object process(BeanContext context, Object object, String name, Object va config.addFilter(ModelB.class, // new ContextValueFilter() { - @Override public Object process(BeanContext context, Object object, String name, Object value) { return 20001; } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_boolean.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_boolean.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_byte.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_byte.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_char.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_char.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_double.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_double.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_float.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_float.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_long.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_long.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_short.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/NameFilterTest_short.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_byte.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_byte.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_char.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_char.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_double.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_double.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_float.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_float.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_long.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_long.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_short.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyFilter_short.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyPathTest.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyPathTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyPathTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyPathTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyPathTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/PropertyPathTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/filters/ValueFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/filters/ValueFilterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListFieldTest.java b/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListFieldTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListTest.java b/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/stream/JSONWriterTest.java b/src/test/java/com/alibaba/json/bvt/stream/JSONWriterTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/support/jaxrs/FastJsonProviderTest.java b/src/test/java/com/alibaba/json/bvt/support/jaxrs/FastJsonProviderTest.java index c8e6729264..f482abd313 100644 --- a/src/test/java/com/alibaba/json/bvt/support/jaxrs/FastJsonProviderTest.java +++ b/src/test/java/com/alibaba/json/bvt/support/jaxrs/FastJsonProviderTest.java @@ -13,6 +13,8 @@ import javax.ws.rs.core.MultivaluedHashMap; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.charset.Charset; public class FastJsonProviderTest extends TestCase { @@ -60,6 +62,8 @@ public void test_1() throws Exception { Assert.assertEquals(false, provider.isWriteable(String.class, String.class, null, MediaType.valueOf("applications/x-json"))); Assert.assertEquals(false, provider.isReadable(null, null, null, MediaType.valueOf("application/x-javascript"))); Assert.assertEquals(false, provider.isWriteable(null, null, null, null)); + Assert.assertEquals(false, provider.isReadable(InputStream.class, null, null, MediaType.valueOf("application/x-javascript"))); + Assert.assertEquals(false, provider.isWriteable(OutputStream.class, null, null, null)); VO vo = (VO) provider.readFrom(null, VO.class, null, MediaType.APPLICATION_JSON_TYPE, null, new ByteArrayInputStream("{\"id\":123}".getBytes(Charset @@ -80,7 +84,6 @@ public void test_1() throws Exception { } catch (WebApplicationException ex) { Assert.assertNotNull(ex); } - } private SerializeFilter serializeFilter = new ValueFilter() { diff --git a/src/test/java/com/alibaba/json/bvt/support/moneta/MoneyNumberTest.java b/src/test/java/com/alibaba/json/bvt/support/moneta/MoneyNumberTest.java new file mode 100644 index 0000000000..85590921fc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/support/moneta/MoneyNumberTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.support.moneta; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.javamoney.moneta.Money; + +import javax.money.Monetary; +import java.math.BigDecimal; + +/** + * @Author :Nanqi + * @Date :Created in 01:31 2020/7/4 + */ +public class MoneyNumberTest extends TestCase { + public void test_for_issue() throws Exception { + // Integer + Money money = Money.of(5000, Monetary.getCurrency("EUR")); + String moneyJSON = JSON.toJSONString(money); + Money moneyBack = JSON.parseObject(moneyJSON, Money.class); + assertEquals(5000, moneyBack.getNumber().intValue()); + + // Long + money = Money.of(1000L, Monetary.getCurrency("EUR")); + moneyJSON = JSON.toJSONString(money); + moneyBack = JSON.parseObject(moneyJSON, Money.class); + assertEquals(1000, moneyBack.getNumber().longValue()); + + // Byte + money = Money.of(0x4a, Monetary.getCurrency("EUR")); + moneyJSON = JSON.toJSONString(money); + moneyBack = JSON.parseObject(moneyJSON, Money.class); + assertEquals(74, moneyBack.getNumber().intValue()); + + // double + money = Money.of(new Double(1.12), Monetary.getCurrency("EUR")); + moneyJSON = JSON.toJSONString(money); + moneyBack = JSON.parseObject(moneyJSON, Money.class); + assertEquals(1.12d, moneyBack.getNumber().doubleValue()); + + // float + money = Money.of(new Float("2.01"), Monetary.getCurrency("EUR")); + moneyJSON = JSON.toJSONString(money); + moneyBack = JSON.parseObject(moneyJSON, Money.class); + assertEquals(2.01f, moneyBack.getNumber().floatValue()); + + // short + money = Money.of(new Short("2"), Monetary.getCurrency("EUR")); + moneyJSON = JSON.toJSONString(money); + moneyBack = JSON.parseObject(moneyJSON, Money.class); + assertEquals(2, moneyBack.getNumber().shortValue()); + + // BigInteger + money = Money.of(new BigDecimal("999999999999999999999"), Monetary.getCurrency("EUR")); + moneyJSON = JSON.toJSONString(money); + moneyBack = JSON.parseObject(moneyJSON, Money.class); + assertEquals("999999999999999999999", moneyBack.getNumber().toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/support/moneta/MoneyTest.java b/src/test/java/com/alibaba/json/bvt/support/moneta/MoneyTest.java new file mode 100644 index 0000000000..4b55c78073 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/support/moneta/MoneyTest.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.support.moneta; + +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; +import org.javamoney.moneta.Money; + +import javax.money.Monetary; +import java.math.BigDecimal; + +public class MoneyTest extends TestCase { + public void test_for_issue() throws Exception { + Money money = Money.of(new BigDecimal("321.789"), Monetary.getCurrency("EUR")); + + String json = JSON.toJSONString(money); + assertEquals("{\"numberStripped\":321.789,\"currency\":\"EUR\"}", json); + Money money2 = JSON.parseObject(json, Money.class); + assertEquals(Monetary.getCurrency("EUR"), money2.getCurrency()); + assertEquals(new BigDecimal("321.789"), money2.getNumber().numberValue(BigDecimal.class)); + } + + public void test_compatible() throws Exception { + String json = "{\"context\":{\"amountType\":\"org.javamoney.moneta.Money\",\"empty\":false,\"fixedScale\":false,\"maxScale\":-1,\"precision\":256},\"currency\":{\"context\":{\"empty\":false,\"providerName\":\"java.util.Currency\"},\"currencyCode\":\"EUR\",\"defaultFractionDigits\":2,\"numericCode\":978},\"factory\":{\"amountType\":\"org.javamoney.moneta.Money\",\"defaultMonetaryContext\":{\"amountType\":\"org.javamoney.moneta.Money\",\"empty\":false,\"fixedScale\":false,\"maxScale\":63,\"precision\":0},\"maximalMonetaryContext\":{\"amountType\":\"org.javamoney.moneta.Money\",\"empty\":false,\"fixedScale\":false,\"maxScale\":-1,\"precision\":0}},\"negative\":false,\"negativeOrZero\":false,\"number\":{\"amountFractionDenominator\":1000,\"amountFractionNumerator\":789,\"numberType\":\"java.math.BigDecimal\",\"precision\":6,\"scale\":3},\"numberStripped\":321.789,\"positive\":true,\"positiveOrZero\":true,\"zero\":false}"; + + Money money = JSON.parseObject(json, Money.class); + assertEquals(Monetary.getCurrency("EUR"), money.getCurrency()); + assertEquals(new BigDecimal("321.789"), money.getNumber().numberValue(BigDecimal.class)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/support/retrofit/Retrofit2ConverterFactoryTest0.java b/src/test/java/com/alibaba/json/bvt/support/retrofit/Retrofit2ConverterFactoryTest0.java new file mode 100644 index 0000000000..232ee6e6f0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/support/retrofit/Retrofit2ConverterFactoryTest0.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt.support.retrofit; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.retrofit.Retrofit2ConverterFactory; +import junit.framework.TestCase; +import okhttp3.Headers; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; +import okhttp3.internal.http.RealResponseBody; +import okio.Buffer; +import org.junit.Assert; + +import java.nio.charset.Charset; + +public class Retrofit2ConverterFactoryTest0 extends TestCase { + public void test_for_coverage() throws Exception { + Retrofit2ConverterFactory f = new Retrofit2ConverterFactory(); + f.getParserConfig(); + f.getParserFeatures(); + f.getParserFeatureValues(); + f.getSerializeConfig(); + f.getSerializerFeatures(); + f.setParserConfig(ParserConfig.getGlobalInstance()); + f.setParserFeatures(new Feature[0]); + f.setParserFeatureValues(0); + f.setSerializeConfig(SerializeConfig.globalInstance); + f.setSerializerFeatures(new SerializerFeature[0]); + f.getFastJsonConfig(); + f.setFastJsonConfig(new FastJsonConfig()); + f.requestBodyConverter(Model.class, null, null, null); + f.responseBodyConverter(Model.class, null, null); + + final Model model = new Model().setId(1).setName("test"); + final String json = JSON.toJSONString(model); + final Buffer buffer = new Buffer().writeString(json, Charset.defaultCharset()); + final Headers headers = Headers.of("Content-Type", "application/json; charset=UTF-8"); + final ResponseBody body = new RealResponseBody(headers, buffer); + + RequestBody requestBody = Retrofit2ConverterFactory.create() + .requestBodyConverter(Model.class, null, null, null) + .convert(model); + + Assert.assertNotEquals(requestBody.contentLength(), 0); + + Model mode2 = (Model) Retrofit2ConverterFactory.create() + .responseBodyConverter(Model.class, null, null) + .convert(body); + + Assert.assertEquals(JSON.toJSONString(mode2), json); + } + + public static class Model { + + private int id; + private String name; + + public int getId() { + return id; + } + + public Model setId(int id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public Model setName(String name) { + this.name = name; + return this; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonRedisSerializerTest.java b/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonRedisSerializerTest.java index 6f00a04c27..f0dd7b5f1c 100644 --- a/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonRedisSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonRedisSerializerTest.java @@ -1,5 +1,8 @@ package com.alibaba.json.bvt.support.spring; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import com.google.common.base.Objects; import org.hamcrest.core.Is; @@ -50,6 +53,35 @@ public void test_5() { Assert.assertNull(serializer.deserialize(serializedValue)); } + /** + * for issue #2147 + */ + @Test + public void test_6() { + + FastJsonConfig fastJsonConfig = new FastJsonConfig(); + + SerializerFeature[] serializerFeatures = new SerializerFeature[]{ + SerializerFeature.WriteClassName + }; + fastJsonConfig.setSerializerFeatures(serializerFeatures); + + ParserConfig parserConfig = ParserConfig.getGlobalInstance(); + parserConfig.setAutoTypeSupport(true); + fastJsonConfig.setParserConfig(parserConfig); + + FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class); + Assert.assertNotNull(fastJsonRedisSerializer.getFastJsonConfig()); + fastJsonRedisSerializer.setFastJsonConfig(fastJsonConfig); + + User userSer = new User(1, "土豆", 25); + + byte[] serializedValue = fastJsonRedisSerializer.serialize(userSer); + User userDes = (User) fastJsonRedisSerializer.deserialize(serializedValue); + + Assert.assertEquals(userDes.getName(), "土豆"); + } + static class User { private Integer id; private String name; diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/GenericFastJsonRedisSerializerTest.java b/src/test/java/com/alibaba/json/bvt/support/spring/GenericFastJsonRedisSerializerTest.java index 5d1ccb542c..d1efa9f1e4 100644 --- a/src/test/java/com/alibaba/json/bvt/support/spring/GenericFastJsonRedisSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/support/spring/GenericFastJsonRedisSerializerTest.java @@ -1,7 +1,9 @@ package com.alibaba.json.bvt.support.spring; import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer; +import com.alibaba.fastjson.util.IOUtils; import com.google.common.base.Objects; +import com.google.common.collect.Lists; import org.hamcrest.core.Is; import org.hamcrest.core.IsNull; import org.junit.Assert; @@ -10,6 +12,7 @@ import org.springframework.data.redis.serializer.SerializationException; import java.util.Arrays; +import java.util.List; public class GenericFastJsonRedisSerializerTest { @@ -51,6 +54,43 @@ public void test_5() { serializer.deserialize(serializedValue); } + /** + * for issue #2155 + */ + @Test + public void test_6() { + + BaseResult> baseResult = new BaseResult>(); + baseResult.setCode("1000"); + baseResult.setMsg("success"); + baseResult.setData(Lists.newArrayList("测试1", "测试2", "测试3")); + + GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer(); + byte[] bytes = genericFastJsonRedisSerializer.serialize(baseResult); + BaseResult> baseResult2 = (BaseResult>) genericFastJsonRedisSerializer.deserialize(bytes); + + Assert.assertEquals(baseResult2.getCode(), "1000"); + Assert.assertEquals(baseResult2.getData().size(), 3); + + String json = "{\n" + + "\"@type\": \"com.alibaba.json.bvt.support.spring.GenericFastJsonRedisSerializerTest$BaseResult\",\n" + + "\"code\": \"1000\",\n" + + "\"data\": [\n" + + "\"按手动控制按钮\",\n" + + "\"不停机\",\n" + + "\"不转动\",\n" + + "\"传动轴振动大\",\n" + + "\"第一推进器\",\n" + + "\"电机不运行\",\n" + + "],\n" + + "\"msg\": \"success\"\n" + + "}"; + + BaseResult> baseResult3 = (BaseResult>) genericFastJsonRedisSerializer.deserialize(json.getBytes(IOUtils.UTF8)); + Assert.assertEquals(baseResult3.getCode(), "1000"); + Assert.assertEquals(baseResult3.getData().size(), 6); + } + static class User { private Integer id; private String name; @@ -89,4 +129,34 @@ public void setAge(Integer age) { this.age = age; } } + + static class BaseResult { + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + private String msg; + private String code; + private T data; + } } diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/messaging/MappingFastJsonMessageConverterTest.java b/src/test/java/com/alibaba/json/bvt/support/spring/messaging/MappingFastJsonMessageConverterTest.java new file mode 100644 index 0000000000..cf709decf0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/support/spring/messaging/MappingFastJsonMessageConverterTest.java @@ -0,0 +1,89 @@ +package com.alibaba.json.bvt.support.spring.messaging; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.messaging.MappingFastJsonMessageConverter; +import junit.framework.TestCase; +import org.junit.Assert; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + + +public class MappingFastJsonMessageConverterTest extends TestCase { + + public void test_1() throws Exception { + + MappingFastJsonMessageConverter converter = new MappingFastJsonMessageConverter(); + + Assert.assertNotNull(converter.getFastJsonConfig()); + converter.setFastJsonConfig(new FastJsonConfig()); + + VO p = new VO(); + p.setId(1); + + String pstr = JSON.toJSONString(p); + + System.out.println(pstr); + + TestMessage message = new TestMessage(pstr); + + // test fromMessage/convertFromInternal + VO vo = (VO) converter.fromMessage(message, VO.class); + Assert.assertEquals(1, vo.getId()); + + // test toMessage/convertToInternal + Message message1 = converter.toMessage(vo, null); + System.out.println(message1.getPayload()); + Assert.assertEquals("{\"id\":1}", new String((byte[]) message1.getPayload())); + +// // test toMessage/convertToInternal + Message message2 = converter.toMessage("{\"id\":1}", null); + System.out.println(message2.getPayload()); + Assert.assertEquals("{\"id\":1}", new String((byte[]) message2.getPayload())); + + converter.setSerializedPayloadClass(String.class); + + // test toMessage/convertToInternal + Message message3 = converter.toMessage(vo, null); + System.out.println(message3.getPayload()); + Assert.assertEquals("{\"id\":1}", message3.getPayload()); + +// // test toMessage/convertToInternal + Message message4 = converter.toMessage("{\"id\":1}", null); + System.out.println(message4.getPayload()); + Assert.assertEquals("{\"id\":1}", message4.getPayload()); + } + + public static class TestMessage implements Message { + + private T payload; + + public TestMessage(T payload) { + this.payload = payload; + } + + @Override + public T getPayload() { + return (T) payload; + } + + @Override + public MessageHeaders getHeaders() { + return null; + } + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case1Test.java b/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case1Test.java index 999c0b7fba..82b6259e19 100644 --- a/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case1Test.java +++ b/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case1Test.java @@ -19,6 +19,7 @@ import java.util.List; +import static junit.framework.TestCase.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -73,8 +74,10 @@ public void test1_2() throws Exception { ResultActions actions = mockMvc.perform((post("/fastjson/test1?callback=fnUpdateSome").characterEncoding( "UTF-8").content(json.toJSONString()).contentType(MediaType.APPLICATION_JSON))); actions.andDo(print()); - actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)) - .andExpect(content().string("/**/fnUpdateSome({\"name\":\"哈哈哈\",\"id\":123})")); + actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)); + String content = actions.andReturn().getResponse().getContentAsString(); + assertTrue(content.equals("/**/fnUpdateSome({\"name\":\"哈哈哈\",\"id\":123})") + || content.equals("/**/fnUpdateSome({\"id\":123,\"name\":\"哈哈哈\"})")); } @Test @@ -95,8 +98,10 @@ public void test2_2() throws Exception { ResultActions actions = mockMvc.perform((post("/fastjson/test2?jsonp=fnUpdateSome").characterEncoding("UTF-8") .content(jsonStr).contentType(MediaType.APPLICATION_JSON))); actions.andDo(print()); - actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)) - .andExpect(content().string("/**/fnUpdateSome({\"p1\":1,\"p2\":2})")); + actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)); + String content = actions.andReturn().getResponse().getContentAsString(); + assertTrue(content.equals("/**/fnUpdateSome({\"p1\":1,\"p2\":2})") + || content.equals("/**/fnUpdateSome({\"p2\":2,\"p1\":1})")); } @Test diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case2Test.java b/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case2Test.java index 240a8f760b..5aa00c9056 100644 --- a/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case2Test.java +++ b/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case2Test.java @@ -26,6 +26,7 @@ import java.util.List; +import static junit.framework.TestCase.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -96,8 +97,10 @@ public void test1_2() throws Exception { ResultActions actions = mockMvc.perform((post("/fastjson/test1?callback=fnUpdateSome").characterEncoding( "UTF-8").content(json.toJSONString()).contentType(MediaType.APPLICATION_JSON))); actions.andDo(print()); - actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)) - .andExpect(content().string("/**/fnUpdateSome({\"name\":\"哈哈哈\",\"id\":123})")); + actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)); + String content = actions.andReturn().getResponse().getContentAsString(); + assertTrue(content.equals("/**/fnUpdateSome({\"name\":\"哈哈哈\",\"id\":123})") + || content.equals("/**/fnUpdateSome({\"id\":123,\"name\":\"哈哈哈\"})")); } @Test @@ -118,8 +121,10 @@ public void test2_2() throws Exception { ResultActions actions = mockMvc.perform((post("/fastjson/test2?jsonp=fnUpdateSome").characterEncoding("UTF-8") .content(jsonStr).contentType(MediaType.APPLICATION_JSON))); actions.andDo(print()); - actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)) - .andExpect(content().string("/**/fnUpdateSome({\"p1\":1,\"p2\":2})")); + actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)); + String content = actions.andReturn().getResponse().getContentAsString(); + assertTrue(content.equals("/**/fnUpdateSome({\"p1\":1,\"p2\":2})") + || content.equals("/**/fnUpdateSome({\"p2\":2,\"p1\":1})")); } @Test diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case3Test.java b/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case3Test.java index ca45694f06..6b1f27301f 100644 --- a/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case3Test.java +++ b/src/test/java/com/alibaba/json/bvt/support/spring/mock/testcase/FastJsonpHttpMessageConverter4Case3Test.java @@ -26,6 +26,7 @@ import java.util.List; +import static junit.framework.TestCase.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -102,9 +103,10 @@ public void test1_2() throws Exception { ResultActions actions = mockMvc.perform((post("/fastjson/test1?callback=fnUpdateSome").characterEncoding( "UTF-8").content(json.toJSONString()).contentType(MediaType.APPLICATION_JSON))); actions.andDo(print()); - actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)) - .andExpect(content().string("/**/fnUpdateSome({\"name\":\"哈哈哈\",\"id\":123})")); - } + actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)); + String content = actions.andReturn().getResponse().getContentAsString(); + assertTrue(content.equals("/**/fnUpdateSome({\"name\":\"哈哈哈\",\"id\":123})") + || content.equals("/**/fnUpdateSome({\"id\":123,\"name\":\"哈哈哈\"})")); } @Test public void test2() throws Exception { @@ -124,9 +126,10 @@ public void test2_2() throws Exception { ResultActions actions = mockMvc.perform((post("/fastjson/test2?jsonp=fnUpdateSome").characterEncoding("UTF-8") .content(jsonStr).contentType(MediaType.APPLICATION_JSON))); actions.andDo(print()); - actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)) - .andExpect(content().string("/**/fnUpdateSome({\"p1\":1,\"p2\":2})")); - } + actions.andExpect(status().isOk()).andExpect(content().contentType(APPLICATION_JAVASCRIPT)); + String content = actions.andReturn().getResponse().getContentAsString(); + assertTrue(content.equals("/**/fnUpdateSome({\"p1\":1,\"p2\":2})") + || content.equals("/**/fnUpdateSome({\"p2\":2,\"p1\":1})")); } @Test public void test3() throws Exception { diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/security/DefaultOAuth2AccessTokenTest.java b/src/test/java/com/alibaba/json/bvt/support/spring/security/DefaultOAuth2AccessTokenTest.java new file mode 100644 index 0000000000..0468ba204f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/support/spring/security/DefaultOAuth2AccessTokenTest.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.support.spring.security; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; + +import java.util.Date; + +public class DefaultOAuth2AccessTokenTest extends TestCase { + public void test_0() throws Exception { + DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("123"); + token.setExpiration(new Date()); + String json = JSON.toJSONString(token, SerializerFeature.WriteClassName); + DefaultOAuth2AccessToken token2 = (DefaultOAuth2AccessToken) JSON.parse(json); + assertEquals(token.getValue(), token2.getValue()); + assertEquals(token.getExpiration(), token2.getExpiration()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/security/DefaultSavedRequestTest.java b/src/test/java/com/alibaba/json/bvt/support/spring/security/DefaultSavedRequestTest.java index 0e93ca177e..e3dce4915e 100644 --- a/src/test/java/com/alibaba/json/bvt/support/spring/security/DefaultSavedRequestTest.java +++ b/src/test/java/com/alibaba/json/bvt/support/spring/security/DefaultSavedRequestTest.java @@ -32,6 +32,7 @@ protected void setUp() throws Exception { Field field = GenericFastJsonRedisSerializer.class.getDeclaredField("defaultRedisConfig"); field.setAccessible(true); config = (ParserConfig) field.get(null); + config.addAccept("org.springframework.security.web.savedrequest.DefaultSavedRequest"); } public void test_for_issue() throws Exception { MockHttpServletRequest mockReq = new MockHttpServletRequest(); diff --git a/src/test/java/com/alibaba/json/bvt/taobao/ItemUpdateDOTest.java b/src/test/java/com/alibaba/json/bvt/taobao/ItemUpdateDOTest.java new file mode 100644 index 0000000000..aba49ebfd6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/taobao/ItemUpdateDOTest.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.taobao; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.TestCase; + +public class ItemUpdateDOTest extends TestCase { + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + Model item = new Model(); + JSON.toJSONString(item, config, SerializerFeature.IgnoreErrorGetter, + SerializerFeature.IgnoreNonFieldGetter, SerializerFeature.WriteClassName, + SerializerFeature.WriteMapNullValue); + + System.out.println(JSON.toJSONString("\u000B")); + } + + public static class Model { + private long f0 = 1; + private long f1; + + public long getF0() { + return f0; + } + + public void setF0(long f0) { + this.f0 = f0; + } + + public long getF1() { + return f1; + } + + public void setF1(long f1) { + this.f1 = f1; + } + + /** @deprecated */ + @Deprecated + public long getUpdateFeatureCc() { + throw new IllegalArgumentException("updateFeatureCc不再使用"); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/taobao/TradeTest.java b/src/test/java/com/alibaba/json/bvt/taobao/TradeTest.java new file mode 100644 index 0000000000..71b179ac49 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/taobao/TradeTest.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.taobao; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import junit.framework.TestCase; + +public class TradeTest extends TestCase { + public void test_cast() { + String s + = "{\"period\":{\"label\":\"最近30天\",\"value\":\"30d\"},\"data\":{\"gmv\":{\"min\":-2},\"id\":3712312925}}"; + Param param; + param = JSON.parseObject(s, Param.class); // 从字符串直接转化,OK + assertNotNull(param); + + JSONObject jobj = JSON.parseObject(s); + param = jobj.toJavaObject(Param.class); + } + + public static class Param extends BaseObject { + + private static final long serialVersionUID = 5180807854744861824L; + + public TradeParam data; + + public Pair period; + } + + public static class TradeParam extends BaseObject { + + private static final long serialVersionUID = 3201881995156974305L; + + public ID id; + + public Range gmv; + + public Range ordCnt; + + public Range cspu; + + } + + public static class Range extends BaseObject { + + private static final long serialVersionUID = 669395861117027110L; + + public T min; + public T max; + + } + + public static class BaseObject {} + + public static class Pair extends BaseObject { + + private static final long serialVersionUID = 2840564531670241284L; + + public String label; + public T value; + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest.java b/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest14.java b/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest14.java new file mode 100644 index 0000000000..33cd034e67 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest14.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.typeRef; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; +import java.util.List; +import junit.framework.TestCase; + +import java.io.Serializable; + +/** + * Created by wenshao on 09/02/2017. + */ +public class TypeReferenceTest14 extends TestCase { + public void test_0() throws Exception { + String str = "{\"result\":{\"item\":[{\"key\":\"123\"}]}}"; + + ParserConfig config = new ParserConfig(); + JSONObject.parseObject(str, OpenSearchResponse.class, config); + JSONObject.parseObject(str + , new TypeReference>() {}.getType() + , config, JSON.DEFAULT_PARSER_FEATURE); + + int size = config.getDeserializers().size(); + for (int i = 0; i < 100 * 1; ++i) { + JSONObject.parseObject(str + , new TypeReference>() {}.getType() + , config, JSON.DEFAULT_PARSER_FEATURE); + assertEquals(size, config.getDeserializers().size()); + } + } + + public static class OpenSearchResponse { + + private OpenSearchResult result; + + public OpenSearchResult getResult() { + return result; + } + + public void setResult(OpenSearchResult result) { + this.result = result; + } + + + } + + public static class OpenSearchResult { + private List item; + + public List getItem() { + return item; + } + + public void setItem(List item) { + this.item = item; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest2.java b/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest3.java b/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest4.java b/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest4.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest5.java b/src/test/java/com/alibaba/json/bvt/typeRef/TypeReferenceTest5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/util/AntiCollisionHashMapTest.java b/src/test/java/com/alibaba/json/bvt/util/AntiCollisionHashMapTest.java new file mode 100644 index 0000000000..c86e5ea011 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/AntiCollisionHashMapTest.java @@ -0,0 +1,122 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.util.AntiCollisionHashMap; +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Iterator; +import java.util.Map; + +public class AntiCollisionHashMapTest extends TestCase { + public void test_0() throws Exception { + AntiCollisionHashMap m = new AntiCollisionHashMap(3, 0.75f); + + for (int i = 0; i < 100; ++i) { + m.put(i, i); + } + + AntiCollisionHashMap m2 = new AntiCollisionHashMap(m); + assertEquals(m.size(), m2.size()); + + AntiCollisionHashMap m3 = new AntiCollisionHashMap(3, 0.75f); + m3.putAll(m); + assertEquals(m.size(), m2.size()); + + AntiCollisionHashMap m4 = (AntiCollisionHashMap) m.clone(); + m4.hashCode(); + m4.size(); + m4.isEmpty(); + m4.values().iterator(); + m4.keySet().iterator(); + m4.values().contains(1); + m4.values().contains(null); + m4.values().iterator().next(); + m4.values().remove(1); + m4.values().size(); + m4.values().clear(); + + AntiCollisionHashMap m5 = (AntiCollisionHashMap) m.clone(); + m5.keySet().contains(1); + m5.put(1, 1001); + m5.get(null); + Map.Entry entry = (Map.Entry) m5.entrySet().iterator().next(); + entry.setValue(1002); + entry.toString(); + m5.keySet().size(); + m5.keySet().iterator().next(); + m5.keySet().remove(1); + m5.keySet().clear(); + + AntiCollisionHashMap m6 = new AntiCollisionHashMap(3); + m6.putAll(m); + assertEquals(m.size(), m6.size()); + m6.put("a", "a"); + m6.put("b", "b"); + + for (int i = 0; i < 100; ++i) { + assertEquals(i, m.get(i)); + assertTrue(m.containsKey(i)); + } + + for (int i = 0; i < 100; ++i) { + m3.remove(i); + m2.remove(i, i); + } + m2.put(null, null); + m2.put(1, 1); + assertTrue(m2.containsKey(null)); + assertTrue(m2.containsKey(1)); + assertTrue(m2.containsValue(null)); + assertTrue(m2.containsValue(1)); + Iterator iterator = m2.entrySet().iterator(); + while (iterator.hasNext()) { + iterator.next(); + iterator.remove(); + } + m2.clear(); + + assertFalse(m.entrySet().contains(1)); + assertTrue(m.entrySet().contains(m.entrySet().iterator().next())); + m.entrySet().size(); + m.entrySet().remove(1); + m.entrySet().remove(m.entrySet().iterator().next()); + m.entrySet().clear(); + + { + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(m); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(AntiCollisionHashMap.class, obj.getClass()); + assertEquals(m, obj); + } + { + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(bytesOut); + objOut.writeObject(m6); + objOut.flush(); + + byte[] bytes = bytesOut.toByteArray(); + + ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes); + ObjectInputStream objIn = new ObjectInputStream(bytesIn); + + Object obj = objIn.readObject(); + + assertEquals(AntiCollisionHashMap.class, obj.getClass()); + assertEquals(m6, obj); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/AntiCollisionHashMapTest_writeClassName.java b/src/test/java/com/alibaba/json/bvt/util/AntiCollisionHashMapTest_writeClassName.java new file mode 100644 index 0000000000..c7d306db72 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/AntiCollisionHashMapTest_writeClassName.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.util.AntiCollisionHashMap; +import junit.framework.TestCase; + +import java.util.Map; + +public class AntiCollisionHashMapTest_writeClassName extends TestCase { + public void test_for_bug() throws Exception { + Model m = JSON.parseObject("{\"value\":{\"@type\":\"com.alibaba.fastjson.util.AntiCollisionHashMap\"}}", Model.class); + assertTrue(m.value.getInnerMap() instanceof AntiCollisionHashMap); + } + + public static class Model { + public JSONObject value; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/Base64Test.java b/src/test/java/com/alibaba/json/bvt/util/Base64Test.java new file mode 100644 index 0000000000..073235dfb0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/Base64Test.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.util.Base64; +import junit.framework.TestCase; + +public class Base64Test extends TestCase { + public void test_base64() throws Exception { + String str = "阿里巴巴網絡有限公司主要通過旗下三個交易市場協助世界各地數以百萬計的買家和供應商從事網上生意,包括:集中服務全球進出口商的國際交易市場(www.alibaba.com);集中國內貿易的中國交易市場(www.1688.com);以及在國際交易市場上的全球批發交易平台(www.aliexpress.com),為規模較小、需要小批量貨物快速付運的買家提供服務。更多>>"; + + byte[] bytes = str.getBytes("UTF8"); + String base64Str = com.alibaba.json.test.Base64.encodeToString(bytes, false); + + { + byte[] bytes2 = Base64.decodeFast(base64Str); + assertEquals(str, new String(bytes2, "UTF8")); + } + + { + byte[] bytes2 = Base64.decodeFast(base64Str, 0, base64Str.length()); + assertEquals(str, new String(bytes2, "UTF8")); + } + + { + byte[] bytes2 = Base64.decodeFast(base64Str.toCharArray(), 0, base64Str.length()); + assertEquals(str, new String(bytes2, "UTF8")); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/FieldInfoTest.java b/src/test/java/com/alibaba/json/bvt/util/FieldInfoTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/util/IOUtilsTest.java b/src/test/java/com/alibaba/json/bvt/util/IOUtilsTest.java new file mode 100644 index 0000000000..1448905e37 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/IOUtilsTest.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.util.IOUtils; +import junit.framework.TestCase; + +import java.io.StringReader; + +public class IOUtilsTest extends TestCase { + public void test_readAll() throws Exception { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < 1024 * 64; ++i) { + buf.append("a"); + } + + StringReader reader = new StringReader(buf.toString()); + IOUtils.readAll(reader); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/JSONASMUtilTest.java b/src/test/java/com/alibaba/json/bvt/util/JSONASMUtilTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/util/JavaBeanInfoTest.java b/src/test/java/com/alibaba/json/bvt/util/JavaBeanInfoTest.java new file mode 100644 index 0000000000..0ecada1bcb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/JavaBeanInfoTest.java @@ -0,0 +1,10 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.util.JavaBeanInfo; +import junit.framework.TestCase; + +public class JavaBeanInfoTest extends TestCase { + public void test_0() throws Exception { + JavaBeanInfo.getBuilderClass(null); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/RyuDoubleTest.java b/src/test/java/com/alibaba/json/bvt/util/RyuDoubleTest.java new file mode 100644 index 0000000000..2bf52aa1b3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/RyuDoubleTest.java @@ -0,0 +1,460 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.util.RyuDouble; +import junit.framework.TestCase; + +import java.util.Random; + +public class RyuDoubleTest extends TestCase { + public void test_for_ryu() throws Exception { + Random random = new Random(); + + for (int i = 0; i < 1000 * 1000 * 10; ++i) { + double value = random.nextDouble(); + + String str1 = Double.toString(value); + String str2 = RyuDouble.toString(value); + + if (!str1.equals(str2)) { + System.out.println(str1 + " -> " + str2); + assertTrue(Double.parseDouble(str1) == Double.parseDouble(str2)); + } + } + } + + public void test_0() throws Exception { + double[] values = new double[] { + Double.NaN, + Double.NEGATIVE_INFINITY, + Double.POSITIVE_INFINITY, + Double.MIN_VALUE, + Double.MAX_VALUE, + + 0, + 0.0d, + -0.0d, + Double.longBitsToDouble(0x8000000000000000L), + Double.NaN, + + Long.MAX_VALUE, + Long.MIN_VALUE, + Integer.MAX_VALUE, + Integer.MIN_VALUE, + Double.longBitsToDouble(0x0010000000000000L), + + 9999999.999999998d, + 0.0009999999999999998d, + 1.0E7d, + 0.001d, + Double.longBitsToDouble(0x7fefffffffffffffL), + + Double.longBitsToDouble(1), + -2.109808898695963E16, + 4.940656E-318d, + 1.18575755E-316d, + 2.989102097996E-312d, + 9.0608011534336E15d, + 4.708356024711512E18, + 9.409340012568248E18, + 1.8531501765868567E21, + -3.347727380279489E33, + 1.9430376160308388E16, + -6.9741824662760956E19, + 4.3816050601147837E18, + + 1.797693134862315E308, + 1.79769313486231E308, + 1.7976931348623E308, + 1.797693134862E308, + 1.79769313486E308, + 1.7976931348E308, + 1.797693134E308, + 1.79769313E308, + 1.7976931E308, + 1.797693E308, + 1.79769E308, + 1.7976E308, + 1.797E308, + 1.79E308, + 1.7E308, + 1E308, + + 1.797693134862315, + 1.79769313486231, + 1.7976931348623, + 1.797693134862, + 1.79769313486, + 1.7976931348, + 1.797693134, + 1.79769313, + 1.7976931, + 1.797693, + 1.79769, + 1.7976, + 1.797, + 1.79, + 1.7, + 1, + + -1.797693134862315, + -1.79769313486231, + -1.7976931348623, + -1.797693134862, + -1.79769313486, + -1.7976931348, + -1.797693134, + -1.79769313, + -1.7976931, + -1.797693, + -1.79769, + -1.7976, + -1.797, + -1.79, + -1.7, + -1, + + 0.1, + 0.01, + 0.001, + 0.0001, + 0.00001, + 0.000001, + 0.0000001, + 0.00000001, + 0.000000001, + 0.0000000001, + 0.00000000001, + 0.000000000001, + 0.0000000000001, + 0.00000000000001, + + -0.1, + -0.01, + -0.001, + -0.0001, + -0.00001, + -0.000001, + -0.0000001, + -0.00000001, + -0.000000001, + -0.0000000001, + -0.00000000001, + -0.000000000001, + -0.0000000000001, + -0.00000000000001, + + 1.1E1, + 1.1E2, + 1.1E3, + 1.1E4, + 1.1E5, + 1.1E6, + 1.1E7, + 1.1E8, + 1.1E9, + 1.1E10, + + -1.1E1, + -1.1E2, + -1.1E3, + -1.1E4, + -1.1E5, + -1.1E6, + -1.1E7, + -1.1E8, + -1.1E9, + -1.1E10, + + 49E10, + 49E100, + 49E200, + 49E300, + 49E301, + 49E302, + 49E303, + 49E304, + + 49E-10, + 49E-100, + 49E-200, + 49E-300, + 49E-301, + 49E-302, + 49E-303, + 49E-304, + + }; + + for (int i = 0; i < values.length; i++) { + double value = values[i]; + String str1 = Double.toString(value); + String str2 = RyuDouble.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Double.parseDouble(str1) == Double.parseDouble(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); + } + } + } + + public void test_1() throws Exception { + double[] values = new double[]{ + 0.1, + 0.01, + 0.001, + 0.0001, + 0.00001, + 0.000001, + 0.0000001, + 0.00000001, + 0.000000001, + 0.0000000001, + 0.00000000001, + 0.000000000001, + 0.0000000000001, + 0.00000000000001, + 0.000000000000001, + 0.0000000000000001, + 0.00000000000000001, + 0.000000000000000001, + 0.0000000000000000001, + 0.00000000000000000001, + 0.000000000000000000001, + 0.0000000000000000000001, + 0.00000000000000000000001, + 0.000000000000000000000001, + 0.0000000000000000000000001, + 0.00000000000000000000000001, + 0.000000000000000000000000001, + 0.0000000000000000000000000001, + 0.00000000000000000000000000001, + 0.000000000000000000000000000001, + 0.0000000000000000000000000000001, + 0.00000000000000000000000000000001, + 0.000000000000000000000000000000001, + 0.0000000000000000000000000000000001, + 0.00000000000000000000000000000000001, + 0.000000000000000000000000000000000001, + 0.0000000000000000000000000000000000001, + 0.00000000000000000000000000000000000001, + 0.000000000000000000000000000000000000001, + 0.0000000000000000000000000000000000000001, + 0.00000000000000000000000000000000000000001, + 0.000000000000000000000000000000000000000001, + 0.0000000000000000000000000000000000000000001, + 0.00000000000000000000000000000000000000000001, + 0.000000000000000000000000000000000000000000001, + 0.0000000000000000000000000000000000000000000001, + 0.00000000000000000000000000000000000000000000001, + 0.000000000000000000000000000000000000000000000001, + 0.0000000000000000000000000000000000000000000000001, + 0.00000000000000000000000000000000000000000000000001, + 0.000000000000000000000000000000000000000000000000001, + 0.0000000000000000000000000000000000000000000000000001, + 0.00000000000000000000000000000000000000000000000000001, + 0.000000000000000000000000000000000000000000000000000001, + 0.0000000000000000000000000000000000000000000000000000001, + 0.00000000000000000000000000000000000000000000000000000001, + 0.000000000000000000000000000000000000000000000000000000001, + 0.000000000000000000000000000000000000000000000000000000001, + + -0.1, + -0.01, + -0.001, + -0.0001, + -0.00001, + -0.000001, + -0.0000001, + -0.00000001, + -0.000000001, + -0.0000000001, + -0.00000000001, + -0.000000000001, + -0.0000000000001, + -0.00000000000001, + -0.000000000000001, + -0.0000000000000001, + -0.00000000000000001, + -0.000000000000000001, + -0.0000000000000000001, + -0.00000000000000000001, + -0.000000000000000000001, + -0.0000000000000000000001, + -0.00000000000000000000001, + -0.000000000000000000000001, + -0.0000000000000000000000001, + -0.00000000000000000000000001, + -0.000000000000000000000000001, + -0.0000000000000000000000000001, + -0.00000000000000000000000000001, + -0.000000000000000000000000000001, + -0.0000000000000000000000000000001, + -0.00000000000000000000000000000001, + -0.000000000000000000000000000000001, + -0.0000000000000000000000000000000001, + -0.00000000000000000000000000000000001, + -0.000000000000000000000000000000000001, + -0.0000000000000000000000000000000000001, + -0.00000000000000000000000000000000000001, + -0.000000000000000000000000000000000000001, + -0.0000000000000000000000000000000000000001, + -0.00000000000000000000000000000000000000001, + -0.000000000000000000000000000000000000000001, + -0.0000000000000000000000000000000000000000001, + -0.00000000000000000000000000000000000000000001, + -0.000000000000000000000000000000000000000000001, + -0.0000000000000000000000000000000000000000000001, + -0.00000000000000000000000000000000000000000000001, + -0.000000000000000000000000000000000000000000000001, + -0.0000000000000000000000000000000000000000000000001, + -0.00000000000000000000000000000000000000000000000001, + -0.000000000000000000000000000000000000000000000000001, + -0.0000000000000000000000000000000000000000000000000001, + -0.00000000000000000000000000000000000000000000000000001, + -0.000000000000000000000000000000000000000000000000000001, + -0.0000000000000000000000000000000000000000000000000000001, + -0.00000000000000000000000000000000000000000000000000000001, + -0.000000000000000000000000000000000000000000000000000000001, + -0.000000000000000000000000000000000000000000000000000000001, + }; + + for (int i = 0; i < values.length; i++) { + double value = values[i]; + String str1 = Double.toString(value); + String str2 = RyuDouble.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Double.parseDouble(str1) == Double.parseDouble(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); + } + } + } + + public void test_2() throws Exception { + double[] values = new double[]{ + 9.223372036854799E18, + 9.223372036854798E18, + 9.223372036854797E18, + 9.223372036854796E18, + 9.223372036854795E18, + 9.223372036854794E18, + 9.223372036854793E18, + 9.223372036854792E18, + 9.223372036854791E18, + 9.223372036854790E18, + + 9.223372036854789E18, + 9.223372036854788E18, + 9.223372036854787E18, + 9.223372036854786E18, + 9.223372036854785E18, + 9.223372036854784E18, + 9.223372036854783E18, + 9.223372036854782E18, + 9.223372036854781E18, + 9.223372036854780E18, + + 9.223372036854779E18, + 9.223372036854778E18, + 9.223372036854777E18, + 9.223372036854776E18, + 9.223372036854775E18, + 9.223372036854774E18, + 9.223372036854773E18, + 9.223372036854772E18, + 9.223372036854771E18, + 9.223372036854770E18, + + 9.223372036854769E18, + 9.223372036854768E18, + 9.223372036854767E18, + 9.223372036854766E18, + 9.223372036854765E18, + 9.223372036854764E18, + 9.223372036854763E18, + 9.223372036854762E18, + 9.223372036854761E18, + 9.223372036854760E18, + + 9.223372036854759E18, + 9.223372036854758E18, + 9.223372036854757E18, + 9.223372036854756E18, + 9.223372036854755E18, + 9.223372036854754E18, + 9.223372036854753E18, + 9.223372036854752E18, + 9.223372036854751E18, + 9.223372036854750E18, + + 9.223372036854749E18, + 9.223372036854748E18, + 9.223372036854747E18, + 9.223372036854746E18, + 9.223372036854745E18, + 9.223372036854744E18, + 9.223372036854743E18, + 9.223372036854742E18, + 9.223372036854741E18, + 9.223372036854740E18, + + 9.223372036854739E18, + 9.223372036854738E18, + 9.223372036854737E18, + 9.223372036854736E18, + 9.223372036854735E18, + 9.223372036854734E18, + 9.223372036854733E18, + 9.223372036854732E18, + 9.223372036854731E18, + 9.223372036854730E18, + + 9.223372036854729E18, + 9.223372036854728E18, + 9.223372036854727E18, + 9.223372036854726E18, + 9.223372036854725E18, + 9.223372036854724E18, + 9.223372036854723E18, + 9.223372036854722E18, + 9.223372036854721E18, + 9.223372036854720E18, + + 9.223372036854719E18, + 9.223372036854718E18, + 9.223372036854717E18, + 9.223372036854716E18, + 9.223372036854715E18, + 9.223372036854714E18, + 9.223372036854713E18, + 9.223372036854712E18, + 9.223372036854711E18, + 9.223372036854710E18, + + 9.223372036854709E18, + 9.223372036854708E18, + 9.223372036854707E18, + 9.223372036854706E18, + 9.223372036854705E18, + 9.223372036854704E18, + 9.223372036854703E18, + 9.223372036854702E18, + 9.223372036854701E18, + 9.223372036854700E18, + }; + + for (int i = 0; i < values.length; i++) { + double value = values[i]; + String str1 = Double.toString(value); + String str2 = RyuDouble.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Double.parseDouble(str1) == Double.parseDouble(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/RyuFloatTest.java b/src/test/java/com/alibaba/json/bvt/util/RyuFloatTest.java new file mode 100644 index 0000000000..c013f81a18 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/RyuFloatTest.java @@ -0,0 +1,116 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.util.RyuFloat; +import junit.framework.TestCase; + +import java.util.Random; + +public class RyuFloatTest extends TestCase { + public void test_for_ryu() throws Exception { + Random random = new Random(); + + for (int i = 0; i < 1000 * 1000 * 10; ++i) { + float value = random.nextFloat(); + + String str1 = Float.toString(value); + String str2 = RyuFloat.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Float.parseFloat(str1) == Float.parseFloat(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); +// assertTrue(Float.parseFloat(str1) == Float.parseFloat(str2)); + } + } + } + + public void test_0() throws Exception { + float[] values = new float[] { + Float.NaN, + Float.NEGATIVE_INFINITY, + Float.POSITIVE_INFINITY, + Float.MIN_VALUE, + Float.MAX_VALUE, + 0, + 0.0f, + -0.0f, + Integer.MAX_VALUE, + Integer.MIN_VALUE, + Long.MAX_VALUE, + Long.MIN_VALUE, + Float.intBitsToFloat(0x80000000), + 1.0f, + -1f, + Float.intBitsToFloat(0x00800000), + 1.0E7f, + 9999999.0f, + 0.001f, + 0.0009999999f, + Float.intBitsToFloat(0x7f7fffff), + Float.intBitsToFloat(0x00000001), + 3.3554448E7f, + 8.999999E9f, + 3.4366717E10f, + 0.33007812f, + Float.intBitsToFloat(0x5D1502F9), + Float.intBitsToFloat(0x5D9502F9), + Float.intBitsToFloat(0x5E1502F9), + 4.7223665E21f, + 8388608.0f, + 1.6777216E7f, + 3.3554436E7f, + 6.7131496E7f, + 1.9310392E-38f, + -2.47E-43f, + 1.993244E-38f, + 4103.9003f, + 5.3399997E9f, + 6.0898E-39f, + 0.0010310042f, + 2.8823261E17f, + 7.038531E-26f, + 9.2234038E17f, + 6.7108872E7f, + 1.0E-44f, + 2.816025E14f, + 9.223372E18f, + 1.5846085E29f, + 1.1811161E19f, + 5.368709E18f, + 4.6143165E18f, + 0.007812537f, + 1.4E-45f, + 1.18697724E20f, + 1.00014165E-36f, + 200f, + 3.3554432E7f, + + 0.1f, + 0.01f, + 0.001f, + 0.0001f, + 0.00001f, + 0.000001f, + 0.0000001f, + + 1.1f, + 1.01f, + 1.001f, + 1.0001f, + 1.00001f, + 1.000001f, + 1.0000001f, + }; + + for (float value : values) { + String str1 = Float.toString(value); + String str2 = RyuFloat.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Float.parseFloat(str1) == Float.parseFloat(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/ThreadLocalCacheTest.java b/src/test/java/com/alibaba/json/bvt/util/ThreadLocalCacheTest.java old mode 100755 new mode 100644 index 085931d065..bd0259ffdd --- a/src/test/java/com/alibaba/json/bvt/util/ThreadLocalCacheTest.java +++ b/src/test/java/com/alibaba/json/bvt/util/ThreadLocalCacheTest.java @@ -3,6 +3,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; +import com.alibaba.fastjson.util.ThreadLocalCache; import org.junit.Assert; import com.alibaba.fastjson.JSON; @@ -90,4 +91,34 @@ public static void clearBytes() throws Exception { ThreadLocal bytesBufLocal = (ThreadLocal) field.get(null); bytesBufLocal.set(null); } + + public void test_chars() throws Exception { + ThreadLocalCache.getChars(10); + ThreadLocalCache.getChars(10); + ThreadLocalCache.getChars(20); + ThreadLocalCache.getChars(30); + clearChars(); + ThreadLocalCache.getChars(10); + ThreadLocalCache.getChars(10); + ThreadLocalCache.getChars(20); + ThreadLocalCache.getChars(30); + + ThreadLocalCache.clearChars(); + ThreadLocalCache.getUTF8Decoder(); + ThreadLocalCache.getUTF8Decoder(); + } + + public void test_bytes() throws Exception { + ThreadLocalCache.getBytes(10); + ThreadLocalCache.getBytes(10); + ThreadLocalCache.getBytes(20); + ThreadLocalCache.getBytes(30); + clearBytes(); + ThreadLocalCache.getBytes(10); + ThreadLocalCache.getBytes(10); + ThreadLocalCache.getBytes(20); + ThreadLocalCache.getBytes(30); + + } + } diff --git a/src/test/java/com/alibaba/json/bvt/util/TypeUtilsTest.java b/src/test/java/com/alibaba/json/bvt/util/TypeUtilsTest.java new file mode 100644 index 0000000000..5f8c668a5f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/TypeUtilsTest.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.util.TypeUtils; +import com.alibaba.json.bvt.parser.deser.generic.GenericArrayTest; +import com.jsoniter.spi.GenericArrayTypeImpl; +import junit.framework.TestCase; + +import java.lang.reflect.Constructor; +import java.lang.reflect.GenericArrayType; + +public class TypeUtilsTest extends TestCase { + public void test_0() throws Exception { + assertEquals(0, TypeUtils.getSerializeFeatures(Object.class)); + assertEquals(SerializerFeature.WriteMapNullValue.mask, TypeUtils.getSerializeFeatures(Model.class)); + } + + public void test_1() throws Exception { + TypeUtils.checkPrimitiveArray((GenericArrayType) A.class.getField("values").getGenericType()); + } + + public void test_3() throws Exception { + assertTrue(TypeUtils.isHibernateInitialized(new Object())); + } + + public void test_2() throws Exception { + Constructor constructor = GenericArrayTypeImpl.class.getDeclaredConstructors()[0]; + constructor.setAccessible(true); + + Class[] classes = new Class[] { + boolean[].class, + byte[].class, + short[].class, + int[].class, + long[].class, + float[].class, + double[].class, + char[].class, + }; + + for (Class clazz : classes) { + GenericArrayType type = (GenericArrayType) constructor.newInstance(clazz.getComponentType()); + assertEquals(clazz, TypeUtils.checkPrimitiveArray(type)); + } + + } + + @JSONType(serialzeFeatures = SerializerFeature.WriteMapNullValue) + public static class Model { + + } + + public static class A { + public T[] values; + } + + public static class VO extends GenericArrayTest.A { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/UTF8DecoderTest.java b/src/test/java/com/alibaba/json/bvt/util/UTF8DecoderTest.java new file mode 100644 index 0000000000..1cbec232bc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/UTF8DecoderTest.java @@ -0,0 +1,165 @@ +package com.alibaba.json.bvt.util; + +import com.alibaba.fastjson.util.ThreadLocalCache; +import com.alibaba.fastjson.util.UTF8Decoder; +import junit.framework.TestCase; + +import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; + +public class UTF8DecoderTest extends TestCase { + public void test_0() throws Exception { + CharsetDecoder decoder = ThreadLocalCache.getUTF8Decoder(); + + String str = "asdfl中华人民共和国据《今日俄罗斯》17日消息,穆希卡总统自2015年卸任总统一职后一直在参议院就职。14日,穆希卡宣布辞职,理由是“长途跋涉后感到疲惫了”。按照规定,他作为参议员的任期将到2020年。"; + + { + byte[] bytes = str.getBytes("UTF-8"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } + + try { + byte[] bytes = str.getBytes("GB18030"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } catch (CharacterCodingException ex) { + + } + } + + public void test_1() throws Exception { + int len = (Character.MAX_VALUE - Character.MIN_VALUE) + 1; + char[] chars = new char[len]; + for (int i = 0; i < len; ++i) { + char ch = (char) ((int) Character.MAX_VALUE + i); + if (ch >= 55296 && ch <= 57344) { + continue; + } + chars[i] = ch; + } + + String str = new String(chars); + + CharsetDecoder decoder = ThreadLocalCache.getUTF8Decoder(); + + { + byte[] bytes = str.getBytes("UTF-8"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } + try { + byte[] bytes = str.getBytes("GB18030"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } catch (CharacterCodingException ex) { + + } + } + + public void test_2() throws Exception { + CharsetDecoder decoder = ThreadLocalCache.getUTF8Decoder(); + + String str = "嫉妬心を止められない\n" + + "服装はいつも地味なAですが、よく見るとアクセサリーやバッグがブランド品。そこで、その人の夫の職業を聞くと…。"; + + { + byte[] bytes = str.getBytes("UTF-8"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } + try { + byte[] bytes = str.getBytes("GB18030"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } catch (CharacterCodingException ex) { + + } + } + + public void test_3() throws Exception { + CharsetDecoder decoder = ThreadLocalCache.getUTF8Decoder(); + + String str = "面的藏文有一个音节“བསྒྲོནད”(威利转写:bsgrond),由前加字ba、上加字sa,基字ga,下加字ra,元音o、第一后加字na、第二后加字da构成。bsgrond是7世纪的藏语语音,随着现在拉萨音里复辅音以及部分韵尾的消失和声调的出现,该词已转变读成/ʈʂø̃˩˨/(藏语拼音:zhön,藏文拉萨音拼音:zhoenv)。\n" + + "\n" + + "前加字只能是 ག /g/、 ད /d/、 བ /b/、 མ /m/、 འ /ɦ/。\n" + + "上加字只能是 ཪ /r/、 ལ /l/、 ས /s/。\n" + + "下加字只能是 ◌ྲ /r/、 ◌ྱ /j/、 ◌ྭ /w/、 ◌ླ /l/ 和用于音译梵文里送气浊辅音的送气符号 ◌ྷ,有一个复辅音 གྲྭ /grwa/ 有两个下加字 ◌ྲ /r/ 和 ◌ྭ /w/。\n" + + "第一后加字只可能是 ཪ /r/、 ག /g/、 བ /b/、 མ /m/、 འ /ɦ/、 ང /ŋ/、 ས /s/、 ད /d/、 ན /n/、 ལ /l/。\n" + + "第二后加字只可能是 ས /s/ 和 ད /d/,在现代藏语里不再发音,ད /d/ 在现代藏语中已经不用。\n" + + "另外,以下是藏文带头字(དབུ་ཅན་)和无头字(དབུ་མེད་)两种字体和国际拉丁文转写的列表:"; + + { + byte[] bytes = str.getBytes("UTF-8"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } + try { + byte[] bytes = str.getBytes("GB18030"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } catch (CharacterCodingException ex) { + + } + } + + public void test_4() throws Exception { + CharsetDecoder decoder = ThreadLocalCache.getUTF8Decoder(); + + String str = "\uD83E\uDD17 on Instagram\n" + + "\uD83E\uDD17 on Twitter\n" + + "\uD83E\uDD17 on Wikipedia\n" + + "\uD83E\uDD17 on Yelp\n" + + "\uD83E\uDD17 on YouTube\n" + + "\uD83E\uDD17 on Google Trends\n" + + "See also\n" + + "\uD83C\uDFE5 Hospital\n" + + "\uD83D\uDC50 Open Hands\n" + + "\uD83E\uDD68 Pretzel\n" + + "\uD83D\uDE42 Slightly Smiling Face\n" + + "\uD83E\uDD27 Sneezing Face\n" + + "\uD83E\uDD14 Thinking Face\n" + + "\uD83D\uDC95 Two Hearts\n" + + "☺ Smiling Face\n" + + "\uD83D\uDD00 Random emoji"; + + { + byte[] bytes = str.getBytes("UTF-8"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } + try { + byte[] bytes = str.getBytes("GB18030"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } catch (CharacterCodingException ex) { + + } + } + + /** + * @deprecated + */ + public void test_5() throws Exception { + UTF8Decoder decoder = new UTF8Decoder(); + + String str = "⌛︎€\uD83D\uDC69\uD83D\uDC68\uD83D\uDC68\uD83C\uDFFB\uD83D\uDC69\uD83C\uDFFFU+1F9D2: Child\tText\t\uD83E\uDDD2\t\uD83E\uDDD2\uD83C\uDFFB\t\uD83E\uDDD2\uD83C\uDFFC\t\uD83E\uDDD2\uD83C\uDFFD\t\uD83E\uDDD2\uD83C\uDFFE\t\uD83E\uDDD2\uD83C\uDFFF\n\uD83E\uDDD1\uD83C\uDFFF\uD83C\uDE1A️\uD83C\uDC04️❤️"; + byte[] bytes =str.getBytes("UTF-8"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } + + /** + * @deprecated + */ + public void test_6() throws Exception { + UTF8Decoder decoder = new UTF8Decoder(); + + String str = "\u20AC"; + byte[] bytes =str.getBytes("UTF-8"); + ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + decoder.decode(byteBuffer); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/validate/JSONValidatorTest.java b/src/test/java/com/alibaba/json/bvt/validate/JSONValidatorTest.java new file mode 100644 index 0000000000..c1b7238a7b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/validate/JSONValidatorTest.java @@ -0,0 +1,114 @@ +package com.alibaba.json.bvt.validate; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONValidator; +import com.alibaba.json.test.benchmark.decode.EishayDecodeBytes; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.StringReader; + +import static org.junit.Assert.*; + +public class JSONValidatorTest { + + @Test + public void validate_test_accurate() throws Throwable { + boolean isValidate = JSONValidator.from("{\"string\":\"a\",\"nums\":[0,-1,10,0.123,1e5,-1e+6,0.1e-7],\"object\":{\"empty\":{},\"list\":[]},\"list\":[\"object\",{\"true\":true,\"false\":false,\"null\":null}]}").validate(); + assertTrue(isValidate); + } + + @Test + public void validate_test_quotation() throws Throwable { + boolean isValidate = JSONValidator.from("{noQuotationMarksError}").validate(); + assertFalse(isValidate); + } + + @Test + public void validate_test_colon() throws Throwable { + boolean isValidate = JSONValidator.from("{\"colonError\"}").validate(); + assertFalse(isValidate); + + } + + @Test + public void validate_test_bracket() throws Throwable { + boolean isValidate = JSONValidator.from("[1}").validate(); + assertFalse(isValidate); + } + + @Test + public void validate_test_num1() throws Throwable { + boolean isValidate = JSONValidator.from("-a").validate(); + assertFalse(isValidate); + } + + @Test + public void validate_test_num2() throws Throwable { + boolean isValidate = JSONValidator.from("1.a1").validate(); + assertFalse(isValidate); + } + + @Test + public void validate_test_num3() throws Throwable { + boolean isValidate = JSONValidator.from("1.e1").validate(); + assertFalse(isValidate); + } + + @Test + public void validate_test_num4() throws Throwable { + assertTrue( + JSONValidator.from("+1") + .validate()); + + assertFalse( + JSONValidator.from("++1") + .validate()); + } + + @Test + public void validate_test_num5() throws Throwable { + boolean isValidate = JSONValidator.from("1ea").validate(); + assertFalse(isValidate); + } + + @Test + public void validate_test_tfn() throws Throwable { + boolean isValidate = JSONValidator.from("trua").validate(); + assertFalse(isValidate); + } + + @Test + public void test_validate_utf8() throws Exception { + byte[] json = JSON.toJSONBytes(EishayDecodeBytes.instance.getContent()); + + JSONValidator validator = JSONValidator.fromUtf8(json); + assertTrue(validator.validate()); + } + + @Test + public void test_validate_utf8_stream() throws Exception { + byte[] json = JSON.toJSONBytes(EishayDecodeBytes.instance.getContent()); + + JSONValidator validator = JSONValidator.fromUtf8(new ByteArrayInputStream(json)); + assertTrue(validator.validate()); + validator.close(); + } + + @Test + public void test_validate() throws Exception { + String json = JSON.toJSONString(EishayDecodeBytes.instance.getContent()); + JSONValidator validator = JSONValidator.from(json); + assertTrue(validator.validate()); + } + + @Test + public void test_validate_reader() throws Exception { + JSONValidator validator = JSONValidator.from( + new StringReader( + new String( + JSON.toJSONBytes(EishayDecodeBytes.instance.getContent())))); + assertTrue(validator.validate()); + validator.close(); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/MapTest.java b/src/test/java/com/alibaba/json/bvt/writeClassName/MapTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/StrictAutoTypeTest_0.java b/src/test/java/com/alibaba/json/bvt/writeClassName/StrictAutoTypeTest_0.java index bce79e86b9..f85980dba4 100644 --- a/src/test/java/com/alibaba/json/bvt/writeClassName/StrictAutoTypeTest_0.java +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/StrictAutoTypeTest_0.java @@ -3,33 +3,26 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; import junit.framework.TestCase; public class StrictAutoTypeTest_0 extends TestCase { - private int features; - - protected void setUp() throws Exception { - this.features = JSON.DEFAULT_PARSER_FEATURE; - } - - protected void tearDown() throws Exception { - JSON.DEFAULT_PARSER_FEATURE = features; - } + private ParserConfig config = new ParserConfig(); public void test_0() throws Exception { - JSON.parseObject("{\"@type\":\"com.alibaba.fastjson.JSONObject\"}", Object.class); - JSON.parseObject("{\"@type\":\"com.alibaba.fastjson.JSONObject\"}", Object.class, Feature.SupportAutoType); + JSON.parseObject("{\"@type\":\"com.alibaba.fastjson.JSONObject\"}", Object.class, config); + JSON.parseObject("{\"@type\":\"com.alibaba.fastjson.JSONObject\"}", Object.class, config, Feature.SupportAutoType); } public void test_1() throws Exception { - JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$VO\"}", Object.class, Feature.SupportAutoType); + JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$VO\"}", Object.class, config, Feature.SupportAutoType); } public void test_2() throws Exception { { Exception error = null; try { - JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$V1\"}", Object.class); + JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$V1\"}", Object.class, config); } catch (JSONException ex) { error = ex; } @@ -38,7 +31,7 @@ public void test_2() throws Exception { { Exception error = null; try { - JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$V1\"}", Object.class); + JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$V1\"}", Object.class, config); } catch (JSONException ex) { error = ex; } @@ -47,13 +40,8 @@ public void test_2() throws Exception { } public void test_3() throws Exception { - try { - JSON.DEFAULT_PARSER_FEATURE |= Feature.SupportAutoType.mask; - JSON.parseObject("{\"val\":{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$V3\"}}"); - } catch (JSONException ex) { - } finally { - JSON.DEFAULT_PARSER_FEATURE &= ~Feature.SupportAutoType.mask; - } + int features = JSON.DEFAULT_PARSER_FEATURE | Feature.SupportAutoType.mask; + JSON.parse("{\"val\":{\"@type\":\"com.alibaba.json.bvt.writeClassName.StrictAutoTypeTest_0$V3\"}}", config, features); } public static class VO { diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest3.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List3.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Map.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Map.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set.java old mode 100755 new mode 100644 index 32b9c42416..11838955e4 --- a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set.java +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set.java @@ -24,7 +24,7 @@ public void test_list() throws Exception { a.setList(set); String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); System.out.println(text); - Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set$A\",\"list\":[{},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set$B1\"}]}", + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set$A\",\"list\":Set[{},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set$B1\"}]}", text); A a1 = (A) JSON.parse(text); diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set3.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set4.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set4.java old mode 100755 new mode 100644 index 9f66809a88..5cf0b56945 --- a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set4.java +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set4.java @@ -24,7 +24,7 @@ public void test_list() throws Exception { a.setList(set); String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); System.out.println(text); - Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set4$A\",\"list\":[{\"valueB\":100},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set4$B1\",\"valueB\":100,\"valueB1\":200}]}", + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set4$A\",\"list\":Set[{\"valueB\":100},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set4$B1\",\"valueB\":100,\"valueB1\":200}]}", text); A a1 = (A) JSON.parse(text); diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set5.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set5.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteDuplicateType.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteDuplicateType.java index 12c04a4589..052529f9d7 100644 --- a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteDuplicateType.java +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteDuplicateType.java @@ -35,13 +35,13 @@ public void test_dupType2() throws Exception { LinkedHashMap> cartMap = new LinkedHashMap>(); - HashMap obj = new HashMap(); + HashMap obj = new LinkedHashMap(); obj.put("id", 1001); obj.put(JSON.DEFAULT_TYPE_KEY, "com.alibaba.json.bvt.writeClassName.WriteDuplicateType$DianDianCart"); cartMap.put("1001", obj); String text1 = JSON.toJSONString(cartMap, SerializerFeature.WriteClassName); - Assert.assertEquals("{\"@type\":\"java.util.LinkedHashMap\",\"1001\":{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteDuplicateType$DianDianCart\",\"id\":1001}}", text1); + Assert.assertEquals("{\"@type\":\"java.util.LinkedHashMap\",\"1001\":{\"id\":1001,\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteDuplicateType$DianDianCart\"}}", text1); } diff --git a/src/test/java/com/alibaba/json/bvtVO/ArgCheckTest.java b/src/test/java/com/alibaba/json/bvtVO/ArgCheckTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/Bean.java b/src/test/java/com/alibaba/json/bvtVO/Bean.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/DataTransaction.java b/src/test/java/com/alibaba/json/bvtVO/DataTransaction.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/DataTransaction2.java b/src/test/java/com/alibaba/json/bvtVO/DataTransaction2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/IEvent.java b/src/test/java/com/alibaba/json/bvtVO/IEvent.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/IEventDto.java b/src/test/java/com/alibaba/json/bvtVO/IEventDto.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/Image.java b/src/test/java/com/alibaba/json/bvtVO/Image.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/Main.java b/src/test/java/com/alibaba/json/bvtVO/Main.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/OfferRankResultVO.java b/src/test/java/com/alibaba/json/bvtVO/OfferRankResultVO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/OptionKey.java b/src/test/java/com/alibaba/json/bvtVO/OptionKey.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/OptionValue.java b/src/test/java/com/alibaba/json/bvtVO/OptionValue.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/Page.java b/src/test/java/com/alibaba/json/bvtVO/Page.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/PhysicalQueue.java b/src/test/java/com/alibaba/json/bvtVO/PhysicalQueue.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/ProductView.java b/src/test/java/com/alibaba/json/bvtVO/ProductView.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/QueueEntity.java b/src/test/java/com/alibaba/json/bvtVO/QueueEntity.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/RainbowStats.java b/src/test/java/com/alibaba/json/bvtVO/RainbowStats.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/TempAttachMetaOption.java b/src/test/java/com/alibaba/json/bvtVO/TempAttachMetaOption.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/TestDTO.java b/src/test/java/com/alibaba/json/bvtVO/TestDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/VirtualTopic.java b/src/test/java/com/alibaba/json/bvtVO/VirtualTopic.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/WareHouseInfo.java b/src/test/java/com/alibaba/json/bvtVO/WareHouseInfo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/alipay/PlatformDepartmentVO.java b/src/test/java/com/alibaba/json/bvtVO/alipay/PlatformDepartmentVO.java new file mode 100644 index 0000000000..82f1b10965 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/alipay/PlatformDepartmentVO.java @@ -0,0 +1,257 @@ +package com.alibaba.json.bvtVO.alipay; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.ArrayList; +import java.util.List; + +public class PlatformDepartmentVO { + @JSONField(ordinal=1) + private String id ; + @JSONField(ordinal=2) + private String label ; + @JSONField(ordinal=3) + private String value; + @JSONField(ordinal=4) + private String parentId; + @JSONField(ordinal=5) + private String parentLabel; + @JSONField(ordinal=6) + private String companyId; + @JSONField(ordinal=7) + private String departCode; + @JSONField(ordinal=8) + private String memo; + @JSONField(ordinal=9) + private String departOrgCode; + @JSONField(ordinal=10) + private String contact; + @JSONField(ordinal=11) + private String mobile; + @JSONField(ordinal=12) + private String departType; + @JSONField(serialize=false) + private String ipId; + @JSONField(serialize=false) + private String ipRoleId; + @JSONField(serialize=false) + private PlatformDepartmentVO parent; + @JSONField(ordinal=6,name="ChildNodes") + private List childNodes =new ArrayList(); + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + + public String getParentId() { + return parentId; + } + public void setParentId(String parentId) { + this.parentId = parentId; + } + public String getCompanyId() { + return companyId; + } + public void setCompanyId(String companyId) { + this.companyId = companyId; + } + + public String getDepartCode() { + return departCode; + } + public void setDepartCode(String departCode) { + this.departCode = departCode; + } + public String getMemo() { + return memo; + } + public void setMemo(String memo) { + this.memo = memo; + } + public PlatformDepartmentVO getParent() { + return parent; + } + public void setParent(PlatformDepartmentVO parent) { + this.parent = parent; + } + public List getChildNodes() { + return childNodes; + } + public void setChildNodes(List childNodes) { + this.childNodes = childNodes; + } + + /** + * Getter method for property departType. + * + * @return property value of departType + */ + public String getDepartType() { + return departType; + } + + /** + * Setter method for property departType. + * + * @param departType value to be assigned to property departType + */ + public void setDepartType(String departType) { + this.departType = departType; + } + + /** + * Getter method for property parentLabel. + * + * @return property value of parentLabel + */ + public String getParentLabel() { + return parentLabel; + } + + /** + * Setter method for property parentLabel. + * + * @param parentLabel value to be assigned to property parentLabel + */ + public void setParentLabel(String parentLabel) { + this.parentLabel = parentLabel; + } + + /** + * Getter method for property departOrgCode. + * + * @return property value of departOrgCode + */ + public String getDepartOrgCode() { + return departOrgCode; + } + + /** + * Setter method for property departOrgCode. + * + * @param departOrgCode value to be assigned to property departOrgCode + */ + public void setDepartOrgCode(String departOrgCode) { + this.departOrgCode = departOrgCode; + } + + /** + * Getter method for property contact. + * + * @return property value of contact + */ + public String getContact() { + return contact; + } + + /** + * Setter method for property contact. + * + * @param contact value to be assigned to property contact + */ + public void setContact(String contact) { + this.contact = contact; + } + + /** + * Getter method for property mobile. + * + * @return property value of mobile + */ + public String getMobile() { + return mobile; + } + + /** + * Setter method for property mobile. + * + * @param mobile value to be assigned to property mobile + */ + public void setMobile(String mobile) { + this.mobile = mobile; + } + + /** + * Getter method for property ipRoleId. + * + * @return property value of ipRoleId + */ + public String getIpRoleId() { + return ipRoleId; + } + + /** + * Setter method for property ipRoleId. + * + * @param ipRoleId value to be assigned to property ipRoleId + */ + public void setIpRoleId(String ipRoleId) { + this.ipRoleId = ipRoleId; + } + + /** + * Getter method for property ipId. + * + * @return property value of ipId + */ + public String getIpId() { + return ipId; + } + + /** + * Setter method for property ipId. + * + * @param ipId value to be assigned to property ipId + */ + public void setIpId(String ipId) { + this.ipId = ipId; + } + + public PlatformDepartmentVO() { + + } +// public PlatformDepartmentVO(String id, String label, String value, String parentId, +// String companyId) { +// this.id = id; +// this.label = label; +// this.value = value; +// this.parentId = parentId; +// this.companyId = companyId; +// } + + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + if(null==this.getId()){ + return false; + } + final PlatformDepartmentVO other = (PlatformDepartmentVO) obj; + if(!this.getId().equals(other.getId())) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvtVO/basic/LongPrimitiveEntity.java b/src/test/java/com/alibaba/json/bvtVO/basic/LongPrimitiveEntity.java new file mode 100644 index 0000000000..c18c048c98 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/basic/LongPrimitiveEntity.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvtVO.basic; + +public class LongPrimitiveEntity { + public long value; + + public LongPrimitiveEntity() { + + } + + public LongPrimitiveEntity(long value) { + this.value = value; + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/vip_com/QueryLoanOrderRsp.java b/src/test/java/com/alibaba/json/bvtVO/vip_com/QueryLoanOrderRsp.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/bvtVO/vip_com/TxnListItsm.java b/src/test/java/com/alibaba/json/bvtVO/vip_com/TxnListItsm.java old mode 100755 new mode 100644 diff --git "a/src/test/java/com/alibaba/json/bvtVO/\344\270\200\344\270\252\344\270\255\346\226\207\345\220\215\345\255\227\347\232\204\345\214\205/User.java" "b/src/test/java/com/alibaba/json/bvtVO/\344\270\200\344\270\252\344\270\255\346\226\207\345\220\215\345\255\227\347\232\204\345\214\205/User.java" new file mode 100644 index 0000000000..d639d5d556 --- /dev/null +++ "b/src/test/java/com/alibaba/json/bvtVO/\344\270\200\344\270\252\344\270\255\346\226\207\345\220\215\345\255\227\347\232\204\345\214\205/User.java" @@ -0,0 +1,18 @@ +package com.alibaba.json.bvtVO.一个中文名字的包; + +public class User { + Integer id ; + String name; + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } +} diff --git a/src/test/java/com/alibaba/json/demo/DateDemo.java b/src/test/java/com/alibaba/json/demo/DateDemo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/Demo1.java b/src/test/java/com/alibaba/json/demo/Demo1.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/Demo2.java b/src/test/java/com/alibaba/json/demo/Demo2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/EncodeDemo.java b/src/test/java/com/alibaba/json/demo/EncodeDemo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/FilterDemo.java b/src/test/java/com/alibaba/json/demo/FilterDemo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/Group.java b/src/test/java/com/alibaba/json/demo/Group.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/JSONFeidDemo.java b/src/test/java/com/alibaba/json/demo/JSONFeidDemo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/MapDemo.java b/src/test/java/com/alibaba/json/demo/MapDemo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/demo/User.java b/src/test/java/com/alibaba/json/demo/User.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/A1.java b/src/test/java/com/alibaba/json/test/A1.java index 9a72d58e3e..49229522af 100644 --- a/src/test/java/com/alibaba/json/test/A1.java +++ b/src/test/java/com/alibaba/json/test/A1.java @@ -1,9 +1,16 @@ package com.alibaba.json.test; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.util.IOUtils; import junit.framework.TestCase; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + /** * Created by wenshao on 14/03/2017. */ @@ -13,5 +20,29 @@ public void test_a() throws Exception { Object obj = JSON.parse("[{\"feature\":\"\\u3A56\\u3A26\"}]"); String json = JSON.toJSONString(obj, SerializerFeature.BrowserCompatible); System.out.println(json); + + + } + + + public void test_ser() throws Exception { +// JSONObject obj = new JSONObject(); +// +// ByteArrayOutputStream out = new ByteArrayOutputStream(); +// ObjectOutputStream objOut = new ObjectOutputStream(out); +// objOut.writeObject(obj); +// objOut.flush(); +// objOut.close(); +// byte[] bytes = out.toByteArray(); +// +// String str = Base64.encodeToString(bytes, false); +// System.out.println(str); + + byte[] bytes2 = IOUtils.decodeBase64("rO0ABXNyAB9jb20uYWxpYmFiYS5mYXN0anNvbi5KU09OT2JqZWN0AAAAAAAAAAECAAFMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAABB3CAAAABAAAAAAeA=="); + ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes2); + ObjectInputStream objIn = new ObjectInputStream(byteIn); + Object obj = objIn.readObject(); + assertEquals(JSONObject.class, obj.getClass()); + } } diff --git a/src/test/java/com/alibaba/json/test/Base64.java b/src/test/java/com/alibaba/json/test/Base64.java old mode 100755 new mode 100644 index 70ce078c30..2b11b5fdea --- a/src/test/java/com/alibaba/json/test/Base64.java +++ b/src/test/java/com/alibaba/json/test/Base64.java @@ -86,56 +86,56 @@ public class Base64 // **************************************************************************************** /** Encodes a raw byte array into a BASE64 char[] representation i accordance with RFC 2045. - * @param sArr The bytes to convert. If null or length 0 an empty array will be returned. + * @param bytes The bytes to convert. If null or length 0 an empty array will be returned. * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a * little faster. * @return A BASE64 encoded array. Never null. */ - public final static char[] encodeToChar(byte[] sArr, boolean lineSep) + public final static char[] encodeToChar(byte[] bytes, boolean lineSep) { // Check special case - int sLen = sArr != null ? sArr.length : 0; - if (sLen == 0) + int bytes_len = bytes != null ? bytes.length : 0; + if (bytes_len == 0) return new char[0]; - int eLen = (sLen / 3) * 3; // Length of even 24-bits. - int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count - int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array - char[] dArr = new char[dLen]; + int eLen = (bytes_len / 3) * 3; // Length of even 24-bits. + int cCnt = ((bytes_len - 1) / 3 + 1) << 2; // Returned character count + int chars_len = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + char[] chars = new char[chars_len]; // Encode even 24-bits for (int s = 0, d = 0, cc = 0; s < eLen;) { // Copy next three bytes into lower 24 bits of int, paying attension to sign. - int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + int i = (bytes[s++] & 0xff) << 16 | (bytes[s++] & 0xff) << 8 | (bytes[s++] & 0xff); // Encode the int into four chars - dArr[d++] = CA[(i >>> 18) & 0x3f]; - dArr[d++] = CA[(i >>> 12) & 0x3f]; - dArr[d++] = CA[(i >>> 6) & 0x3f]; - dArr[d++] = CA[i & 0x3f]; + chars[d++] = CA[(i >>> 18) & 0x3f]; + chars[d++] = CA[(i >>> 12) & 0x3f]; + chars[d++] = CA[(i >>> 6) & 0x3f]; + chars[d++] = CA[i & 0x3f]; // Add optional line separator - if (lineSep && ++cc == 19 && d < dLen - 2) { - dArr[d++] = '\r'; - dArr[d++] = '\n'; + if (lineSep && ++cc == 19 && d < chars_len - 2) { + chars[d++] = '\r'; + chars[d++] = '\n'; cc = 0; } } // Pad and encode last bits if source isn't even 24 bits. - int left = sLen - eLen; // 0 - 2. + int left = bytes_len - eLen; // 0 - 2. if (left > 0) { // Prepare the int - int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0); + int i = ((bytes[eLen] & 0xff) << 10) | (left == 2 ? ((bytes[bytes_len - 1] & 0xff) << 2) : 0); // Set last four chars - dArr[dLen - 4] = CA[i >> 12]; - dArr[dLen - 3] = CA[(i >>> 6) & 0x3f]; - dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '='; - dArr[dLen - 1] = '='; + chars[chars_len - 4] = CA[i >> 12]; + chars[chars_len - 3] = CA[(i >>> 6) & 0x3f]; + chars[chars_len - 2] = left == 2 ? CA[i & 0x3f] : '='; + chars[chars_len - 1] = '='; } - return dArr; + return chars; } /** Decodes a BASE64 encoded char array. All illegal characters will be ignored and can handle both arrays with @@ -517,7 +517,7 @@ public final static byte[] decode(String str) * @param s The source string. Length 0 will return an empty array. null will throw an exception. * @return The decoded array of bytes. May be of length 0. */ - public final static byte[] decodeFast(String s) + public final static byte[] dedecodeFast(String s) { // Check special case int sLen = s.length(); diff --git a/src/test/java/com/alibaba/json/test/Bug_0_Test.java b/src/test/java/com/alibaba/json/test/Bug_0_Test.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/DateTest.java b/src/test/java/com/alibaba/json/test/DateTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/DetectProhibitChar.java b/src/test/java/com/alibaba/json/test/DetectProhibitChar.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/DigitTest.java b/src/test/java/com/alibaba/json/test/DigitTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/ErrorAppendable.java b/src/test/java/com/alibaba/json/test/ErrorAppendable.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/FNV32_CollisionTest.java b/src/test/java/com/alibaba/json/test/FNV32_CollisionTest.java index b0c20e71da..6b51efa904 100644 --- a/src/test/java/com/alibaba/json/test/FNV32_CollisionTest.java +++ b/src/test/java/com/alibaba/json/test/FNV32_CollisionTest.java @@ -1,7 +1,6 @@ package com.alibaba.json.test; import junit.framework.TestCase; -import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper; import java.text.NumberFormat; import java.util.Random; diff --git a/src/test/java/com/alibaba/json/test/FNV32_CollisionTest_All.java b/src/test/java/com/alibaba/json/test/FNV32_CollisionTest_All.java index 65fba52ea1..4b01ef76be 100644 --- a/src/test/java/com/alibaba/json/test/FNV32_CollisionTest_All.java +++ b/src/test/java/com/alibaba/json/test/FNV32_CollisionTest_All.java @@ -10,6 +10,9 @@ import java.util.BitSet; import java.util.Random; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime; + /** * Created by wenshao on 08/01/2017. */ @@ -60,14 +63,14 @@ public void test_fnv_hash() throws Exception { long n = (long) Math.pow(digLetters.length, chars.length); for (; v < n; ++v) { - long hash = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; for (int i = 0; i < chars.length; ++i) { int power = powers[chars.length - i - 1]; int d = (int) ((v / power) % digLetters.length); char c = digLetters[d]; hash ^= c; - hash *= 0x100000001b3L; + hash *= fnv1a_64_magic_prime; } b[7] = (byte) (hash ); b[6] = (byte) (hash >>> 8); @@ -103,11 +106,11 @@ String build(long v, int len) { } static long fnv_hash(char[] chars) { - long hash = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; for (int i = 0; i < chars.length; ++i) { char c = chars[i]; hash ^= c; - hash *= 0x100000001b3L; + hash *= fnv1a_64_magic_prime; } return hash; } diff --git a/src/test/java/com/alibaba/json/test/FNVHashTest.java b/src/test/java/com/alibaba/json/test/FNVHashTest.java index ddd106ad68..545acd5594 100644 --- a/src/test/java/com/alibaba/json/test/FNVHashTest.java +++ b/src/test/java/com/alibaba/json/test/FNVHashTest.java @@ -4,6 +4,9 @@ import java.util.*; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_hashcode; +import static com.alibaba.fastjson.util.TypeUtils.fnv1a_64_magic_prime; + /** * Created by wenshao on 05/01/2017. */ @@ -68,11 +71,11 @@ static int fnv_hash32(char[] chars) { } static long fnv_hash64(char[] chars) { - long hash = 0xcbf29ce484222325L; + long hash = fnv1a_64_magic_hashcode; for (int i = 0; i < chars.length; ++i) { char c = chars[i]; hash ^= c; - hash *= 0x100000001b3L; + hash *= fnv1a_64_magic_prime; } return hash; } diff --git a/src/test/java/com/alibaba/json/test/GenerateJavaTest.java b/src/test/java/com/alibaba/json/test/GenerateJavaTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/IntArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/test/IntArrayFieldTest_primitive.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/Issue3805.java b/src/test/java/com/alibaba/json/test/Issue3805.java new file mode 100644 index 0000000000..b327f0e853 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/Issue3805.java @@ -0,0 +1,73 @@ +package com.alibaba.json.test; + +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import lombok.Data; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.time.LocalDateTime; + +/** + * @project fastjson + * @desc: + * @date 2021-06-15 15:18 + */ +public class Issue3805 { + + @Data + private class TestModel { + private LocalDateTime createTime; + } + + @Test + public void test() throws Exception { + + String dateFormat = "yyyy"; + TestModel model = new TestModel(); + model.setCreateTime(LocalDateTime.of(2021,5,6,7,8,9,5)); + + FastJsonConfig config = new FastJsonConfig(); + + config.setDateFormat(dateFormat); + + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + converter.setFastJsonConfig(config); + + converter.canRead(TestModel.class, MediaType.APPLICATION_JSON_UTF8); + converter.canWrite(TestModel.class, MediaType.APPLICATION_JSON_UTF8); + + final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + HttpOutputMessage out = new HttpOutputMessage() { + public HttpHeaders getHeaders() { + return new HttpHeaders() { + private static final long serialVersionUID = 1L; + + @Override + public MediaType getContentType() { + return MediaType.APPLICATION_JSON; + } + }; + } + + public OutputStream getBody() throws IOException { + return byteOut; + } + }; + + converter.write(model, TestModel.class, MediaType.APPLICATION_JSON_UTF8, out); + byte[] bytes = byteOut.toByteArray(); + String jsonString = new String(bytes, "UTF-8"); +// System.out.println(jsonString); + Assert.assertEquals(jsonString, "{\"createTime\":\"2021\"}"); + + } + + +} diff --git a/src/test/java/com/alibaba/json/test/JSONLibXmlTest.java b/src/test/java/com/alibaba/json/test/JSONLibXmlTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/JSONParser2Test.java b/src/test/java/com/alibaba/json/test/JSONParser2Test.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/SymbolTableDupTest.java b/src/test/java/com/alibaba/json/test/SymbolTableDupTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/TestASM.java b/src/test/java/com/alibaba/json/test/TestASM.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/TestFor_iteye_resolute.java b/src/test/java/com/alibaba/json/test/TestFor_iteye_resolute.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/TestSysProperty.java b/src/test/java/com/alibaba/json/test/TestSysProperty.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/TestUtils.java b/src/test/java/com/alibaba/json/test/TestUtils.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/TestWriteSlashAsSpecial.java b/src/test/java/com/alibaba/json/test/TestWriteSlashAsSpecial.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/UTF8Test.java b/src/test/java/com/alibaba/json/test/UTF8Test.java index d1611cbdf3..f20ce80ce1 100644 --- a/src/test/java/com/alibaba/json/test/UTF8Test.java +++ b/src/test/java/com/alibaba/json/test/UTF8Test.java @@ -32,20 +32,22 @@ protected void setUp() throws Exception { public void test_encode() throws Exception { - for (int i = 0; i < 5; ++i) { - f0(); - } +// for (int i = 0; i < 5; ++i) { +// f0(); +// } for (int i = 0; i < 5; ++i) { f1(); } - for (int i = 0; i < 5; ++i) { - f2(); - } +// for (int i = 0; i < 5; ++i) { +// f2(); +// } } + final static int COUNT = 1000 * 1000 * 5; + private void f0() throws Exception { long start = System.currentTimeMillis(); - for (int i = 0; i < 1000 * 1000; ++i) { + for (int i = 0; i < COUNT; ++i) { text.getBytes(charset); } long millis = System.currentTimeMillis() - start; @@ -54,7 +56,7 @@ private void f0() throws Exception { private void f1() throws Exception { long start = System.currentTimeMillis(); - for (int i = 0; i < 1000 * 1000; ++i) { + for (int i = 0; i < COUNT; ++i) { IOUtils.encodeUTF8(chars, 0, chars.length, bytes); } long millis = System.currentTimeMillis() - start; @@ -63,7 +65,7 @@ private void f1() throws Exception { private void f2() throws Exception { long start = System.currentTimeMillis(); - for (int i = 0; i < 1000 * 1000; ++i) { + for (int i = 0; i < COUNT; ++i) { charset.newEncoder().encode(CharBuffer.wrap(chars)); } long millis = System.currentTimeMillis() - start; diff --git a/src/test/java/com/alibaba/json/test/UTF8Test_decode.java b/src/test/java/com/alibaba/json/test/UTF8Test_decode.java index 4419790387..f352ba6267 100644 --- a/src/test/java/com/alibaba/json/test/UTF8Test_decode.java +++ b/src/test/java/com/alibaba/json/test/UTF8Test_decode.java @@ -37,8 +37,8 @@ public void test_encode() throws Exception { for (int i = 0; i < 10; ++i) { long start = System.currentTimeMillis(); -// f0(); // 764 - f1(); // 695 + f0(); // 764 +// f1(); // 695 // f2(); // 975 long millis = System.currentTimeMillis() - start; System.out.println("millis : " + millis); diff --git a/src/test/java/com/alibaba/json/test/a/Group.java b/src/test/java/com/alibaba/json/test/a/Group.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/a/JTest.java b/src/test/java/com/alibaba/json/test/a/JTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/a/User.java b/src/test/java/com/alibaba/json/test/a/User.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkCase.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkCase.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkExecutor.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkExecutor.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain.java old mode 100755 new mode 100644 index c1f745bfce..7a6d71b72b --- a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain.java +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain.java @@ -29,10 +29,14 @@ public static void main(String[] args) throws Exception { // executor.getCaseList().add(new EishayDecodeBytes()); // executor.getCaseList().add(new EishayEncodeOutputStream()); // executor.getCaseList().add(new EishayEncodeToBytes()); -// executor.getCaseList().add(new EishayDecode()); + executor.getCaseList().add(new EishayDecode()); // 1069 + //JDK8_162 1094 + //JDK9_01 1214 + //JDK9_04 1252 + //JDK10 1088 // executor.getCaseList().add(new EishayDecodeByClassName()); // executor.getCaseList().add(new EishayTreeDecode()); - executor.getCaseList().add(new EishayEncode()); +// executor.getCaseList().add(new EishayEncode()); // executor.getCaseList().add(new EishayEncodeManual()); // executor.getCaseList().add(new IntArray1000Decode()); // executor.getCaseList().add(new StringArray1000Decode()); diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/JSONPathBenchmarkTest.java b/src/test/java/com/alibaba/json/test/benchmark/JSONPathBenchmarkTest.java new file mode 100644 index 0000000000..773b8621e6 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/JSONPathBenchmarkTest.java @@ -0,0 +1,81 @@ +package com.alibaba.json.test.benchmark; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.Feature; + +public class JSONPathBenchmarkTest { + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 5; ++i) { + f0(); // 390 353 + } + for (int i = 0; i < 5; ++i) { +// f1(); + } + } + + public static void f0() throws Exception { + long start = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000; ++i) { + Object val = JSONPath.extract(json2, "$.expensive"); + if (((Integer) val).intValue() != 10) { + throw new Exception(); + } + } + long millis = System.currentTimeMillis() - start; + System.out.println("extract millis : " + millis); + } + + public static void f1() throws Exception { + long start = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000; ++i) { + Object val = JSONPath.read(json2, "$.expensive"); + if (((Integer) val).intValue() != 10) { + throw new Exception(); + } + } + long millis = System.currentTimeMillis() - start; + System.out.println("eval millis : " + millis); + } + + public static final String json = "{\n" + + " \"store\": {\n" + + " \"book\": [\n" + + " {\n" + + " \"category\": \"reference\",\n" + + " \"author\": \"Nigel Rees\",\n" + + " \"title\": \"Sayings of the Century\",\n" + + " \"price\": 8.95\n" + + " },\n" + + " {\n" + + " \"category\": \"fiction\",\n" + + " \"author\": \"Evelyn Waugh\",\n" + + " \"title\": \"Sword of Honour\",\n" + + " \"price\": 12.99\n" + + " },\n" + + " {\n" + + " \"category\": \"fiction\",\n" + + " \"author\": \"Herman Melville\",\n" + + " \"title\": \"Moby Dick\",\n" + + " \"isbn\": \"0-553-21311-3\",\n" + + " \"price\": 8.99\n" + + " },\n" + + " {\n" + + " \"category\": \"fiction\",\n" + + " \"author\": \"J. R. R. Tolkien\",\n" + + " \"title\": \"The Lord of the Rings\",\n" + + " \"isbn\": \"0-395-19395-8\",\n" + + " \"price\": 22.99\n" + + " }\n" + + " ],\n" + + " \"bicycle\": {\n" + + " \"color\": \"red\",\n" + + " \"price\": 19.95\n" + + " }\n" + + " },\n" + + " \"expensive\": 10\n" + + "}"; + + public static final String json2 = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}},\"expensive\":10}"; +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/RyuDoubleBenchmark.java b/src/test/java/com/alibaba/json/test/benchmark/RyuDoubleBenchmark.java new file mode 100644 index 0000000000..bec9804eb1 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/RyuDoubleBenchmark.java @@ -0,0 +1,41 @@ +package com.alibaba.json.test.benchmark; + +import com.alibaba.fastjson.util.RyuDouble; + +public class RyuDoubleBenchmark { + private final static int COUNT = 1000 * 1000 * 10; + public static void main(String[] args) throws Exception { + double v = 0.5390050566444644; //new java.util.Random().nextDouble(); + + + System.out.println(v); + + for (int i = 0; i < 10; ++i) { + f0(v); // 2505, 1865 + } + +// System.out.println(); +// +// for (int i = 0; i < 10; ++i) { +// f1(v); // 752, 571 +// } + } + + public static void f0(double v) throws Exception { + long start = System.currentTimeMillis(); + for (int i = 0; i < COUNT; ++i) { + Double.toString(v); + } + long millis = System.currentTimeMillis() - start; + System.out.println("jdk : " + millis); + } + + public static void f1(double v) throws Exception { + long start = System.currentTimeMillis(); + for (int i = 0; i < COUNT; ++i) { + RyuDouble.toString(v); + } + long millis = System.currentTimeMillis() - start; + System.out.println("ryu : " + millis); + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/RyuFloatBenchmark.java b/src/test/java/com/alibaba/json/test/benchmark/RyuFloatBenchmark.java new file mode 100644 index 0000000000..e64048b576 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/RyuFloatBenchmark.java @@ -0,0 +1,42 @@ +package com.alibaba.json.test.benchmark; + +import com.alibaba.fastjson.util.RyuDouble; +import com.alibaba.fastjson.util.RyuFloat; + +public class RyuFloatBenchmark { + private final static int COUNT = 1000 * 1000 * 10; + public static void main(String[] args) throws Exception { + float v = 0.539005056644f; //new java.util.Random().nextDouble(); + + + System.out.println(v); + +// for (int i = 0; i < 10; ++i) { +// f0(v); // 741 +// } + +// System.out.println(); +// + for (int i = 0; i < 10; ++i) { + f1(v); // 368 + } + } + + public static void f0(float v) throws Exception { + long start = System.currentTimeMillis(); + for (int i = 0; i < COUNT; ++i) { + Float.toString(v); + } + long millis = System.currentTimeMillis() - start; + System.out.println("jdk : " + millis); + } + + public static void f1(float v) throws Exception { + long start = System.currentTimeMillis(); + for (int i = 0; i < COUNT; ++i) { + RyuFloat.toString(v); + } + long millis = System.currentTimeMillis() - start; + System.out.println("ryu : " + millis); + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/basic/IntBenchmark.java b/src/test/java/com/alibaba/json/test/benchmark/basic/IntBenchmark.java index 6dd5b48d59..acea490feb 100644 --- a/src/test/java/com/alibaba/json/test/benchmark/basic/IntBenchmark.java +++ b/src/test/java/com/alibaba/json/test/benchmark/basic/IntBenchmark.java @@ -19,6 +19,7 @@ public class IntBenchmark { "}"; public static void main(String[] args) throws Exception { + System.out.println(System.getProperty("java.vm.name") + " " + System.getProperty("java.runtime.version")); // Model model = new Model(); // model.v1 = new Random().nextInt(); // model.v2 = new Random().nextInt(); @@ -30,9 +31,9 @@ public static void main(String[] args) throws Exception { for (int i = 0; i < 10; ++i) { -// perf(); // 1798 + perf(); // 1798 // perf2(); // 1877 - perf3(); // 20624 2334 +// perf3(); // 20624 2334 } } diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/BooleanArray1000Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/BooleanArray1000Decode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode2Bytes.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode2Bytes.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeByClassName.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeByClassName.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeBytes.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeBytes.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayTreeDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayTreeDecode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100IntDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100IntDecode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100StringDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100StringDecode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/GroupDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/GroupDecode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/IntArray1000Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/IntArray1000Decode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Map1000StringDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Map1000StringDecode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Map1Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Map1Decode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/StringArray1000Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/StringArray1000Decode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayBoolean1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayBoolean1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayByte1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayByte1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyList1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyList1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyMap1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyMap1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayInt1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayInt1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayLong1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayLong1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayObjectEmptyMap1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayObjectEmptyMap1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayString1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayString1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/CategoryEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/CategoryEncode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/EishayEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/EishayEncode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/Entity100IntEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/Entity100IntEncode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/GroupEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/GroupEncode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ListBoolean1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ListBoolean1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/Map1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/Map1000Encode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100Int.java b/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100Int.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100String.java b/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100String.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/benchmark/jdk10/StringBenchmark.java b/src/test/java/com/alibaba/json/test/benchmark/jdk10/StringBenchmark.java new file mode 100644 index 0000000000..e37944f15a --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/jdk10/StringBenchmark.java @@ -0,0 +1,131 @@ +package com.alibaba.json.test.benchmark.jdk10; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.openjdk.jmh.annotations.*; + +import java.util.HashMap; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@Warmup(iterations = 10) +@Measurement(iterations = 10) +@State(Scope.Benchmark) +public class StringBenchmark { + private ObjectMapper mapper = new ObjectMapper(); + + static private String s = "{\"compress\":true,\"queryParams\":\"^^$$Z29e389d72fca43e2591dfa6d5bd182039|null{$_$}H4sIAAAAAAAAAK1YW2/kthX+K4GeGsCdkpRIit6XztrehVHf4ssmabwYUCRlay2Jii72ThcD9L3IY5/7NwL076To3+ghJc1obDd2g754R0fnfvnO0X4J0loW5sHWd2cSfjWHRZUHu1+CKpdtauviclkZ96xy2TQnwBrsBsoWM5lniUzkrK2lNjOVZ6ZsZ4XVJp81tquVmZ1NNHwgwU5Q9tLfHp4fHB1cXCzCBQKqrXVWSrBJVjtBJW/Mf7PYSptIO4OflS2dNb0EjZmaFaaVE7L7lZvPs7dX35PZ2aiw1w2qbkxparC3E2jTKCD8+5//+OXnv/7y89/+9dPfgVrI+s60QN94/P7g5OB8fjR1loOzuVUyd+//crvYOwmA0jWmnjdNdlO+nLLmVtZGz6raNOC1bDNbzipXgtk3namXvho+bbUptalPa/jjiU511uyN8X4wdQOyJNht6864MJcFkNes4NMcYlagcRnspjJvgCkrm1bm+RbjhDbXsmptfWFyo1qjnxO7tDc3uTmSTXsBznfNs6qhD25l8wLXYOzXmUZX3tW22Id6Z/maq6qtMk0zdbNxbHP9qWvagbhauXrn2f2YWhexzu4zl7s9aFuoURghjDFkXGoNVWnWfM1g/FB7qUHNvOdyRNSX3v9cOfsXXVXZuj1tb019bpQBQ+XNxL/h/fH+ny+fUveeo9mysXmmfZ9MXp+CJ42Rh9VTGvgH/26yKX0XbNztu6KfNqDkWXm3HVJpjL6qwKSJhhdrXSDeh2XW8q19KEf5MrWQKZdzyMp9psz8UUbrMSeDOHDeWKubR3yrnYHTHJv21uonFTmfvoUSjm1yArgj8+23zh0Yw8KWazVJt+yrxjEhKKYR9aH1/TCECjwn9mGcLuvG8MIDnFNQmtZBZ++qNi7UPqLg4Pjs8nuHOtso+AT+Nog3gZlm2bSmeKQp6ZqshOQMZI8fweCR63fnTwvvBsR5d356vAAMPDn9FrhSYHg7iWTVk3zllC3TrC48wlx4y8EuBnJtoNvKmy36l8G3wciDrBxkWt3lo13IVwlWVo6cZLlPU9tmrjoYIURFGP2xh/KFLHVtM73gMzaL3NxV1YBmwLwhZoPmorXVAJ5Jl+XaR95zPBXrJDwcX56eXez/6Q/hDM2iGf/qd/Pe4hs+Q2++y6QtsjfHh18dz7/7OnCTM2Zo0+WPuyNrTszD2lrfE00/oucGSg3tdlVvsKk2P3amaV15jsH7EYxAJmtNX7QAVocDsczWWbs87wU2jLZyE994JC98FoEbBrdeVgCXdf/cZgUIyQIMBAyHJIxCRDndp/OIUBLtM8b3Ax8PDEi6J+t6+d6N2wQcwZ+ivwCC3R++BLZrXeQBpyxGUZykIkU6otgQJhHmJuGGKaKE72DYUO1p1/pG8VJKxBgzQilSIokREiqkRnIghlhizUFKybodcMaZdj8pY0hggpkICWTornPE0DUMobEgkQCq6mBX2rUlkL7P8hxmaHxsYJWY4fePnSxbSKpv56y8BzdtvfxmTUUzNLS5ucxci2FKCKYopIww7nwsKgnLfLQEC1yPRe/PiOlybKo8Wxfu4zCYz6T0Fcnxou9r21XDsF8ez4+OFu+uzk8OL6/OD/xVcO7vgos2U3drH+7M0ou9heiC0rZDay5aQMM87eoya7samsCD8mjoCGDl1Dnn/Hy54h+f2aQwlWXjN5rH2sHr32M/VQCnV9P1/AAVe28v7Z4D9Bsz2VwwW9vMfpkeW52l2UTBpBAu0eYzmB8TDWeX3aABmTmMVZAR/+gkHBjmn+AhwiGK48jluyuqvVtZlgYmt+zy3B137hxxFR16zat+MTcAfwsqohALwkkUxQuXgRcL/ljKgWdza6vKoe//cf4Bmsc0BdNhW+DF1pgtXA78n18BjR1XdAWjdpQ5vPohQEkqEeHRdIiiGBFsYoZZ8HHlJfTYfZNbdnotuQtgM1KPXkxPkO3LYt4sS/UOgGDTOMMxbtpmegsPpP3L0+FCgfOxsC7HE4fOrMNsY97BDQx1+JBtzqvqyasjc+/6xi/SIrEDWKTA8z5LW3fSTNvZpwD2jD/yhxtkcl88t3L+B3jcQrzfsAJfvahf2skjQoyo3BfrcOjfZxd9402HKMKGCa0ETQXFPCJxiBKWmEQgSrR03f953cVfrjfjfh3sXruBvw52roeR9ySXWE+DsfeEcfCvg9VE22nyCU7H3wQgq+21A9xlWy+Hrwr3Zdh3455Ut2Z9fq0/WJsLWDHS4XIf0PD1scDe2ZAwxEOaxlQrHicxD8OYuuQgFPEY9ZHJ8QNvEIqwkJxRHEnqJhHJWAoFCZSRjDVnvBcqbbksbLe2BNlOaSQjUJ/QiKE0lGmCBEpJmJAoHfK6uRUHOYMNDwkSTMRE0NgIzHTMqFBCplrK0MuN/dDvh8VLkNhHoWgoqBCJ5lQwnKAYmh8bhRiKhUkjr9hPB3xvLF7C5r49KMSCJNEJ55wJoyjChuqUEshnEm9Uuly+SiOPUxaGmmMEmU1Dg8NYY6plCpFgGbG1xtepEylXYcowVxEMNEk5YCmmKiEplTxkxKsrTGFfl0KVJGFKpJQmkgJhFlOkFYp0rLDiSGGvzs+sz+GrdNKQR6FEjEgqYsHgq1kxCI3jEBqGhhOdLomvUskg9bA1qIpTIUisE0Y4xcIgRnWc6nCj8pUuCuhHiohROAk5izBhhhoRaxFHsUx6iHDAnzXmxbosUN86sMsQVpowSsFNFScixZwqHQpMBY62dL7k5aDTyEglRnGcpqkAuCdIawQCKgUeaWKvc8T0VzZQ4sYjTqTGGkeMhYIDoEgGSyjVSvZ4ASdvvkGLNKWJMsAEk4B1xJOESQyTLHAM6dN9tpouKYZjaBBLQgwLSRIGKJjoiEEfRNAEiGqBOdOyh9fhw3P476nVfwDaiC3ccBQAAA==\",\"structures\":\"H4sIAAAAAAAAAI2QwW7DIBBE/4WzD+AYY/IHOUTpvbKsNawbJAMpxpVQ1X+vjZWzObK8nZ2ZX6K8m0ywj6AxDIxcPwloHXBZtkdFfB4r2THW1pxTJceOUqkuHEFswwsDpsUGwhc6lT4g5TVw3iXr10MkIMzvn2UdrYnva31FTEQ7CN52tOnGSU5UN5xh3QJlAkeBraqV3G3t4M1N/hyuyPcKLpqYSthX8NYseIoOlBxu9yinun1xd1u0TOZsBU2XFVYRjbP5wZDuGJ9elyhbtEUOst29hVO2//sHOuYJjmECAAA=\",\"submitParams\":\"^^$$Z262e889742b9875f5107901ea64c33b46|null{$_$}H4sIAAAAAAAAAM1XS2/kxhH+KwZPMaDQ3XxTe4lWqw2U7GgmkvZhRAHRJItSWySb7m5KOxIGCHyM4dxyChD7bvjgk9fI39nd+GekuknOjHaztoJcotOwurue31dVunUqyRq4FvJywfCXOmy62tm9dbqa6UrI5nTZgfkuaqbUEV51dp1CNC6rec5y5mrJSnCLmkOr3UaUULtK9LIAd7Gl4Znn7Djt8Pr54fHBk4OTk8zPCEqFLHnL0Ka32nE6dg4fsqiZyJlw8WcnWmOtXKJGXrgNaLYlNr9qeOk+fPqp5y4mhYNuVHUOLUi0t+OUoAoU/OufX79+9efXr75889XfUNoweQka5RuPf3twdHC892Tb2RidrUXBanN+c5HtHzko6RXIPaX4eXvvlOGLK47ZKiQwzdvzuSxBuhI+70Fpd39bejwIBzdAPjqdK2f3j7cOV3utaJeN6PG7YrUC9KTlorWvhnT+mo6vnvAWNi81NIel8XV04yG/Ge6TnfVhGEUkpR6NUt/bcdRlb4R+mPqBFyapF6QoLZjURky2rJjvNEh8L9yZ1J8Mj29XmCvR2xdOHEYJCZK8SitSBiEFL2KExpDHEBVekWK4eb/8Q89azfXS2cVAeHu1+SYuGs35zT5iD9WNKBmr7ELZF5hB0RoASNEI8xvjNzFz9Rglv7tQjxBAvF7nTuf7osnFGI9uWF1bwbyzinbJyrqA1RNyOehCia3qyRDnfKzPcMK0ljzvNShjteqV1eJQx5bJxIC/VzaIg5caWrVxEabvGeusyxIqkM5u29f1jiPvfGFl8Llkw7dJ8ZAEDeU6NK7mJu2H7bwuHyM3mR6PVn/aVKRIE0ojLwxJkeYJIWnhh8BiFPqU0TIeKgJyBkoNnLJkqvkVTPlwWFlKPJ4ybWCUEuqnaeD7yBzeXu4NN8Ysl/yKmziHKg4v/IBQSglB/Ii6PFxLMLIKIxyZ9farH376/kf0YDI5FtN5+49vX7/68c3Xf33z6ouf/vL9m79/R99+86VPEgMFofQIGGL/DPFFzi2daeyHUUjTJPYdw/JzrjQvTrTF0YRyjFUBG4MwHouBogVgJO25vYTdD7AXPBpTs2bWKJ/4PBXHNC7WLp8iWawVU0J4Mprfey+h5L55JOv8WZUtQKkmtcpCde2CtP7DDPSFKAd/ndbgpHZ+FuIdWzbIh9E7bIOnD1+oi2atd8Gm6PHyBVPPuNQ9qw+xxazvvEOT+jO0HVCsVxIYyH0meHvfhnGHVh/EvGlLdT0k26NxiP0sCAPDBAtvI46p55EExYZevLNBH7Qsr22JJy3TyQm7uiO/EF2HgsWd5CBjWo2iiXh4z85Lc9aCNpN4yGkJJs9jEQ5mi9NPDXDvDtX3pulmgG5NLbVUmOh3NOXYh1oEzihWF0zCNFpMXzT+aDwbafb4eD7LcKQezZ/jrQovPOyXR+La2dWyN1FU9g0xMG4rLpshI9aybdp3Btwkvx19G41cY5czRCz7erKLpWjRymrDT3RLG1g72BqIGUO/GXp+xtpSCl5msRu5gWkIXfcMWTp0242Qj5obLbpxFuc9r0sb+XDj/Wc9tlVndjpfnDz6/Se+S9zAjT/61d5g8UHskgcvOBMNfzA7/Gi29+Jjx+BuytA0k9V7oOLqCK7X1kwmsVp91wmpjwFLjVx8KustetqOYcozQ++3IITDeiiag5uIGXVcSOTA3RZjZtE1k+W+ndZqaNx4tYARm4jY62Ng9cLI8NjD4UruOZqyLDMUzbAAWWYKl4XY7GnqxV4QJJmZdniA+S7A3Kmx/QwXSV4x4sUBDT2PhgR7rxcFCfEoJBGN7DN4mXV2O7UPbs8QY2PSzpzdM8dzyZmzY6R9N4pMKq0M+4gVTJ3kzFlZlY3OWHmVgSEzWLXWQwktoiDTvAEr2/iU2E2E36DzMK4eP7dstMX+BRSXpg9nWlyCnfhlWkGY+DGFIvB8GtOKJayiYVXQKqRhXAYszuPc0LCqBrA4htWf90LD+ksCrjHAMeuOH7lh7FIvdb3UnrQjexF63hiTsmTxSUAhSssiDas0pHHgJT7JoxzylIReyQzGG3vz+TNa3YS42BGcg2FR5bFfINVo5BckqSJajVdPx6hOATCOCtXnMfVzP89ZGtMAN8bYC4swNKu/gb5tfP8li8y8wi1an3Q117ZzWNze/vIQ+I8A/MXN5t1XdqnvStyhrPFpHV/TCv9PMsO3l3C6PcnXm+bwP9XQz7nat/jE+b4ZERq6I2Hb5mY75QqB3OrHMGwL62FE/sdRsdj//x0Q5H4DAnPx4QFxzya4Wq3d80bn/g2iNh8JBg8AAA==\",\"validateParams\":\"^^$$5da126afd2e7ebcf402eecea37f8e6df{$_$}H4sIAAAAAAAAAIVRTWsCMRT8LzlLcNePVW9ZG4ogItpaepJn9qmL2WRJIq0VoffSY8/9G4X+HUv/Rt9WSr2U3ibzXmaGeXu2dFDgnXWbMRDyg6LUrLdnpYawtK642pVYvZUG70e0ynpM2YKDzhewAB4cZMiVztEEXtgMNfd26xTy8ZnCLGY1Zk6/bwYTOZTT6bwxrxNrXZYbIM/4UGMlrPAvxwB2AZYTLK2p3LIdKeaKFxjgjK6QxnueXt/GfPwjeNImqRUadORXYxl6RcTn++vx7fH49vTx/EJsAW6DgfjfxJdyJCdieB42obDaKtDV/GE9748YMVuPTnifr8z/lfk1OMx46dBTagi5NbysTsAvIMCMlrPvi5yqQ8z6a1SbPjXMekvQHmsMjXK7MkyDy82KTLrtSLRF0ql32qLRkEIK0WzFUookitMo7cq006wnddGKREd22y12OHwB3aDYjQACAAA=\"}"; + static private DO d_o = JSON.parseObject(s, DO.class); + static private Object o; + static private int i; + static private HashMap methodMap = new HashMap(); + + @Setup + public void prepare() { + methodMap.put("org.openjdk.jmh.annotations.org.openjdk.jmh.annotations.StringBenchmark.prepare(aaa,bbb,com.alibaba.fastjson.JSON)", ""); + } + + @Benchmark + @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") + public void testParseJsonComp() { + o = JSON.parseObject(s, DO.class); + } + + @Benchmark + @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") + public void testParseJson() { + o = JSON.parseObject(s, DO.class); + } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") + public void testToJsonComp() { + o = JSON.toJSON(d_o); + } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") + public void testToJson() { + o = JSON.toJSON(d_o); + } + +// // @Benchmark +// @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") +// public void testJoinComp() { +// o = IntStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining()); +// } +// +// // @Benchmark +// @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") +// public void testJoin() { +// o = IntStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining()); +// } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") + public void testFindMethodComp() { + o = testFindMethod0(); + } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") + public void testFindMethod() { + o = testFindMethod0(); + } + + + private Object testFindMethod0() { + StringBuilder sb = new StringBuilder(); + sb.append("org.openjdk.jmh.annotations.org.openjdk.jmh.annotations.StringBenchmark") + .append(".").append("prepare").append("(") + .append("aaa").append(",").append("bbb").append(",") + .append("com.alibaba.fastjson.JSON").append(")"); + + return methodMap.get(sb.toString()); + } + + static class DO { + boolean compress; + String queryParams, structures, submitParams, validateParams; + + public boolean isCompress() { + return compress; + } + + public void setCompress(boolean compress) { + this.compress = compress; + } + + public String getQueryParams() { + return queryParams; + } + + public void setQueryParams(String queryParams) { + this.queryParams = queryParams; + } + + public String getStructures() { + return structures; + } + + public void setStructures(String structures) { + this.structures = structures; + } + + public String getSubmitParams() { + return submitParams; + } + + public void setSubmitParams(String submitParams) { + this.submitParams = submitParams; + } + + public String getValidateParams() { + return validateParams; + } + + public void setValidateParams(String validateParams) { + this.validateParams = validateParams; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/jdk10/StringBenchmark_jackson.java b/src/test/java/com/alibaba/json/test/benchmark/jdk10/StringBenchmark_jackson.java new file mode 100644 index 0000000000..4de26b3d59 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/jdk10/StringBenchmark_jackson.java @@ -0,0 +1,137 @@ +package com.alibaba.json.test.benchmark.jdk10; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.openjdk.jmh.annotations.*; + +import java.io.IOException; +import java.util.HashMap; + +@Warmup(iterations = 10) +@Measurement(iterations = 10) +@State(Scope.Benchmark) +public class StringBenchmark_jackson { + static ObjectMapper mapper = new ObjectMapper(); + static private String s = "{\"compress\":true,\"queryParams\":\"^^$$Z29e389d72fca43e2591dfa6d5bd182039|null{$_$}H4sIAAAAAAAAAK1YW2/kthX+K4GeGsCdkpRIit6XztrehVHf4ssmabwYUCRlay2Jii72ThcD9L3IY5/7NwL076To3+ghJc1obDd2g754R0fnfvnO0X4J0loW5sHWd2cSfjWHRZUHu1+CKpdtauviclkZ96xy2TQnwBrsBsoWM5lniUzkrK2lNjOVZ6ZsZ4XVJp81tquVmZ1NNHwgwU5Q9tLfHp4fHB1cXCzCBQKqrXVWSrBJVjtBJW/Mf7PYSptIO4OflS2dNb0EjZmaFaaVE7L7lZvPs7dX35PZ2aiw1w2qbkxparC3E2jTKCD8+5//+OXnv/7y89/+9dPfgVrI+s60QN94/P7g5OB8fjR1loOzuVUyd+//crvYOwmA0jWmnjdNdlO+nLLmVtZGz6raNOC1bDNbzipXgtk3namXvho+bbUptalPa/jjiU511uyN8X4wdQOyJNht6864MJcFkNes4NMcYlagcRnspjJvgCkrm1bm+RbjhDbXsmptfWFyo1qjnxO7tDc3uTmSTXsBznfNs6qhD25l8wLXYOzXmUZX3tW22Id6Z/maq6qtMk0zdbNxbHP9qWvagbhauXrn2f2YWhexzu4zl7s9aFuoURghjDFkXGoNVWnWfM1g/FB7qUHNvOdyRNSX3v9cOfsXXVXZuj1tb019bpQBQ+XNxL/h/fH+ny+fUveeo9mysXmmfZ9MXp+CJ42Rh9VTGvgH/26yKX0XbNztu6KfNqDkWXm3HVJpjL6qwKSJhhdrXSDeh2XW8q19KEf5MrWQKZdzyMp9psz8UUbrMSeDOHDeWKubR3yrnYHTHJv21uonFTmfvoUSjm1yArgj8+23zh0Yw8KWazVJt+yrxjEhKKYR9aH1/TCECjwn9mGcLuvG8MIDnFNQmtZBZ++qNi7UPqLg4Pjs8nuHOtso+AT+Nog3gZlm2bSmeKQp6ZqshOQMZI8fweCR63fnTwvvBsR5d356vAAMPDn9FrhSYHg7iWTVk3zllC3TrC48wlx4y8EuBnJtoNvKmy36l8G3wciDrBxkWt3lo13IVwlWVo6cZLlPU9tmrjoYIURFGP2xh/KFLHVtM73gMzaL3NxV1YBmwLwhZoPmorXVAJ5Jl+XaR95zPBXrJDwcX56eXez/6Q/hDM2iGf/qd/Pe4hs+Q2++y6QtsjfHh18dz7/7OnCTM2Zo0+WPuyNrTszD2lrfE00/oucGSg3tdlVvsKk2P3amaV15jsH7EYxAJmtNX7QAVocDsczWWbs87wU2jLZyE994JC98FoEbBrdeVgCXdf/cZgUIyQIMBAyHJIxCRDndp/OIUBLtM8b3Ax8PDEi6J+t6+d6N2wQcwZ+ivwCC3R++BLZrXeQBpyxGUZykIkU6otgQJhHmJuGGKaKE72DYUO1p1/pG8VJKxBgzQilSIokREiqkRnIghlhizUFKybodcMaZdj8pY0hggpkICWTornPE0DUMobEgkQCq6mBX2rUlkL7P8hxmaHxsYJWY4fePnSxbSKpv56y8BzdtvfxmTUUzNLS5ucxci2FKCKYopIww7nwsKgnLfLQEC1yPRe/PiOlybKo8Wxfu4zCYz6T0Fcnxou9r21XDsF8ez4+OFu+uzk8OL6/OD/xVcO7vgos2U3drH+7M0ou9heiC0rZDay5aQMM87eoya7samsCD8mjoCGDl1Dnn/Hy54h+f2aQwlWXjN5rH2sHr32M/VQCnV9P1/AAVe28v7Z4D9Bsz2VwwW9vMfpkeW52l2UTBpBAu0eYzmB8TDWeX3aABmTmMVZAR/+gkHBjmn+AhwiGK48jluyuqvVtZlgYmt+zy3B137hxxFR16zat+MTcAfwsqohALwkkUxQuXgRcL/ljKgWdza6vKoe//cf4Bmsc0BdNhW+DF1pgtXA78n18BjR1XdAWjdpQ5vPohQEkqEeHRdIiiGBFsYoZZ8HHlJfTYfZNbdnotuQtgM1KPXkxPkO3LYt4sS/UOgGDTOMMxbtpmegsPpP3L0+FCgfOxsC7HE4fOrMNsY97BDQx1+JBtzqvqyasjc+/6xi/SIrEDWKTA8z5LW3fSTNvZpwD2jD/yhxtkcl88t3L+B3jcQrzfsAJfvahf2skjQoyo3BfrcOjfZxd9402HKMKGCa0ETQXFPCJxiBKWmEQgSrR03f953cVfrjfjfh3sXruBvw52roeR9ySXWE+DsfeEcfCvg9VE22nyCU7H3wQgq+21A9xlWy+Hrwr3Zdh3455Ut2Z9fq0/WJsLWDHS4XIf0PD1scDe2ZAwxEOaxlQrHicxD8OYuuQgFPEY9ZHJ8QNvEIqwkJxRHEnqJhHJWAoFCZSRjDVnvBcqbbksbLe2BNlOaSQjUJ/QiKE0lGmCBEpJmJAoHfK6uRUHOYMNDwkSTMRE0NgIzHTMqFBCplrK0MuN/dDvh8VLkNhHoWgoqBCJ5lQwnKAYmh8bhRiKhUkjr9hPB3xvLF7C5r49KMSCJNEJ55wJoyjChuqUEshnEm9Uuly+SiOPUxaGmmMEmU1Dg8NYY6plCpFgGbG1xtepEylXYcowVxEMNEk5YCmmKiEplTxkxKsrTGFfl0KVJGFKpJQmkgJhFlOkFYp0rLDiSGGvzs+sz+GrdNKQR6FEjEgqYsHgq1kxCI3jEBqGhhOdLomvUskg9bA1qIpTIUisE0Y4xcIgRnWc6nCj8pUuCuhHiohROAk5izBhhhoRaxFHsUx6iHDAnzXmxbosUN86sMsQVpowSsFNFScixZwqHQpMBY62dL7k5aDTyEglRnGcpqkAuCdIawQCKgUeaWKvc8T0VzZQ4sYjTqTGGkeMhYIDoEgGSyjVSvZ4ASdvvkGLNKWJMsAEk4B1xJOESQyTLHAM6dN9tpouKYZjaBBLQgwLSRIGKJjoiEEfRNAEiGqBOdOyh9fhw3P476nVfwDaiC3ccBQAAA==\",\"structures\":\"H4sIAAAAAAAAAI2QwW7DIBBE/4WzD+AYY/IHOUTpvbKsNawbJAMpxpVQ1X+vjZWzObK8nZ2ZX6K8m0ywj6AxDIxcPwloHXBZtkdFfB4r2THW1pxTJceOUqkuHEFswwsDpsUGwhc6lT4g5TVw3iXr10MkIMzvn2UdrYnva31FTEQ7CN52tOnGSU5UN5xh3QJlAkeBraqV3G3t4M1N/hyuyPcKLpqYSthX8NYseIoOlBxu9yinun1xd1u0TOZsBU2XFVYRjbP5wZDuGJ9elyhbtEUOst29hVO2//sHOuYJjmECAAA=\",\"submitParams\":\"^^$$Z262e889742b9875f5107901ea64c33b46|null{$_$}H4sIAAAAAAAAAM1XS2/kxhH+KwZPMaDQ3XxTe4lWqw2U7GgmkvZhRAHRJItSWySb7m5KOxIGCHyM4dxyChD7bvjgk9fI39nd+GekuknOjHaztoJcotOwurue31dVunUqyRq4FvJywfCXOmy62tm9dbqa6UrI5nTZgfkuaqbUEV51dp1CNC6rec5y5mrJSnCLmkOr3UaUULtK9LIAd7Gl4Znn7Djt8Pr54fHBk4OTk8zPCEqFLHnL0Ka32nE6dg4fsqiZyJlw8WcnWmOtXKJGXrgNaLYlNr9qeOk+fPqp5y4mhYNuVHUOLUi0t+OUoAoU/OufX79+9efXr75889XfUNoweQka5RuPf3twdHC892Tb2RidrUXBanN+c5HtHzko6RXIPaX4eXvvlOGLK47ZKiQwzdvzuSxBuhI+70Fpd39bejwIBzdAPjqdK2f3j7cOV3utaJeN6PG7YrUC9KTlorWvhnT+mo6vnvAWNi81NIel8XV04yG/Ge6TnfVhGEUkpR6NUt/bcdRlb4R+mPqBFyapF6QoLZjURky2rJjvNEh8L9yZ1J8Mj29XmCvR2xdOHEYJCZK8SitSBiEFL2KExpDHEBVekWK4eb/8Q89azfXS2cVAeHu1+SYuGs35zT5iD9WNKBmr7ELZF5hB0RoASNEI8xvjNzFz9Rglv7tQjxBAvF7nTuf7osnFGI9uWF1bwbyzinbJyrqA1RNyOehCia3qyRDnfKzPcMK0ljzvNShjteqV1eJQx5bJxIC/VzaIg5caWrVxEabvGeusyxIqkM5u29f1jiPvfGFl8Llkw7dJ8ZAEDeU6NK7mJu2H7bwuHyM3mR6PVn/aVKRIE0ojLwxJkeYJIWnhh8BiFPqU0TIeKgJyBkoNnLJkqvkVTPlwWFlKPJ4ybWCUEuqnaeD7yBzeXu4NN8Ysl/yKmziHKg4v/IBQSglB/Ii6PFxLMLIKIxyZ9farH376/kf0YDI5FtN5+49vX7/68c3Xf33z6ouf/vL9m79/R99+86VPEgMFofQIGGL/DPFFzi2daeyHUUjTJPYdw/JzrjQvTrTF0YRyjFUBG4MwHouBogVgJO25vYTdD7AXPBpTs2bWKJ/4PBXHNC7WLp8iWawVU0J4Mprfey+h5L55JOv8WZUtQKkmtcpCde2CtP7DDPSFKAd/ndbgpHZ+FuIdWzbIh9E7bIOnD1+oi2atd8Gm6PHyBVPPuNQ9qw+xxazvvEOT+jO0HVCsVxIYyH0meHvfhnGHVh/EvGlLdT0k26NxiP0sCAPDBAtvI46p55EExYZevLNBH7Qsr22JJy3TyQm7uiO/EF2HgsWd5CBjWo2iiXh4z85Lc9aCNpN4yGkJJs9jEQ5mi9NPDXDvDtX3pulmgG5NLbVUmOh3NOXYh1oEzihWF0zCNFpMXzT+aDwbafb4eD7LcKQezZ/jrQovPOyXR+La2dWyN1FU9g0xMG4rLpshI9aybdp3Btwkvx19G41cY5czRCz7erKLpWjRymrDT3RLG1g72BqIGUO/GXp+xtpSCl5msRu5gWkIXfcMWTp0242Qj5obLbpxFuc9r0sb+XDj/Wc9tlVndjpfnDz6/Se+S9zAjT/61d5g8UHskgcvOBMNfzA7/Gi29+Jjx+BuytA0k9V7oOLqCK7X1kwmsVp91wmpjwFLjVx8KustetqOYcozQ++3IITDeiiag5uIGXVcSOTA3RZjZtE1k+W+ndZqaNx4tYARm4jY62Ng9cLI8NjD4UruOZqyLDMUzbAAWWYKl4XY7GnqxV4QJJmZdniA+S7A3Kmx/QwXSV4x4sUBDT2PhgR7rxcFCfEoJBGN7DN4mXV2O7UPbs8QY2PSzpzdM8dzyZmzY6R9N4pMKq0M+4gVTJ3kzFlZlY3OWHmVgSEzWLXWQwktoiDTvAEr2/iU2E2E36DzMK4eP7dstMX+BRSXpg9nWlyCnfhlWkGY+DGFIvB8GtOKJayiYVXQKqRhXAYszuPc0LCqBrA4htWf90LD+ksCrjHAMeuOH7lh7FIvdb3UnrQjexF63hiTsmTxSUAhSssiDas0pHHgJT7JoxzylIReyQzGG3vz+TNa3YS42BGcg2FR5bFfINVo5BckqSJajVdPx6hOATCOCtXnMfVzP89ZGtMAN8bYC4swNKu/gb5tfP8li8y8wi1an3Q117ZzWNze/vIQ+I8A/MXN5t1XdqnvStyhrPFpHV/TCv9PMsO3l3C6PcnXm+bwP9XQz7nat/jE+b4ZERq6I2Hb5mY75QqB3OrHMGwL62FE/sdRsdj//x0Q5H4DAnPx4QFxzya4Wq3d80bn/g2iNh8JBg8AAA==\",\"validateParams\":\"^^$$5da126afd2e7ebcf402eecea37f8e6df{$_$}H4sIAAAAAAAAAIVRTWsCMRT8LzlLcNePVW9ZG4ogItpaepJn9qmL2WRJIq0VoffSY8/9G4X+HUv/Rt9WSr2U3ibzXmaGeXu2dFDgnXWbMRDyg6LUrLdnpYawtK642pVYvZUG70e0ynpM2YKDzhewAB4cZMiVztEEXtgMNfd26xTy8ZnCLGY1Zk6/bwYTOZTT6bwxrxNrXZYbIM/4UGMlrPAvxwB2AZYTLK2p3LIdKeaKFxjgjK6QxnueXt/GfPwjeNImqRUadORXYxl6RcTn++vx7fH49vTx/EJsAW6DgfjfxJdyJCdieB42obDaKtDV/GE9748YMVuPTnifr8z/lfk1OMx46dBTagi5NbysTsAvIMCMlrPvi5yqQ8z6a1SbPjXMekvQHmsMjXK7MkyDy82KTLrtSLRF0ql32qLRkEIK0WzFUookitMo7cq006wnddGKREd22y12OHwB3aDYjQACAAA=\"}"; + static private DO d_o; + static private Object o; + static private int i; + static private HashMap methodMap = new HashMap(); + + static { + try { + d_o = mapper.readValue(s, DO.class); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Setup + public void prepare() { + methodMap.put("org.openjdk.jmh.annotations.org.openjdk.jmh.annotations.StringBenchmark.prepare(aaa,bbb,com.fasterxml.jackson.databind.ObjectMapper)", ""); + } + + @Benchmark + @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") + public void testParseJsonComp() throws Exception { + o = mapper.readValue(s, DO.class); + } + + @Benchmark + @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") + public void testParseJson() throws Exception { + o = mapper.readValue(s, DO.class); + } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") + public void testToJsonComp() throws Exception { + o = JSON.toJSON(d_o); + } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") + public void testToJson() throws Exception { + o = JSON.toJSON(d_o); + } + +// // @Benchmark +// @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") +// public void testJoinComp() { +// o = IntStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining()); +// } +// +// // @Benchmark +// @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") +// public void testJoin() { +// o = IntStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining()); +// } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:+CompactStrings") + public void testFindMethodComp() { + o = testFindMethod0(); + } + + // @Benchmark + @Fork(value = 3, jvmArgs = "-XX:-CompactStrings") + public void testFindMethod() { + o = testFindMethod0(); + } + + + private Object testFindMethod0() { + StringBuilder sb = new StringBuilder(); + sb.append("org.openjdk.jmh.annotations.org.openjdk.jmh.annotations.StringBenchmark") + .append(".").append("prepare").append("(") + .append("aaa").append(",").append("bbb").append(",") + .append("com.fasterxml.jackson.databind.ObjectMapper").append(")"); + + return methodMap.get(sb.toString()); + } + + static class DO { + boolean compress; + String queryParams, structures, submitParams, validateParams; + + public boolean isCompress() { + return compress; + } + + public void setCompress(boolean compress) { + this.compress = compress; + } + + public String getQueryParams() { + return queryParams; + } + + public void setQueryParams(String queryParams) { + this.queryParams = queryParams; + } + + public String getStructures() { + return structures; + } + + public void setStructures(String structures) { + this.structures = structures; + } + + public String getSubmitParams() { + return submitParams; + } + + public void setSubmitParams(String submitParams) { + this.submitParams = submitParams; + } + + public String getValidateParams() { + return validateParams; + } + + public void setValidateParams(String validateParams) { + this.validateParams = validateParams; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/codec/Codec.java b/src/test/java/com/alibaba/json/test/codec/Codec.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/codec/FastjsonCodec.java b/src/test/java/com/alibaba/json/test/codec/FastjsonCodec.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/codec/GsonCodec.java b/src/test/java/com/alibaba/json/test/codec/GsonCodec.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java b/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/codec/JacksonCodec.java b/src/test/java/com/alibaba/json/test/codec/JacksonCodec.java old mode 100755 new mode 100644 index 80c5941f81..e804f74a38 --- a/src/test/java/com/alibaba/json/test/codec/JacksonCodec.java +++ b/src/test/java/com/alibaba/json/test/codec/JacksonCodec.java @@ -61,12 +61,10 @@ public String encode(Object object) throws Exception { return mapper.writeValueAsString(object); } - @Override public byte[] encodeToBytes(Object object) throws Exception { return mapper.writeValueAsBytes(object); } - @Override public void encode(OutputStream out, Object object) throws Exception { out.write(encodeToBytes(object)); } diff --git a/src/test/java/com/alibaba/json/test/codec/JsonLibCodec.java b/src/test/java/com/alibaba/json/test/codec/JsonLibCodec.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/codec/JsonSmartCodec.java b/src/test/java/com/alibaba/json/test/codec/JsonSmartCodec.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/codec/SimpleJsonCodec.java b/src/test/java/com/alibaba/json/test/codec/SimpleJsonCodec.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/EnumTest.java b/src/test/java/com/alibaba/json/test/dubbo/EnumTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/FullAddress.java b/src/test/java/com/alibaba/json/test/dubbo/FullAddress.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/HelloServiceImpl.java b/src/test/java/com/alibaba/json/test/dubbo/HelloServiceImpl.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/Image.java b/src/test/java/com/alibaba/json/test/dubbo/Image.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/Person.java b/src/test/java/com/alibaba/json/test/dubbo/Person.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/PersonInfo.java b/src/test/java/com/alibaba/json/test/dubbo/PersonInfo.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/PersonStatus.java b/src/test/java/com/alibaba/json/test/dubbo/PersonStatus.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/Phone.java b/src/test/java/com/alibaba/json/test/dubbo/Phone.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/Tiger.java b/src/test/java/com/alibaba/json/test/dubbo/Tiger.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/dubbo/Tigers.java b/src/test/java/com/alibaba/json/test/dubbo/Tigers.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/Company.java b/src/test/java/com/alibaba/json/test/entity/Company.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/Department.java b/src/test/java/com/alibaba/json/test/entity/Department.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/Employee.java b/src/test/java/com/alibaba/json/test/entity/Employee.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/Group.java b/src/test/java/com/alibaba/json/test/entity/Group.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/TestEntity.java b/src/test/java/com/alibaba/json/test/entity/TestEntity.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/IntObject_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/IntObject_100_Entity.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/Int_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/Int_100_Entity.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/LongObject_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/LongObject_100_Entity.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/Long_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/Long_100_Entity.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/String_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/String_100_Entity.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/case2/Category.java b/src/test/java/com/alibaba/json/test/entity/case2/Category.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstance.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstanceParam.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstanceParam.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/LayoutInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/LayoutInstance.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/PageInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/PageInstance.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionEnum.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionEnum.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionInstance.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/SegmentInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/SegmentInstance.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/WidgetInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/WidgetInstance.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewBook.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewBook.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPoint.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPoint.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPointZone.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPointZone.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewMetaData.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewMetaData.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewPage.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewPage.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/TestKlutz.java b/src/test/java/com/alibaba/json/test/epubview/TestKlutz.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/TestKlutz2.java b/src/test/java/com/alibaba/json/test/epubview/TestKlutz2.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/epubview/TestKlutz3.java b/src/test/java/com/alibaba/json/test/epubview/TestKlutz3.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/jackson/JacksonInnerClassTest.java b/src/test/java/com/alibaba/json/test/jackson/JacksonInnerClassTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/jackson/JacksonTest.java b/src/test/java/com/alibaba/json/test/jackson/JacksonTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/knowissue/Bug_for_loveflying.java b/src/test/java/com/alibaba/json/test/knowissue/Bug_for_loveflying.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/DecoderPerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/DecoderPerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/IntArrayEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/IntArrayEncodePerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/IntegerArrayEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/IntegerArrayEncodePerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/IntegerListEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/IntegerListEncodePerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/JacksonGroupDecoder.java b/src/test/java/com/alibaba/json/test/performance/JacksonGroupDecoder.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/JacksonGroupParser.java b/src/test/java/com/alibaba/json/test/performance/JacksonGroupParser.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/JacksonPageModelParser.java b/src/test/java/com/alibaba/json/test/performance/JacksonPageModelParser.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/ObjectDecodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/ObjectDecodePerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/ObjectEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/ObjectEncodePerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/PageModelPerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/PageModelPerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/GenerateTest.java b/src/test/java/com/alibaba/json/test/performance/case1/GenerateTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/IntDecoderPerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/case1/IntDecoderPerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/IntObjectDecodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/case1/IntObjectDecodePerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/IntObjectEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/case1/IntObjectEncodePerformanceTest.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/alibaba/json/test/ryu/RyuDoubleTest.java b/src/test/java/com/alibaba/json/test/ryu/RyuDoubleTest.java new file mode 100644 index 0000000000..0c6c55f771 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/ryu/RyuDoubleTest.java @@ -0,0 +1,81 @@ +package com.alibaba.json.test.ryu; + +import com.alibaba.fastjson.util.RyuDouble; +import junit.framework.TestCase; + +import java.util.Random; + +public class RyuDoubleTest extends TestCase { + public void test_for_ryu() throws Exception { + Random random = new Random(); + + long start = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000 * 100; ++i) { + double value = random.nextDouble(); + + String str1 = Double.toString(value); + String str2 = RyuDouble.toString(value); + + if (!str1.equals(str2)) { + System.out.println(str1 + " -> " + str2); + assertTrue(Double.parseDouble(str1) == Double.parseDouble(str2)); + } + } + long millis = System.currentTimeMillis() - start; + System.out.println("millis : " + millis); + } + + public void test_0() throws Exception { + double[] values = new double[] { + Double.NaN, + Double.NEGATIVE_INFINITY, + Double.POSITIVE_INFINITY, + Double.MIN_VALUE, + Double.MAX_VALUE, + + 0, + 0.0d, + -0.0d, + Double.longBitsToDouble(0x8000000000000000L), + Double.NaN, + + Long.MAX_VALUE, + Long.MIN_VALUE, + Integer.MAX_VALUE, + Integer.MIN_VALUE, + Double.longBitsToDouble(0x0010000000000000L), + + 9999999.999999998d, + 0.0009999999999999998d, + 1.0E7d, + 0.001d, + Double.longBitsToDouble(0x7fefffffffffffffL), + + Double.longBitsToDouble(1), + -2.109808898695963E16, + 4.940656E-318d, + 1.18575755E-316d, + 2.989102097996E-312d, + 9.0608011534336E15d, + 4.708356024711512E18, + 9.409340012568248E18, + 1.8531501765868567E21, + -3.347727380279489E33, + 1.9430376160308388E16, + -6.9741824662760956E19, + 4.3816050601147837E18, + }; + + for (int i = 0; i < values.length; i++) { + double value = values[i]; + String str1 = Double.toString(value); + String str2 = RyuDouble.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Double.parseDouble(str1) == Double.parseDouble(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/test/ryu/RyuFloatTest.java b/src/test/java/com/alibaba/json/test/ryu/RyuFloatTest.java new file mode 100644 index 0000000000..de493bb483 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/ryu/RyuFloatTest.java @@ -0,0 +1,102 @@ +package com.alibaba.json.test.ryu; + +import com.alibaba.fastjson.util.RyuDouble; +import com.alibaba.fastjson.util.RyuFloat; +import junit.framework.TestCase; + +import java.util.Random; + +public class RyuFloatTest extends TestCase { + public void test_for_ryu() throws Exception { + Random random = new Random(); + + for (int i = 0; i < 1000 * 1000 * 1000; ++i) { + float value = random.nextFloat(); + + String str1 = Float.toString(value); + String str2 = RyuFloat.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Float.parseFloat(str1) == Float.parseFloat(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); +// assertTrue(Float.parseFloat(str1) == Float.parseFloat(str2)); + } + } + } + + public void test_0() throws Exception { + float[] values = new float[] { + Float.NaN, + Float.NEGATIVE_INFINITY, + Float.POSITIVE_INFINITY, + Float.MIN_VALUE, + Float.MAX_VALUE, + 0, + 0.0f, + -0.0f, + Integer.MAX_VALUE, + Integer.MIN_VALUE, + Long.MAX_VALUE, + Long.MIN_VALUE, + Float.intBitsToFloat(0x80000000), + 1.0f, + -1f, + Float.intBitsToFloat(0x00800000), + 1.0E7f, + 9999999.0f, + 0.001f, + 0.0009999999f, + Float.intBitsToFloat(0x7f7fffff), + Float.intBitsToFloat(0x00000001), + 3.3554448E7f, + 8.999999E9f, + 3.4366717E10f, + 0.33007812f, + Float.intBitsToFloat(0x5D1502F9), + Float.intBitsToFloat(0x5D9502F9), + Float.intBitsToFloat(0x5E1502F9), + 4.7223665E21f, + 8388608.0f, + 1.6777216E7f, + 3.3554436E7f, + 6.7131496E7f, + 1.9310392E-38f, + -2.47E-43f, + 1.993244E-38f, + 4103.9003f, + 5.3399997E9f, + 6.0898E-39f, + 0.0010310042f, + 2.8823261E17f, + 7.038531E-26f, + 9.2234038E17f, + 6.7108872E7f, + 1.0E-44f, + 2.816025E14f, + 9.223372E18f, + 1.5846085E29f, + 1.1811161E19f, + 5.368709E18f, + 4.6143165E18f, + 0.007812537f, + 1.4E-45f, + 1.18697724E20f, + 1.00014165E-36f, + 200f, + 3.3554432E7f + + }; + + for (float value : values) { + String str1 = Float.toString(value); + String str2 = RyuFloat.toString(value); + + if (!str1.equals(str2)) { + boolean cmp = (Float.parseFloat(str1) == Float.parseFloat(str2)); + System.out.println(str1 + " -> " + str2 + " : " + cmp); + assertTrue(cmp); + } + } + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/Generic.java b/src/test/java/com/derbysoft/spitfire/fastjson/Generic.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/Header.java b/src/test/java/com/derbysoft/spitfire/fastjson/Header.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/TestFastJson.java b/src/test/java/com/derbysoft/spitfire/fastjson/TestFastJson.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractRS.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractRS.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AgeQualifyingType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AgeQualifyingType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailGuaranteeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailGuaranteeDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailRoomStayDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailRoomStayDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/BathType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/BathType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPenaltyType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPenaltyType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPolicyDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPolicyDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CardCode.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CardCode.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeItemDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeItemDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeUnit.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeUnit.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CompositeType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CompositeType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/Currency.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/Currency.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/DateRangeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/DateRangeDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ErrorsDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ErrorsDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/GenericRS.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GenericRS.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuaranteeType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuaranteeType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuestCountDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuestCountDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRS.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRS.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRoomStayDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRoomStayDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelRefDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelRefDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/LanguageType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/LanguageType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/PaymentType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/PaymentType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ProviderChainDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ProviderChainDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RateDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RateDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RatePlanDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RatePlanDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ResponseHeader.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ResponseHeader.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomRateDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomRateDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomStayCandidateDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomStayCandidateDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomTypeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomTypeDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/SimpleAmountDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SimpleAmountDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/SmokingType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SmokingType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/StayDateRangeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/StayDateRangeDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/SuccessDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SuccessDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/TPAExtensionsDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/TPAExtensionsDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDType.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningsDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningsDTO.java old mode 100755 new mode 100644 diff --git a/src/test/java/com/wheelchair/parser/JSONScannerTest.java b/src/test/java/com/wheelchair/parser/JSONScannerTest.java new file mode 100644 index 0000000000..f832219e20 --- /dev/null +++ b/src/test/java/com/wheelchair/parser/JSONScannerTest.java @@ -0,0 +1,561 @@ +package com.wheelchair.parser; + +import com.diffblue.deeptestutils.Reflector; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Method; + +import static org.junit.Assert.*; +import com.diffblue.deeptestutils.Reflector; + + +public class JSONScannerTest { + + @Test + public void checkDate1() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(true, retval); + } + @Test + public void checkDate2() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 48; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate3() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 97; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate4() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 49; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(true, retval); + } + @Test + public void checkDate5() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 49; + int d1 = 21; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate6() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 49; + int d1 = 97; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate7() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 51; + int d1 = 49; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(true, retval); + } + @Test + public void checkDate8() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 51; + int d1 = 21; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate9() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 51; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate10() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 21; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate11() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 52; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate12() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '0'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate13() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = 'a'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate14() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '1'; + char M1 = '0'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(true, retval); + } + @Test + public void checkDate15() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '1'; + char M1 = '!'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate16() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '1'; + char M1 = '3'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate17() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '!'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate18() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '2'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate19() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = '!'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate20() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '2'; + char y3 = 'a'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate21() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = '!'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate22() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '0'; + char y2 = 'a'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate23() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = '!'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate24() throws Throwable { + // Arrange + char y0 = '2'; + char y1 = 'a'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate25() throws Throwable { + // Arrange + char y0 = '!'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } + @Test + public void checkDate26() throws Throwable { + // Arrange + char y0 = 'a'; + char y1 = '0'; + char y2 = '2'; + char y3 = '0'; + char M0 = '0'; + char M1 = '2'; + int d0 = 48; + int d1 = 52; + + // Act + Class c = Reflector.forName("com.alibaba.fastjson.parser.JSONScanner"); + Method m = c.getDeclaredMethod("checkDate", Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("char"), Reflector.forName("int"), Reflector.forName("int")); + m.setAccessible(true); + boolean retval = (Boolean)m.invoke(null, y0, y1, y2, y3, M0, M1, d0, d1); + + // Assert result + Assert.assertEquals(false, retval); + } +} \ No newline at end of file diff --git a/src/test/java/com/wheelchair/validate/testcase_accurate_json.json b/src/test/java/com/wheelchair/validate/testcase_accurate_json.json new file mode 100644 index 0000000000..2023b3d1ca --- /dev/null +++ b/src/test/java/com/wheelchair/validate/testcase_accurate_json.json @@ -0,0 +1 @@ +{"string":"a","nums":[0,-1,10,0.123,1e5,-1e+6,0.1e-7],"object":{"empty":{},"list":[]},"list":["object",{"true":true,"false":false,"null":null}]} \ No newline at end of file diff --git a/src/test/java/com/wheelchair/validate/testcase_colon_error.json b/src/test/java/com/wheelchair/validate/testcase_colon_error.json new file mode 100644 index 0000000000..02c17e0310 --- /dev/null +++ b/src/test/java/com/wheelchair/validate/testcase_colon_error.json @@ -0,0 +1 @@ +{"colonError"} \ No newline at end of file diff --git a/src/test/java/com/wheelchair/validate/testcase_num_error1.json b/src/test/java/com/wheelchair/validate/testcase_num_error1.json new file mode 100644 index 0000000000..ba3d065a0e --- /dev/null +++ b/src/test/java/com/wheelchair/validate/testcase_num_error1.json @@ -0,0 +1 @@ +{"num_err1":+a} \ No newline at end of file diff --git a/src/test/java/com/wheelchair/validate/testcase_num_error2.json b/src/test/java/com/wheelchair/validate/testcase_num_error2.json new file mode 100644 index 0000000000..26fe57838c --- /dev/null +++ b/src/test/java/com/wheelchair/validate/testcase_num_error2.json @@ -0,0 +1 @@ +{"num_err1":1ea} \ No newline at end of file diff --git a/src/test/java/com/wheelchair/validate/testcase_quotation_mark_error.json b/src/test/java/com/wheelchair/validate/testcase_quotation_mark_error.json new file mode 100644 index 0000000000..0a430ebb31 --- /dev/null +++ b/src/test/java/com/wheelchair/validate/testcase_quotation_mark_error.json @@ -0,0 +1 @@ +{noQuotationMarksError} \ No newline at end of file diff --git a/src/test/java/com/wheelchair/validate/testcase_square_brackets_error.json b/src/test/java/com/wheelchair/validate/testcase_square_brackets_error.json new file mode 100644 index 0000000000..6d6471c8e2 --- /dev/null +++ b/src/test/java/com/wheelchair/validate/testcase_square_brackets_error.json @@ -0,0 +1 @@ +{"square_brackets_error": [1} \ No newline at end of file diff --git a/src/test/java/com/wheelchair/validate/testcase_tfn_error.json b/src/test/java/com/wheelchair/validate/testcase_tfn_error.json new file mode 100644 index 0000000000..9c854f9785 --- /dev/null +++ b/src/test/java/com/wheelchair/validate/testcase_tfn_error.json @@ -0,0 +1 @@ +{"num_err1":trua} \ No newline at end of file diff --git a/src/test/java/data/ReprUtil.java b/src/test/java/data/ReprUtil.java old mode 100755 new mode 100644 diff --git a/src/test/java/data/media/FieldMapping.java b/src/test/java/data/media/FieldMapping.java old mode 100755 new mode 100644 diff --git a/src/test/java/data/media/Image.java b/src/test/java/data/media/Image.java old mode 100755 new mode 100644 diff --git a/src/test/java/data/media/Media.java b/src/test/java/data/media/Media.java old mode 100755 new mode 100644 diff --git a/src/test/java/data/media/MediaContent.java b/src/test/java/data/media/MediaContent.java old mode 100755 new mode 100644 diff --git a/src/test/java/data/media/MediaContentDeserializer.java b/src/test/java/data/media/MediaContentDeserializer.java old mode 100755 new mode 100644 diff --git a/src/test/resources/json/book.json b/src/test/resources/json/book.json new file mode 100644 index 0000000000..cb88a7b62f --- /dev/null +++ b/src/test/resources/json/book.json @@ -0,0 +1,37 @@ +{ + "store": { + "book": [ + { + "category": "reference", + "author": "Nigel Rees", + "title": "Sayings of the Century", + "price": 8.95 + }, + { + "category": "fiction", + "author": "Evelyn Waugh", + "title": "Sword of Honour", + "price": 12.99 + }, + { + "category": "fiction", + "author": "Herman Melville", + "title": "Moby Dick", + "isbn": "0-553-21311-3", + "price": 8.99 + }, + { + "category": "fiction", + "author": "J. R. R. Tolkien", + "title": "The Lord of the Rings", + "isbn": "0-395-19395-8", + "price": 22.99 + } + ], + "bicycle": { + "color": "red", + "price": 19.95 + } + }, + "expensive": 10 +} \ No newline at end of file diff --git a/src/test/resources/json/dla_01.json b/src/test/resources/json/dla_01.json new file mode 100644 index 0000000000..3c8e792438 --- /dev/null +++ b/src/test/resources/json/dla_01.json @@ -0,0 +1,585 @@ +{ + "queryId": "20181024_040507_3_f32vb", + "session": { + "queryId": "20181024_040507_3_f32vb", + "transactionId": "e63395c8-1206-4145-9b57-269c46501fa0", + "clientTransactionSupport": true, + "user": "1013022312866336", + "principal": null, + "source": "172.17.246.55:9999", + "catalog": "dla", + "schema": "dla", + "timeZoneKey": 1980, + "locale": "en_US", + "remoteUserAddress": "127.0.0.1", + "userAgent": null, + "clientInfo": null, + "startTime": 1540353907429, + "systemProperties": { + "prefer_streaming_operators": "true", + "query_max_memory_per_node": "1GB", + "reorder_joins": "false", + "auto_delete_query_enable": "false", + "colocated_join": "true", + "mpp_metric_enable": "true", + "task_writer_count": "1", + "distributed_join": "true", + "task_concurrency": "16", + "small_table_threshold": "1000", + "task_max_running_seconds": "10800", + "join_distribution_type": "automatic", + "query_plan_cache": "false", + "connector_hint": "eyJkbGEiOnt9fQ==", + "execution_policy": "all-at-once", + "resource_overcommit": "false", + "hash_partition_count": "16", + "query_plan_cache_check": "false", + "query_max_memory": "400GB" + }, + "catalogProperties": { + "hive": { + "oss_select_enabled": "false" + }, + "ads": { + "insert_into_batch_size": "100" + } + }, + "rootHint": {}, + "preparedStatements": {} + }, + "state": "FINISHED", + "memoryPool": "general", + "scheduled": true, + "self": "http://172.17.246.55:10001/v1/query/20181024_040507_3_f32vb", + "fieldNames": ["count(*)"], + "query": "SELECT count(*) AS \"count(*)\"\nFROM hive.oa1013022312866336_tpch_100m_text.lineitem", + "queryStats": { + "createTime": "2018-10-24T04:05:07.432Z", + "executionStartTime": "2018-10-24T04:05:07.570Z", + "lastHeartbeat": "2018-10-24T04:05:08.906Z", + "endTime": "2018-10-24T04:05:08.907Z", + "elapsedTime": "1.48s", + "queuedTime": "1.19ms", + "analysisTime": "28.00ms", + "hitPlanCache": false, + "distributedPlanningTime": "36.00ms", + "totalPlanningTime": "83.94ms", + "scheduleToRemoteTime": 303, + "finishingTime": "3.72ms", + "dataFinished": false, + "totalTasks": 3, + "runningTasks": 0, + "completedTasks": 3, + "totalDrivers": 20, + "queuedDrivers": 0, + "runningDrivers": 0, + "completedDrivers": 20, + "cumulativeMemory": 0.0, + "totalMemoryReservation": "0B", + "peakMemoryReservation": "0B", + "totalScheduledTime": "0.00ns", + "totalCpuTime": "5.16s", + "totalUserTime": "0.00ns", + "totalBlockedTime": "0.00ns", + "fullyBlocked": true, + "blockedReasons": [], + "rawInputDataSize": "70.81MB", + "rawInputPositions": 600572, + "processedInputDataSize": "0B", + "processedInputPositions": 600572, + "outputDataSize": "9B", + "outputPositions": 1, + "totalTableScanDataSize": 74246996, + "tableScanPosition": 600572, + "executionTime": "1.47s" + }, + "setSessionProperties": {}, + "resetSessionProperties": [], + "addedPreparedStatements": {}, + "deallocatedPreparedStatements": [], + "startedTransactionId": null, + "clearTransactionId": false, + "outputStage": { + "stageId": "20181024_040507_3_f32vb.0", + "state": "FINISHED", + "self": "http://172.17.246.55:10001/v1/stage/20181024_040507_3_f32vb.0", + "plan": { + "id": "0", + "root": { + "@type": "output", + "id": "7", + "source": { + "@type": "aggregation", + "id": "18", + "source": { + "@type": "exchange", + "id": "17", + "type": "GATHER", + "scope": "LOCAL", + "partitioningScheme": { + "partitioning": { + "handle": { + "connectorId": null, + "transactionHandle": null, + "connectorHandle": { + "@type": "$remote", + "partitioning": "SINGLE", + "function": "SINGLE" + } + }, + "arguments": [] + }, + "outputLayout": ["count_0_3"], + "hashColumn": null, + "replicateNulls": false, + "bucketToPartition": null + }, + "sources": [{ + "@type": "remoteSource", + "id": "16", + "sourceFragmentIds": ["1"], + "outputs": ["count_0_3"], + "label": "" + }], + "inputs": [ + ["count_0_3"] + ], + "label": "" + }, + "aggregations": { + "count": "\"count\"(\"count_0_3\")" + }, + "functions": { + "count": { + "name": "count", + "kind": "AGGREGATE", + "typeVariableConstraints": [], + "longVariableConstraints": [], + "returnType": "bigint", + "argumentTypes": [], + "variableArity": false + } + }, + "masks": {}, + "groupingSets": [ + [] + ], + "step": "FINAL", + "hashSymbol": null, + "groupIdSymbol": null, + "label": "" + }, + "columns": ["count(*)"], + "outputs": ["count"], + "label": "" + }, + "symbols": { + "count_0_3": "bigint", + "count": "bigint" + }, + "partitioning": { + "connectorId": null, + "transactionHandle": null, + "connectorHandle": { + "@type": "$remote", + "partitioning": "SINGLE", + "function": "SINGLE" + } + }, + "partitionedSources": [], + "partitioningScheme": { + "partitioning": { + "handle": { + "connectorId": null, + "transactionHandle": null, + "connectorHandle": { + "@type": "$remote", + "partitioning": "SINGLE", + "function": "SINGLE" + } + }, + "arguments": [] + }, + "outputLayout": ["count"], + "hashColumn": null, + "replicateNulls": false, + "bucketToPartition": [0] + } + }, + "types": ["bigint"], + "stageStats": { + "schedulingComplete": "2018-10-24T04:05:07.564Z", + "totalTasks": 1, + "runningTasks": 0, + "completedTasks": 1, + "totalDrivers": 17, + "queuedDrivers": 0, + "runningDrivers": 0, + "completedDrivers": 17, + "cumulativeMemory": 0.0, + "totalMemoryReservation": "0B", + "peakMemoryReservation": "0B", + "totalScheduledTime": "0.00ns", + "totalCpuTime": "2.58s", + "totalUserTime": "0.00ns", + "totalBlockedTime": "0.00ns", + "fullyBlocked": false, + "blockedReasons": [], + "rawInputDataSize": "93B", + "rawInputPositions": 3, + "processedInputDataSize": "27B", + "processedInputPositions": 3, + "outputDataSize": "9B", + "outputPositions": 1, + "totalTableScanDataSize": 0, + "tableScanPosition": 0 + }, + "tasks": [{ + "taskStatus": { + "taskId": "20181024_040507_3_f32vb.0.0", + "taskInstanceId": "a1948577-62db-4a56-bb36-ab6b1d5d0853", + "version": 26, + "state": "FINISHED", + "self": "http://172.17.246.56:14005/v1/task/20181024_040507_3_f32vb.0.0?shufferNettyServerPort=39524&commandNettyServerPort=37207", + "failures": [], + "queuedPartitionedDrivers": 0, + "runningPartitionedDrivers": 0, + "needLoop": false, + "memoryReservation": "0B" + }, + "lastHeartbeat": "2018-10-24T04:05:08.885Z", + "outputBuffers": { + "type": "PARTITIONED", + "state": "FINISHED", + "canAddBuffers": false, + "canAddPages": false, + "totalBufferedBytes": 0, + "totalBufferedPages": 0, + "totalRowsSent": 1, + "totalPagesSent": 1, + "buffers": [] + }, + "noMoreSplits": ["16"], + "stats": { + "createTime": "2018-10-24T04:05:07.557Z", + "firstStartTime": "2018-10-24T04:05:07.859Z", + "lastStartTime": "2018-10-24T04:05:07.863Z", + "lastEndTime": "2018-10-24T04:05:08.867Z", + "endTime": "2018-10-24T04:05:08.889Z", + "elapsedTime": 1031, + "queuedTime": 31, + "totalDrivers": 17, + "queuedDrivers": 0, + "queuedPartitionedDrivers": 0, + "runningDrivers": 0, + "runningPartitionedDrivers": 0, + "completedDrivers": 17, + "cumulativeMemory": 0.0, + "memoryReservation": "0B", + "systemMemoryReservation": "0B", + "totalScheduledTime": 0, + "totalCpuTime": 2584, + "totalUserTime": 0, + "totalBlockedTime": 0, + "fullyBlocked": false, + "blockedReasons": [], + "rawInputDataSize": "93B", + "rawInputPositions": 3, + "processedInputDataSize": "27B", + "processedInputPositions": 3, + "outputDataSize": "9B", + "outputPositions": 1, + "tableScanDataSize": 0, + "tableScanTimeCost": "0.00ms", + "tableScanPosition": 0 + }, + "needsPlan": false, + "complete": true, + "completedDrivers": 17, + "totalDrivers": 17, + "cumulativeMemory": 0.0, + "memoryReservation": 0, + "elapsedTime": 1031, + "totalCpuTime": 0 + }], + "subStages": [{ + "stageId": "20181024_040507_3_f32vb.1", + "state": "FINISHED", + "self": "http://172.17.246.55:10001/v1/stage/20181024_040507_3_f32vb.1", + "plan": { + "id": "1", + "root": { + "@type": "aggregation", + "id": "15", + "source": { + "@type": "tablescan", + "id": "0", + "table": { + "connectorId": "hive", + "connectorHandle": { + "@type": "hive-hadoop2", + "clientId": "hive", + "schemaName": "oa1013022312866336_tpch_100m_text", + "tableName": "lineitem" + } + }, + "outputSymbols": [], + "assignments": {}, + "layout": { + "connectorId": "hive", + "transactionHandle": { + "@type": "hive-hadoop2", + "uuid": "ee8f6b43-d456-4bba-907b-941a5c87da1b" + }, + "connectorHandle": { + "@type": "hive-hadoop2", + "clientId": "hive", + "partitionColumns": [], + "promisedPredicate": { + "columnDomains": null + }, + "bucketHandle": null, + "tupleDomain": null, + "remainPredicate": [] + } + }, + "currentConstraint": { + "columnDomains": [] + }, + "originalConstraint": "true", + "label": "hive:hive:oa1013022312866336_tpch_100m_text:lineitem true" + }, + "aggregations": { + "count_0_3": "\"count\"(*)" + }, + "functions": { + "count_0_3": { + "name": "count", + "kind": "AGGREGATE", + "typeVariableConstraints": [], + "longVariableConstraints": [], + "returnType": "bigint", + "argumentTypes": [], + "variableArity": false + } + }, + "masks": {}, + "groupingSets": [ + [] + ], + "step": "PARTIAL", + "hashSymbol": null, + "groupIdSymbol": null, + "label": "" + }, + "symbols": { + "count_0_3": "bigint" + }, + "partitioning": { + "connectorId": null, + "transactionHandle": null, + "connectorHandle": { + "@type": "$remote", + "partitioning": "SOURCE", + "function": "UNKNOWN" + } + }, + "partitionedSources": ["0"], + "partitioningScheme": { + "partitioning": { + "handle": { + "connectorId": null, + "transactionHandle": null, + "connectorHandle": { + "@type": "$remote", + "partitioning": "SINGLE", + "function": "SINGLE" + } + }, + "arguments": [] + }, + "outputLayout": ["count_0_3"], + "hashColumn": null, + "replicateNulls": false, + "bucketToPartition": [0] + } + }, + "types": ["bigint"], + "stageStats": { + "schedulingComplete": "2018-10-24T04:05:07.664Z", + "totalTasks": 2, + "runningTasks": 0, + "completedTasks": 2, + "totalDrivers": 3, + "queuedDrivers": 0, + "runningDrivers": 0, + "completedDrivers": 3, + "cumulativeMemory": 0.0, + "totalMemoryReservation": "0B", + "peakMemoryReservation": "0B", + "totalScheduledTime": "0.00ns", + "totalCpuTime": "2.58s", + "totalUserTime": "0.00ns", + "totalBlockedTime": "0.00ns", + "fullyBlocked": false, + "blockedReasons": [], + "rawInputDataSize": "70.81MB", + "rawInputPositions": 600572, + "processedInputDataSize": "0B", + "processedInputPositions": 600572, + "outputDataSize": "27B", + "outputPositions": 3, + "totalTableScanDataSize": 74246996, + "tableScanPosition": 600572 + }, + "tasks": [{ + "taskStatus": { + "taskId": "20181024_040507_3_f32vb.1.0", + "taskInstanceId": "34d2e099-c622-4768-83ad-3443dcb9cde6", + "version": 25, + "state": "FINISHED", + "self": "http://172.17.246.55:14005/v1/task/20181024_040507_3_f32vb.1.0?shufferNettyServerPort=33921&commandNettyServerPort=45121", + "failures": [], + "queuedPartitionedDrivers": 0, + "runningPartitionedDrivers": 0, + "needLoop": false, + "memoryReservation": "0B" + }, + "lastHeartbeat": "2018-10-24T04:05:08.817Z", + "outputBuffers": { + "type": "PARTITIONED", + "state": "FINISHED", + "canAddBuffers": false, + "canAddPages": false, + "totalBufferedBytes": 0, + "totalBufferedPages": 0, + "totalRowsSent": 1, + "totalPagesSent": 1, + "buffers": [] + }, + "noMoreSplits": ["0"], + "stats": { + "createTime": "2018-10-24T04:05:07.662Z", + "firstStartTime": "2018-10-24T04:05:07.832Z", + "lastStartTime": "2018-10-24T04:05:07.832Z", + "lastEndTime": "2018-10-24T04:05:08.711Z", + "endTime": "2018-10-24T04:05:08.836Z", + "elapsedTime": 1005, + "queuedTime": 3, + "totalDrivers": 1, + "queuedDrivers": 0, + "queuedPartitionedDrivers": 0, + "runningDrivers": 0, + "runningPartitionedDrivers": 0, + "completedDrivers": 1, + "cumulativeMemory": 0.0, + "memoryReservation": "0B", + "systemMemoryReservation": "0B", + "totalScheduledTime": 0, + "totalCpuTime": 879, + "totalUserTime": 0, + "totalBlockedTime": 0, + "fullyBlocked": false, + "blockedReasons": [], + "rawInputDataSize": "32MB", + "rawInputPositions": 271878, + "processedInputDataSize": "0B", + "processedInputPositions": 271878, + "outputDataSize": "9B", + "outputPositions": 1, + "tableScanDataSize": 33554432, + "tableScanTimeCost": "2.00ms", + "tableScanPosition": 271878 + }, + "needsPlan": false, + "complete": true, + "completedDrivers": 1, + "totalDrivers": 1, + "cumulativeMemory": 0.0, + "memoryReservation": 0, + "elapsedTime": 1005, + "totalCpuTime": 0 + }, { + "taskStatus": { + "taskId": "20181024_040507_3_f32vb.1.1", + "taskInstanceId": "74fe82fd-f59d-4f39-b7b7-5399c769b1e8", + "version": 25, + "state": "FINISHED", + "self": "http://172.17.246.56:14005/v1/task/20181024_040507_3_f32vb.1.1?shufferNettyServerPort=39524&commandNettyServerPort=37207", + "failures": [], + "queuedPartitionedDrivers": 0, + "runningPartitionedDrivers": 0, + "needLoop": false, + "memoryReservation": "0B" + }, + "lastHeartbeat": "2018-10-24T04:05:08.814Z", + "outputBuffers": { + "type": "PARTITIONED", + "state": "FINISHED", + "canAddBuffers": false, + "canAddPages": false, + "totalBufferedBytes": 0, + "totalBufferedPages": 0, + "totalRowsSent": 2, + "totalPagesSent": 2, + "buffers": [] + }, + "noMoreSplits": ["0"], + "stats": { + "createTime": "2018-10-24T04:05:07.665Z", + "firstStartTime": "2018-10-24T04:05:07.834Z", + "lastStartTime": "2018-10-24T04:05:07.834Z", + "lastEndTime": "2018-10-24T04:05:08.779Z", + "endTime": "2018-10-24T04:05:08.845Z", + "elapsedTime": 1011, + "queuedTime": 6, + "totalDrivers": 2, + "queuedDrivers": 0, + "queuedPartitionedDrivers": 0, + "runningDrivers": 0, + "runningPartitionedDrivers": 0, + "completedDrivers": 2, + "cumulativeMemory": 0.0, + "memoryReservation": "0B", + "systemMemoryReservation": "0B", + "totalScheduledTime": 0, + "totalCpuTime": 1700, + "totalUserTime": 0, + "totalBlockedTime": 0, + "fullyBlocked": false, + "blockedReasons": [], + "rawInputDataSize": "38.81MB", + "rawInputPositions": 328694, + "processedInputDataSize": "0B", + "processedInputPositions": 328694, + "outputDataSize": "18B", + "outputPositions": 2, + "tableScanDataSize": 40692564, + "tableScanTimeCost": "4.00ms", + "tableScanPosition": 328694 + }, + "needsPlan": false, + "complete": true, + "completedDrivers": 2, + "totalDrivers": 2, + "cumulativeMemory": 0.0, + "memoryReservation": 0, + "elapsedTime": 1011, + "totalCpuTime": 0 + }], + "subStages": [] + }] + }, + "inputs": [{ + "connectorId": "hive", + "schema": "oa1013022312866336_tpch_100m_text", + "table": "lineitem", + "connectorInfo": { + "partitionIds": [""] + }, + "columns": [] + }], + "output": null, + "resourceGroupName": null, + "finalQueryInfo": true +} \ No newline at end of file diff --git a/src/test/resources/kotlin/DataClassPropsGeneric.clazz b/src/test/resources/kotlin/DataClassPropsGeneric.clazz new file mode 100644 index 0000000000..10cc815bcd Binary files /dev/null and b/src/test/resources/kotlin/DataClassPropsGeneric.clazz differ diff --git a/src/test/resources/kotlin/Issue1750_ProcessBO.clazz b/src/test/resources/kotlin/Issue1750_ProcessBO.clazz new file mode 100644 index 0000000000..473516dc98 Binary files /dev/null and b/src/test/resources/kotlin/Issue1750_ProcessBO.clazz differ diff --git a/src/test/resources/kotlin/ProjectItemCheckItemRelation1.clazz b/src/test/resources/kotlin/ProjectItemCheckItemRelation1.clazz new file mode 100644 index 0000000000..4a239a0868 Binary files /dev/null and b/src/test/resources/kotlin/ProjectItemCheckItemRelation1.clazz differ diff --git a/src/test/resources/kotlin/zuojing/NoticeData.clazz b/src/test/resources/kotlin/zuojing/NoticeData.clazz new file mode 100644 index 0000000000..ee4333f483 Binary files /dev/null and b/src/test/resources/kotlin/zuojing/NoticeData.clazz differ diff --git a/src/test/resources/kotlin/zuojing/NoticeDataKt.clazz b/src/test/resources/kotlin/zuojing/NoticeDataKt.clazz new file mode 100644 index 0000000000..5c00e54266 Binary files /dev/null and b/src/test/resources/kotlin/zuojing/NoticeDataKt.clazz differ diff --git a/src/test/resources/kotlin/zuojing/NoticeData_Companion.clazz b/src/test/resources/kotlin/zuojing/NoticeData_Companion.clazz new file mode 100644 index 0000000000..160844fdd8 Binary files /dev/null and b/src/test/resources/kotlin/zuojing/NoticeData_Companion.clazz differ diff --git a/vtune.sh b/vtune.sh index 6ea5ae707c..04d506f8bb 100755 --- a/vtune.sh +++ b/vtune.sh @@ -1,2 +1,2 @@ export AMPLXE_EXPERIMENTAL=1 -/opt/intel/vtune_amplifier_xe/bin64/amplxe-cl -collect hotspots java -classpath target/classes/:target/test-classes/ com.alibaba.json.test.benchmark.BenchmarkMain +/Users/wenshao/Install/vtune/amplxe-cl -collect hotspots java -classpath target/classes/:target/test-classes/ com.alibaba.json.test.benchmark.BenchmarkMain