├── .github ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── BUG.md │ └── FEATURE.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml ├── no-response.yml └── workflows │ ├── build.yaml │ ├── release-pull-request.yaml │ └── release.yaml ├── .gitignore ├── .mailmap ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ └── maven-wrapper.properties ├── .zappr.yaml ├── BUILD.md ├── CHANGELOG.md ├── LICENSE ├── MAINTAINERS ├── MONEY.md ├── README.md ├── SECURITY.md ├── cve-suppressions.xml ├── mvnw ├── mvnw.cmd ├── pom.xml ├── release.sh └── src ├── main ├── java │ └── org │ │ └── zalando │ │ └── jackson │ │ └── datatype │ │ └── money │ │ ├── AmountWriter.java │ │ ├── BigDecimalAmountWriter.java │ │ ├── CurrencyUnitDeserializer.java │ │ ├── CurrencyUnitSerializer.java │ │ ├── DecimalAmountWriter.java │ │ ├── FieldNames.java │ │ ├── MonetaryAmountDeserializer.java │ │ ├── MonetaryAmountFactory.java │ │ ├── MonetaryAmountFormatFactory.java │ │ ├── MonetaryAmountSerializer.java │ │ ├── MoneyModule.java │ │ ├── QuotedDecimalAmountWriter.java │ │ └── package-info.java └── resources │ └── META-INF │ └── services │ └── com.fasterxml.jackson.databind.Module └── test └── java └── org └── zalando └── jackson └── datatype └── money ├── CurrencyUnitDeserializerTest.java ├── CurrencyUnitSchemaSerializerTest.java ├── CurrencyUnitSerializerTest.java ├── FieldNamesTest.java ├── MonetaryAmountDeserializerTest.java ├── MonetaryAmountSchemaSerializerTest.java ├── MonetaryAmountSerializerTest.java └── SchemaTestClass.java /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @whiskeysierra @lukasniemeier-zalando 2 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | education, socio-economic status, nationality, personal appearance, race, 10 | religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at team-balance [at] zalando [dot] de. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Pull requests only 4 | 5 | **DON'T** push to the main branch directly. Always use feature branches and let people discuss changes in pull requests. 6 | Pull requests should only be merged after all discussions have been concluded and at least 1 reviewer has given their 7 | **approval**. 8 | 9 | ## Guidelines 10 | 11 | - **every change** needs a test 12 | - 100% code coverage 13 | - keep the current code style 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41EBug report" 3 | about: Create a report to help us improve 4 | labels: Bug 5 | --- 6 | 7 | 8 | 9 | ## Description 10 | 11 | 12 | ## Expected Behavior 13 | 14 | 15 | ## Actual Behavior 16 | 17 | 18 | ## Possible Fix 19 | 20 | 21 | ## Steps to Reproduce 22 | 23 | 24 | 1. 25 | 2. 26 | 3. 27 | 4. 28 | 29 | ## Context 30 | 31 | 32 | ## Your Environment 33 | 34 | * Version used: 35 | * Link to your project: 36 | 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 Feature request" 3 | about: Suggest an idea for this project 4 | labels: Feature 5 | --- 6 | 7 | 8 | 9 | ## Detailed Description 10 | 11 | 12 | ## Context 13 | 14 | 15 | 16 | ## Possible Implementation 17 | 18 | 19 | ## Your Environment 20 | 21 | * Version used: 22 | * Link to your project: 23 | 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | ## Motivation and Context 7 | 8 | 9 | 10 | ## Types of changes 11 | 12 | - [ ] Bug fix (non-breaking change which fixes an issue) 13 | - [ ] New feature (non-breaking change which adds functionality) 14 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 15 | 16 | ## Checklist: 17 | 18 | 19 | - [ ] My change requires a change to the documentation. 20 | - [ ] I have updated the documentation accordingly. 21 | - [ ] I have added tests to cover my changes. 22 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: org.basepom.maven:duplicate-finder-maven-plugin 11 | versions: 12 | - "< 1.4, >= 1.3.0.a" 13 | - dependency-name: org.owasp:dependency-check-maven 14 | versions: 15 | - 6.1.0 16 | - 6.1.2 17 | -------------------------------------------------------------------------------- /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-no-response - https://github.com/probot/no-response 2 | 3 | responseRequiredLabel: More information needed 4 | 5 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | schedule: 11 | - cron: "0 6 * * *" 12 | 13 | env: 14 | # https://github.com/actions/virtual-environments/issues/1499#issuecomment-689467080 15 | MAVEN_OPTS: >- 16 | -Dhttp.keepAlive=false 17 | -Dmaven.wagon.http.pool=false 18 | -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 19 | 20 | jobs: 21 | build: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v1 26 | - name: Cache 27 | uses: actions/cache@v1 28 | with: 29 | path: ~/.m2 30 | key: m2 31 | - name: Set up JDK 32 | uses: actions/setup-java@v1 33 | with: 34 | java-version: 1.8 35 | - name: Compile 36 | run: ./mvnw clean test-compile -B 37 | - name: Test 38 | run: ./mvnw verify -B 39 | - name: Coverage 40 | if: github.event_name != 'pull_request' 41 | run: ./mvnw coveralls:report -B -D repoToken=${{ secrets.COVERALLS_TOKEN }} 42 | -------------------------------------------------------------------------------- /.github/workflows/release-pull-request.yaml: -------------------------------------------------------------------------------- 1 | name: Release Pull Request 2 | 3 | on: 4 | push: 5 | branches: 6 | - release/* 7 | 8 | jobs: 9 | pull-request: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: pull-request-action 13 | uses: vsoch/pull-request-action@master 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | PULL_REQUEST_TITLE: Release ${{ github.ref }} 17 | PULL_REQUEST_BODY: Bump version 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Create Release 13 | uses: actions/create-release@v1 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | with: 17 | tag_name: ${{ github.ref }} 18 | release_name: ${{ github.ref }} 19 | draft: false 20 | prerelease: ${{ contains(github.ref, 'RC') }} 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### IntelliJ ### 2 | *.iml 3 | .idea/ 4 | 5 | ### Maven ### 6 | target/ 7 | /.mvn/wrapper/*.jar 8 | 9 | *.log 10 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Willi Schönborn -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /.zappr.yaml: -------------------------------------------------------------------------------- 1 | approvals: 2 | pattern: "^(:\\+1:|👍|\\+1|:thumbsup:|[Ll][Gg][Tt][Mm])$" 3 | minimum: 1 4 | from: 5 | orgs: 6 | - zalando 7 | collaborators: true 8 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | # Build 2 | 3 | ## Dependencies 4 | 5 | - [jEnv](http://www.jenv.be/) 6 | - OpenJDK 1.7 7 | - OpenJDK 1.8 8 | 9 | ## Run tests 10 | 11 | ./test.sh 12 | 13 | ## Release 14 | 15 | ./release.sh 16 | 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [Unreleased](https://github.com/zalando/jackson-datatype-money/tree/HEAD) 4 | 5 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.3.0...HEAD) 6 | 7 | **Merged pull requests:** 8 | 9 | - Fixed Serialization of amount-field when using WRAP\_ROOT\_VALUE [\#332](https://github.com/zalando/jackson-datatype-money/pull/332) ([happyherp](https://github.com/happyherp)) 10 | - Bump dependency-check-maven from 6.3.2 to 6.5.0 [\#331](https://github.com/zalando/jackson-datatype-money/pull/331) ([dependabot[bot]](https://github.com/apps/dependabot)) 11 | - Bump mockito-core from 3.12.4 to 4.0.0 [\#329](https://github.com/zalando/jackson-datatype-money/pull/329) ([dependabot[bot]](https://github.com/apps/dependabot)) 12 | - Bump lombok from 1.18.20 to 1.18.22 [\#328](https://github.com/zalando/jackson-datatype-money/pull/328) ([dependabot[bot]](https://github.com/apps/dependabot)) 13 | - Bump jackson.version from 2.12.5 to 2.13.0 [\#327](https://github.com/zalando/jackson-datatype-money/pull/327) ([dependabot[bot]](https://github.com/apps/dependabot)) 14 | - Bump dependency-check-maven from 6.3.1 to 6.3.2 [\#326](https://github.com/zalando/jackson-datatype-money/pull/326) ([dependabot[bot]](https://github.com/apps/dependabot)) 15 | - Bump junit-jupiter.version from 5.7.2 to 5.8.1 [\#325](https://github.com/zalando/jackson-datatype-money/pull/325) ([dependabot[bot]](https://github.com/apps/dependabot)) 16 | - Bump assertj-core from 3.20.2 to 3.21.0 [\#324](https://github.com/zalando/jackson-datatype-money/pull/324) ([dependabot[bot]](https://github.com/apps/dependabot)) 17 | - Bump maven-javadoc-plugin from 3.3.0 to 3.3.1 [\#322](https://github.com/zalando/jackson-datatype-money/pull/322) ([dependabot[bot]](https://github.com/apps/dependabot)) 18 | - Bump dependency-check-maven from 6.2.2 to 6.3.1 [\#321](https://github.com/zalando/jackson-datatype-money/pull/321) ([dependabot[bot]](https://github.com/apps/dependabot)) 19 | - Bump jackson.version from 2.12.3 to 2.12.5 [\#319](https://github.com/zalando/jackson-datatype-money/pull/319) ([dependabot[bot]](https://github.com/apps/dependabot)) 20 | - Bump mockito-core from 3.11.2 to 3.12.4 [\#318](https://github.com/zalando/jackson-datatype-money/pull/318) ([dependabot[bot]](https://github.com/apps/dependabot)) 21 | - Bump maven-enforcer-plugin from 3.0.0-M3 to 3.0.0 [\#313](https://github.com/zalando/jackson-datatype-money/pull/313) ([dependabot[bot]](https://github.com/apps/dependabot)) 22 | - Bump slf4j.version from 1.7.31 to 1.7.32 [\#312](https://github.com/zalando/jackson-datatype-money/pull/312) ([dependabot[bot]](https://github.com/apps/dependabot)) 23 | - Bump apiguardian-api from 1.1.1 to 1.1.2 [\#310](https://github.com/zalando/jackson-datatype-money/pull/310) ([dependabot[bot]](https://github.com/apps/dependabot)) 24 | - Bump mockito-core from 3.11.1 to 3.11.2 [\#309](https://github.com/zalando/jackson-datatype-money/pull/309) ([dependabot[bot]](https://github.com/apps/dependabot)) 25 | - Bump assertj-core from 3.20.1 to 3.20.2 [\#308](https://github.com/zalando/jackson-datatype-money/pull/308) ([dependabot[bot]](https://github.com/apps/dependabot)) 26 | - Bump slf4j.version from 1.7.30 to 1.7.31 [\#307](https://github.com/zalando/jackson-datatype-money/pull/307) ([dependabot[bot]](https://github.com/apps/dependabot)) 27 | - Bump assertj-core from 3.20.0 to 3.20.1 [\#306](https://github.com/zalando/jackson-datatype-money/pull/306) ([dependabot[bot]](https://github.com/apps/dependabot)) 28 | - Bump assertj-core from 3.19.0 to 3.20.0 [\#305](https://github.com/zalando/jackson-datatype-money/pull/305) ([dependabot[bot]](https://github.com/apps/dependabot)) 29 | - Bump mockito-core from 3.10.0 to 3.11.1 [\#304](https://github.com/zalando/jackson-datatype-money/pull/304) ([dependabot[bot]](https://github.com/apps/dependabot)) 30 | - Bump dependency-check-maven from 6.2.0 to 6.2.2 [\#303](https://github.com/zalando/jackson-datatype-money/pull/303) ([dependabot[bot]](https://github.com/apps/dependabot)) 31 | - Bump dependency-check-maven from 6.1.6 to 6.2.0 [\#299](https://github.com/zalando/jackson-datatype-money/pull/299) ([dependabot[bot]](https://github.com/apps/dependabot)) 32 | - Bump maven-javadoc-plugin from 3.2.0 to 3.3.0 [\#298](https://github.com/zalando/jackson-datatype-money/pull/298) ([dependabot[bot]](https://github.com/apps/dependabot)) 33 | - Updated Maven to version 3.8.1 [\#297](https://github.com/zalando/jackson-datatype-money/pull/297) ([whiskeysierra](https://github.com/whiskeysierra)) 34 | - Bump junit-jupiter.version from 5.7.1 to 5.7.2 [\#296](https://github.com/zalando/jackson-datatype-money/pull/296) ([dependabot[bot]](https://github.com/apps/dependabot)) 35 | - Bump mockito-core from 3.9.0 to 3.10.0 [\#295](https://github.com/zalando/jackson-datatype-money/pull/295) ([dependabot[bot]](https://github.com/apps/dependabot)) 36 | - Bump maven-gpg-plugin from 1.6 to 3.0.1 [\#294](https://github.com/zalando/jackson-datatype-money/pull/294) ([dependabot[bot]](https://github.com/apps/dependabot)) 37 | - Bump jacoco-maven-plugin from 0.8.6 to 0.8.7 [\#293](https://github.com/zalando/jackson-datatype-money/pull/293) ([dependabot[bot]](https://github.com/apps/dependabot)) 38 | - Bump dependency-check-maven from 6.1.5 to 6.1.6 [\#292](https://github.com/zalando/jackson-datatype-money/pull/292) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 39 | - Upgrade to GitHub-native Dependabot [\#291](https://github.com/zalando/jackson-datatype-money/pull/291) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 40 | - Bump jackson.version from 2.12.2 to 2.12.3 [\#289](https://github.com/zalando/jackson-datatype-money/pull/289) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 41 | - Bump mockito-core from 3.8.0 to 3.9.0 [\#288](https://github.com/zalando/jackson-datatype-money/pull/288) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 42 | - Bump lombok from 1.18.18 to 1.18.20 [\#287](https://github.com/zalando/jackson-datatype-money/pull/287) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 43 | - Bump dependency-check-maven from 6.1.4 to 6.1.5 [\#286](https://github.com/zalando/jackson-datatype-money/pull/286) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 44 | - Bump dependency-check-maven from 6.1.3 to 6.1.4 [\#285](https://github.com/zalando/jackson-datatype-money/pull/285) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 45 | - Release/1.2.2 [\#284](https://github.com/zalando/jackson-datatype-money/pull/284) ([whiskeysierra](https://github.com/whiskeysierra)) 46 | - Ensure that currency is always serialized with the proper serializer [\#283](https://github.com/zalando/jackson-datatype-money/pull/283) ([geoand](https://github.com/geoand)) 47 | - Bump dependency-check-maven from 6.1.1 to 6.1.3 [\#282](https://github.com/zalando/jackson-datatype-money/pull/282) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 48 | - Bump jackson.version from 2.12.1 to 2.12.2 [\#280](https://github.com/zalando/jackson-datatype-money/pull/280) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 49 | - Bump mockito-core from 3.7.7 to 3.8.0 [\#279](https://github.com/zalando/jackson-datatype-money/pull/279) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 50 | - Bump dependency-check-maven from 6.0.5 to 6.1.1 [\#278](https://github.com/zalando/jackson-datatype-money/pull/278) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 51 | - Bump junit-jupiter.version from 5.7.0 to 5.7.1 [\#277](https://github.com/zalando/jackson-datatype-money/pull/277) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 52 | - Bump lombok from 1.18.16 to 1.18.18 [\#276](https://github.com/zalando/jackson-datatype-money/pull/276) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 53 | - Bump assertj-core from 3.18.1 to 3.19.0 [\#274](https://github.com/zalando/jackson-datatype-money/pull/274) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 54 | - Bump mockito-core from 3.7.0 to 3.7.7 [\#273](https://github.com/zalando/jackson-datatype-money/pull/273) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 55 | - Bump jackson.version from 2.12.0 to 2.12.1 [\#272](https://github.com/zalando/jackson-datatype-money/pull/272) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 56 | - Bump dependency-check-maven from 6.0.4 to 6.0.5 [\#271](https://github.com/zalando/jackson-datatype-money/pull/271) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 57 | - Bump mockito-core from 3.6.28 to 3.7.0 [\#270](https://github.com/zalando/jackson-datatype-money/pull/270) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 58 | - Bump dependency-check-maven from 6.0.3 to 6.0.4 [\#269](https://github.com/zalando/jackson-datatype-money/pull/269) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 59 | - Bump apiguardian-api from 1.1.0 to 1.1.1 [\#268](https://github.com/zalando/jackson-datatype-money/pull/268) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 60 | - Configured maven to avoid Connection Reset issues [\#267](https://github.com/zalando/jackson-datatype-money/pull/267) ([whiskeysierra](https://github.com/whiskeysierra)) 61 | - Bump jackson.version from 2.11.3 to 2.12.0 [\#266](https://github.com/zalando/jackson-datatype-money/pull/266) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 62 | - Bump mockito-core from 3.6.0 to 3.6.28 [\#265](https://github.com/zalando/jackson-datatype-money/pull/265) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 63 | - Bump assertj-core from 3.18.0 to 3.18.1 [\#264](https://github.com/zalando/jackson-datatype-money/pull/264) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 64 | - Bump dependency-check-maven from 6.0.2 to 6.0.3 [\#263](https://github.com/zalando/jackson-datatype-money/pull/263) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 65 | - Release/1.2.1 [\#262](https://github.com/zalando/jackson-datatype-money/pull/262) ([whiskeysierra](https://github.com/whiskeysierra)) 66 | 67 | ## [1.3.0](https://github.com/zalando/jackson-datatype-money/tree/1.3.0) (2021-11-15) 68 | 69 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.2.2...1.3.0) 70 | 71 | **Closed issues:** 72 | 73 | - Integration with JSR-303 and Spring Validation [\#301](https://github.com/zalando/jackson-datatype-money/issues/301) 74 | 75 | ## [1.2.2](https://github.com/zalando/jackson-datatype-money/tree/1.2.2) (2021-03-29) 76 | 77 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.2.1...1.2.2) 78 | 79 | ## [1.2.1](https://github.com/zalando/jackson-datatype-money/tree/1.2.1) (2020-10-29) 80 | 81 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.2.0...1.2.1) 82 | 83 | **Fixed bugs:** 84 | 85 | - Failed to get nested archive for entry BOOT-INF/lib/moneta-1.4.2.pom after upgrading to 1.2.0 [\#260](https://github.com/zalando/jackson-datatype-money/issues/260) 86 | - can I provide a custom MonetaryAmountDeserializer? [\#257](https://github.com/zalando/jackson-datatype-money/issues/257) 87 | 88 | **Closed issues:** 89 | 90 | - MoneyModule seems configured but Jackson not deserializing [\#246](https://github.com/zalando/jackson-datatype-money/issues/246) 91 | - When can we expect 1.1.2? [\#226](https://github.com/zalando/jackson-datatype-money/issues/226) 92 | - Version 1.1.1 in Maven central is using NumberValue not BigDecimal [\#221](https://github.com/zalando/jackson-datatype-money/issues/221) 93 | 94 | **Merged pull requests:** 95 | 96 | - Fixed incorrect moneta dependency [\#261](https://github.com/zalando/jackson-datatype-money/pull/261) ([whiskeysierra](https://github.com/whiskeysierra)) 97 | - Bump mockito-core from 3.5.15 to 3.6.0 [\#259](https://github.com/zalando/jackson-datatype-money/pull/259) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 98 | - Bump assertj-core from 3.17.2 to 3.18.0 [\#258](https://github.com/zalando/jackson-datatype-money/pull/258) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 99 | - Made coverage step not running for PRs [\#256](https://github.com/zalando/jackson-datatype-money/pull/256) ([whiskeysierra](https://github.com/whiskeysierra)) 100 | - Unifies SECURITY.md to point to the Zalando security form [\#255](https://github.com/zalando/jackson-datatype-money/pull/255) ([bocytko](https://github.com/bocytko)) 101 | - Bump mockito-core from 3.5.13 to 3.5.15 [\#254](https://github.com/zalando/jackson-datatype-money/pull/254) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 102 | - Bump lombok from 1.18.14 to 1.18.16 [\#253](https://github.com/zalando/jackson-datatype-money/pull/253) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 103 | - Replaced Hamcrest with AssertJ [\#252](https://github.com/zalando/jackson-datatype-money/pull/252) ([whiskeysierra](https://github.com/whiskeysierra)) 104 | - Bump lombok from 1.18.12 to 1.18.14 [\#251](https://github.com/zalando/jackson-datatype-money/pull/251) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 105 | - Bump jackson.version from 2.11.2 to 2.11.3 [\#250](https://github.com/zalando/jackson-datatype-money/pull/250) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 106 | - Bump dependency-check-maven from 6.0.1 to 6.0.2 [\#249](https://github.com/zalando/jackson-datatype-money/pull/249) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 107 | - Bump mockito-core from 3.5.11 to 3.5.13 [\#248](https://github.com/zalando/jackson-datatype-money/pull/248) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 108 | - Enabled no-response bot [\#247](https://github.com/zalando/jackson-datatype-money/pull/247) ([whiskeysierra](https://github.com/whiskeysierra)) 109 | - Bump mockito-core from 3.5.10 to 3.5.11 [\#245](https://github.com/zalando/jackson-datatype-money/pull/245) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 110 | - Bump jacoco-maven-plugin from 0.8.5 to 0.8.6 [\#244](https://github.com/zalando/jackson-datatype-money/pull/244) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 111 | - Bump junit-jupiter.version from 5.6.2 to 5.7.0 [\#243](https://github.com/zalando/jackson-datatype-money/pull/243) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 112 | - Bump dependency-check-maven from 6.0.0 to 6.0.1 [\#242](https://github.com/zalando/jackson-datatype-money/pull/242) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 113 | - Bump duplicate-finder-maven-plugin from 1.4.0 to 1.5.0 [\#241](https://github.com/zalando/jackson-datatype-money/pull/241) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 114 | - Bump dependency-check-maven from 5.3.2 to 6.0.0 [\#240](https://github.com/zalando/jackson-datatype-money/pull/240) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 115 | - Bump mockito-core from 3.5.2 to 3.5.10 [\#239](https://github.com/zalando/jackson-datatype-money/pull/239) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 116 | - Bump mockito-core from 3.5.0 to 3.5.2 [\#234](https://github.com/zalando/jackson-datatype-money/pull/234) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 117 | - Bump mockito-core from 3.4.6 to 3.5.0 [\#233](https://github.com/zalando/jackson-datatype-money/pull/233) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 118 | - Bump maven-resources-plugin from 3.1.0 to 3.2.0 [\#232](https://github.com/zalando/jackson-datatype-money/pull/232) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 119 | - Bump versions-maven-plugin from 2.7 to 2.8.1 [\#230](https://github.com/zalando/jackson-datatype-money/pull/230) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 120 | - Bump jackson.version from 2.11.1 to 2.11.2 [\#229](https://github.com/zalando/jackson-datatype-money/pull/229) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 121 | - Bump mockito-core from 3.4.4 to 3.4.6 [\#228](https://github.com/zalando/jackson-datatype-money/pull/228) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 122 | - Release refs/heads/release/1.2.0 [\#227](https://github.com/zalando/jackson-datatype-money/pull/227) ([github-actions[bot]](https://github.com/apps/github-actions)) 123 | 124 | ## [1.2.0](https://github.com/zalando/jackson-datatype-money/tree/1.2.0) (2020-07-29) 125 | 126 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.1.1...1.2.0) 127 | 128 | **Fixed bugs:** 129 | 130 | - CNH currency is not being deserialized [\#213](https://github.com/zalando/jackson-datatype-money/issues/213) 131 | 132 | **Security fixes:** 133 | 134 | - \[Security\] Bump jackson.version from 2.9.9 to 2.10.0.pr1 [\#169](https://github.com/zalando/jackson-datatype-money/pull/169) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 135 | 136 | **Merged pull requests:** 137 | 138 | - Bump moneta from 1.4.1 to 1.4.2 [\#225](https://github.com/zalando/jackson-datatype-money/pull/225) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 139 | - Bump moneta from 1.3 to 1.4.1 [\#223](https://github.com/zalando/jackson-datatype-money/pull/223) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 140 | - Bump mockito-core from 3.3.3 to 3.4.4 [\#222](https://github.com/zalando/jackson-datatype-money/pull/222) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 141 | - Bump jackson.version from 2.10.3 to 2.11.1 [\#219](https://github.com/zalando/jackson-datatype-money/pull/219) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 142 | - Bump money-api from 1.0.3 to 1.1 [\#217](https://github.com/zalando/jackson-datatype-money/pull/217) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 143 | - Bump mbknor-jackson-jsonschema\_2.12 from 1.0.38 to 1.0.39 [\#215](https://github.com/zalando/jackson-datatype-money/pull/215) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 144 | - Bump junit-jupiter.version from 5.6.1 to 5.6.2 [\#214](https://github.com/zalando/jackson-datatype-money/pull/214) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 145 | - Bump dependency-check-maven from 5.3.1 to 5.3.2 [\#212](https://github.com/zalando/jackson-datatype-money/pull/212) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 146 | - Bump junit-jupiter.version from 5.6.0 to 5.6.1 [\#211](https://github.com/zalando/jackson-datatype-money/pull/211) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 147 | - Bump mockito-core from 3.3.0 to 3.3.3 [\#210](https://github.com/zalando/jackson-datatype-money/pull/210) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 148 | - Bump maven-javadoc-plugin from 3.1.1 to 3.2.0 [\#209](https://github.com/zalando/jackson-datatype-money/pull/209) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 149 | - Bump dependency-check-maven from 5.3.0 to 5.3.1 [\#208](https://github.com/zalando/jackson-datatype-money/pull/208) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 150 | - Bump mbknor-jackson-jsonschema\_2.12 from 1.0.36 to 1.0.38 [\#207](https://github.com/zalando/jackson-datatype-money/pull/207) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 151 | - Bump jackson.version from 2.10.2 to 2.10.3 [\#206](https://github.com/zalando/jackson-datatype-money/pull/206) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 152 | - Bump mockito-core from 3.2.4 to 3.3.0 [\#205](https://github.com/zalando/jackson-datatype-money/pull/205) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 153 | - Bump lombok from 1.18.10 to 1.18.12 [\#204](https://github.com/zalando/jackson-datatype-money/pull/204) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 154 | - Bump junit-jupiter.version from 5.5.2 to 5.6.0 [\#203](https://github.com/zalando/jackson-datatype-money/pull/203) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 155 | - Bump dependency-check-maven from 5.2.4 to 5.3.0 [\#202](https://github.com/zalando/jackson-datatype-money/pull/202) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 156 | - Bump jackson.version from 2.10.1 to 2.10.2 [\#201](https://github.com/zalando/jackson-datatype-money/pull/201) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 157 | - Bump maven-source-plugin from 3.2.0 to 3.2.1 [\#200](https://github.com/zalando/jackson-datatype-money/pull/200) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 158 | - Bump slf4j.version from 1.7.29 to 1.7.30 [\#199](https://github.com/zalando/jackson-datatype-money/pull/199) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 159 | - Bump mockito-core from 3.2.0 to 3.2.4 [\#198](https://github.com/zalando/jackson-datatype-money/pull/198) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 160 | - Updated build badge [\#197](https://github.com/zalando/jackson-datatype-money/pull/197) ([whiskeysierra](https://github.com/whiskeysierra)) 161 | - Bump mockito-core from 3.1.0 to 3.2.0 [\#196](https://github.com/zalando/jackson-datatype-money/pull/196) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 162 | - Bump maven-enforcer-plugin from 3.0.0-M2 to 3.0.0-M3 [\#195](https://github.com/zalando/jackson-datatype-money/pull/195) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 163 | - Bump mbknor-jackson-jsonschema\_2.12 from 1.0.35 to 1.0.36 [\#194](https://github.com/zalando/jackson-datatype-money/pull/194) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 164 | - Switched from Travis to Github Actions [\#193](https://github.com/zalando/jackson-datatype-money/pull/193) ([whiskeysierra](https://github.com/whiskeysierra)) 165 | - Bump mbknor-jackson-jsonschema\_2.12 from 1.0.34 to 1.0.35 [\#192](https://github.com/zalando/jackson-datatype-money/pull/192) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 166 | - Bump dependency-check-maven from 5.2.2 to 5.2.4 [\#191](https://github.com/zalando/jackson-datatype-money/pull/191) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 167 | - Bump jackson.version from 2.10.0 to 2.10.1 [\#189](https://github.com/zalando/jackson-datatype-money/pull/189) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 168 | - Bump maven-source-plugin from 3.1.0 to 3.2.0 [\#188](https://github.com/zalando/jackson-datatype-money/pull/188) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 169 | - Bump slf4j.version from 1.7.28 to 1.7.29 [\#187](https://github.com/zalando/jackson-datatype-money/pull/187) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 170 | - Bump duplicate-finder-maven-plugin from 1.2.1 to 1.4.0 [\#186](https://github.com/zalando/jackson-datatype-money/pull/186) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 171 | - Bump jacoco-maven-plugin from 0.8.4 to 0.8.5 [\#185](https://github.com/zalando/jackson-datatype-money/pull/185) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 172 | - Bump mockito-core from 3.0.0 to 3.1.0 [\#184](https://github.com/zalando/jackson-datatype-money/pull/184) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 173 | - Bump jackson.version from 2.10.0.pr2 to 2.10.0 [\#183](https://github.com/zalando/jackson-datatype-money/pull/183) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 174 | - Bump dependency-check-maven from 5.2.1 to 5.2.2 [\#182](https://github.com/zalando/jackson-datatype-money/pull/182) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 175 | - Bump lombok from 1.18.8 to 1.18.10 [\#180](https://github.com/zalando/jackson-datatype-money/pull/180) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 176 | - Bump junit-jupiter.version from 5.5.1 to 5.5.2 [\#179](https://github.com/zalando/jackson-datatype-money/pull/179) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 177 | - Updated maven [\#178](https://github.com/zalando/jackson-datatype-money/pull/178) ([whiskeysierra](https://github.com/whiskeysierra)) 178 | - Bump jackson.version from 2.10.0.pr1 to 2.10.0.pr2 [\#177](https://github.com/zalando/jackson-datatype-money/pull/177) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 179 | - Bump slf4j.version from 1.7.27 to 1.7.28 [\#176](https://github.com/zalando/jackson-datatype-money/pull/176) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 180 | - Disabled tests/checks for faster releases [\#175](https://github.com/zalando/jackson-datatype-money/pull/175) ([whiskeysierra](https://github.com/whiskeysierra)) 181 | - Bump slf4j.version from 1.7.26 to 1.7.27 [\#174](https://github.com/zalando/jackson-datatype-money/pull/174) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 182 | - Added emojis to issue template names [\#173](https://github.com/zalando/jackson-datatype-money/pull/173) ([whiskeysierra](https://github.com/whiskeysierra)) 183 | - Bump dependency-check-maven from 5.2.0 to 5.2.1 [\#172](https://github.com/zalando/jackson-datatype-money/pull/172) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 184 | - Bump dependency-check-maven from 5.1.1 to 5.2.0 [\#171](https://github.com/zalando/jackson-datatype-money/pull/171) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 185 | - Bump junit-jupiter.version from 5.5.0 to 5.5.1 [\#170](https://github.com/zalando/jackson-datatype-money/pull/170) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 186 | - Bump dependency-check-maven from 5.1.0 to 5.1.1 [\#168](https://github.com/zalando/jackson-datatype-money/pull/168) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 187 | - Dropped Java 7 support [\#167](https://github.com/zalando/jackson-datatype-money/pull/167) ([whiskeysierra](https://github.com/whiskeysierra)) 188 | - Bump maven-javadoc-plugin from 3.1.0 to 3.1.1 [\#165](https://github.com/zalando/jackson-datatype-money/pull/165) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 189 | - Bump dependency-check-maven from 5.0.0 to 5.1.0 [\#164](https://github.com/zalando/jackson-datatype-money/pull/164) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 190 | - Added labels to issue templates [\#163](https://github.com/zalando/jackson-datatype-money/pull/163) ([whiskeysierra](https://github.com/whiskeysierra)) 191 | - Bump dependency-check-maven from 3.3.4 to 5.0.0 [\#162](https://github.com/zalando/jackson-datatype-money/pull/162) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 192 | - Bump apiguardian-api from 1.0.0 to 1.1.0 [\#161](https://github.com/zalando/jackson-datatype-money/pull/161) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 193 | - Bump mockito-core from 2.27.0 to 2.28.2 [\#160](https://github.com/zalando/jackson-datatype-money/pull/160) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 194 | - Bump maven-source-plugin from 3.0.1 to 3.1.0 [\#159](https://github.com/zalando/jackson-datatype-money/pull/159) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 195 | - Bump jackson.version from 2.9.8 to 2.9.9 [\#158](https://github.com/zalando/jackson-datatype-money/pull/158) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 196 | - Bump jacoco-maven-plugin from 0.8.3 to 0.8.4 [\#157](https://github.com/zalando/jackson-datatype-money/pull/157) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 197 | - Bump lombok from 1.18.6 to 1.18.8 [\#156](https://github.com/zalando/jackson-datatype-money/pull/156) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 198 | - Fix typo in "Martin Fowler" [\#155](https://github.com/zalando/jackson-datatype-money/pull/155) ([toukovk](https://github.com/toukovk)) 199 | - Bump maven-surefire-plugin from 2.22.1 to 2.22.2 [\#154](https://github.com/zalando/jackson-datatype-money/pull/154) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 200 | - Bump maven-compiler-plugin from 3.8.0 to 3.8.1 [\#153](https://github.com/zalando/jackson-datatype-money/pull/153) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 201 | - Bump mockito-core from 2.26.0 to 2.27.0 [\#152](https://github.com/zalando/jackson-datatype-money/pull/152) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 202 | - Bump mockito-core from 2.25.1 to 2.26.0 [\#151](https://github.com/zalando/jackson-datatype-money/pull/151) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 203 | - Bump mbknor-jackson-jsonschema\_2.12 from 1.0.33 to 1.0.34 [\#150](https://github.com/zalando/jackson-datatype-money/pull/150) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 204 | - Bump mockito-core from 2.25.0 to 2.25.1 [\#149](https://github.com/zalando/jackson-datatype-money/pull/149) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 205 | - Bump mockito-core from 2.24.5 to 2.25.0 [\#148](https://github.com/zalando/jackson-datatype-money/pull/148) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 206 | - Bump maven-javadoc-plugin from 3.0.1 to 3.1.0 [\#147](https://github.com/zalando/jackson-datatype-money/pull/147) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 207 | - Release/1.1.1 [\#146](https://github.com/zalando/jackson-datatype-money/pull/146) ([whiskeysierra](https://github.com/whiskeysierra)) 208 | 209 | ## [1.1.1](https://github.com/zalando/jackson-datatype-money/tree/1.1.1) (2019-02-28) 210 | 211 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.1.0...1.1.1) 212 | 213 | **Merged pull requests:** 214 | 215 | - Release/1.1.0 [\#145](https://github.com/zalando/jackson-datatype-money/pull/145) ([whiskeysierra](https://github.com/whiskeysierra)) 216 | - Adds support for other jsonSchema-Generators like mbknor-jackson-jsonschema [\#144](https://github.com/zalando/jackson-datatype-money/pull/144) ([PhilippHirch4211](https://github.com/PhilippHirch4211)) 217 | - Bump mockito-core from 2.24.0 to 2.24.5 [\#143](https://github.com/zalando/jackson-datatype-money/pull/143) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 218 | - Bump lombok from 1.18.4 to 1.18.6 [\#142](https://github.com/zalando/jackson-datatype-money/pull/142) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 219 | - Bump mockito-core from 2.23.4 to 2.24.0 [\#141](https://github.com/zalando/jackson-datatype-money/pull/141) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 220 | - Bump jacoco-maven-plugin from 0.8.2 to 0.8.3 [\#140](https://github.com/zalando/jackson-datatype-money/pull/140) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 221 | - Suppressed false positive CVE-2018-8088 for slf4j-api [\#139](https://github.com/zalando/jackson-datatype-money/pull/139) ([whiskeysierra](https://github.com/whiskeysierra)) 222 | - Bump jackson.version from 2.9.7 to 2.9.8 [\#136](https://github.com/zalando/jackson-datatype-money/pull/136) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 223 | - Bump mockito-core from 2.23.0 to 2.23.4 [\#134](https://github.com/zalando/jackson-datatype-money/pull/134) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 224 | - Bump lombok from 1.18.2 to 1.18.4 [\#133](https://github.com/zalando/jackson-datatype-money/pull/133) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 225 | - Bump dependency-check-maven from 3.3.2 to 3.3.4 [\#132](https://github.com/zalando/jackson-datatype-money/pull/132) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 226 | - Bump maven-surefire-plugin from 2.22.0 to 2.22.1 [\#131](https://github.com/zalando/jackson-datatype-money/pull/131) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 227 | - Bump mockito-core from 2.22.0 to 2.23.0 [\#130](https://github.com/zalando/jackson-datatype-money/pull/130) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 228 | - Bump jackson.version from 2.9.6 to 2.9.7 [\#129](https://github.com/zalando/jackson-datatype-money/pull/129) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 229 | - Bump dependency-check-maven from 3.3.1 to 3.3.2 [\#128](https://github.com/zalando/jackson-datatype-money/pull/128) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 230 | - Bump mockito-core from 2.21.0 to 2.22.0 [\#127](https://github.com/zalando/jackson-datatype-money/pull/127) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 231 | - Bump versions-maven-plugin from 2.6 to 2.7 [\#126](https://github.com/zalando/jackson-datatype-money/pull/126) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 232 | - Bump versions-maven-plugin from 2.5 to 2.6 [\#125](https://github.com/zalando/jackson-datatype-money/pull/125) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 233 | - Bump jacoco-maven-plugin from 0.8.1 to 0.8.2 [\#124](https://github.com/zalando/jackson-datatype-money/pull/124) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 234 | - Added stability marker [\#123](https://github.com/zalando/jackson-datatype-money/pull/123) ([whiskeysierra](https://github.com/whiskeysierra)) 235 | 236 | ## [1.1.0](https://github.com/zalando/jackson-datatype-money/tree/1.1.0) (2018-08-07) 237 | 238 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.0.2...1.1.0) 239 | 240 | **Closed issues:** 241 | 242 | - Please release version with moneta 1.3 [\#112](https://github.com/zalando/jackson-datatype-money/issues/112) 243 | - Ability to change default digits for a particular currency [\#110](https://github.com/zalando/jackson-datatype-money/issues/110) 244 | - Known issue with setters on MonetaryAmount [\#82](https://github.com/zalando/jackson-datatype-money/issues/82) 245 | 246 | **Merged pull requests:** 247 | 248 | - Bump dependency-check-maven from 3.3.0 to 3.3.1 [\#122](https://github.com/zalando/jackson-datatype-money/pull/122) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 249 | - Bump mockito-core from 2.20.1 to 2.21.0 [\#121](https://github.com/zalando/jackson-datatype-money/pull/121) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 250 | - Bump maven-compiler-plugin from 3.7.0 to 3.8.0 [\#120](https://github.com/zalando/jackson-datatype-money/pull/120) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 251 | - Bump lombok from 1.18.0 to 1.18.2 [\#119](https://github.com/zalando/jackson-datatype-money/pull/119) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 252 | - Bump mockito-core from 2.20.0 to 2.20.1 [\#118](https://github.com/zalando/jackson-datatype-money/pull/118) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 253 | - Bump mockito-core from 2.19.1 to 2.20.0 [\#117](https://github.com/zalando/jackson-datatype-money/pull/117) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 254 | - Bump dependency-check-maven from 3.2.1 to 3.3.0 [\#116](https://github.com/zalando/jackson-datatype-money/pull/116) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 255 | - Bump mockito-core from 2.19.0 to 2.19.1 [\#115](https://github.com/zalando/jackson-datatype-money/pull/115) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 256 | - Bump moneta-bp from 1.2 to 1.3 [\#114](https://github.com/zalando/jackson-datatype-money/pull/114) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 257 | - Bump moneta from 1.2.1 to 1.3 [\#113](https://github.com/zalando/jackson-datatype-money/pull/113) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 258 | - Opened up AmountWriter to clients [\#111](https://github.com/zalando/jackson-datatype-money/pull/111) ([whiskeysierra](https://github.com/whiskeysierra)) 259 | - Bump mockito-core from 2.18.3 to 2.19.0 [\#109](https://github.com/zalando/jackson-datatype-money/pull/109) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 260 | - Bump maven-enforcer-plugin from 3.0.0-M1 to 3.0.0-M2 [\#108](https://github.com/zalando/jackson-datatype-money/pull/108) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 261 | - Bump maven-surefire-plugin from 2.21.0 to 2.22.0 [\#107](https://github.com/zalando/jackson-datatype-money/pull/107) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 262 | - Bump jackson.version from 2.9.5 to 2.9.6 [\#105](https://github.com/zalando/jackson-datatype-money/pull/105) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 263 | - Bump lombok from 1.16.22 to 1.18.0 [\#104](https://github.com/zalando/jackson-datatype-money/pull/104) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 264 | - Bump maven-javadoc-plugin from 3.0.0 to 3.0.1 [\#103](https://github.com/zalando/jackson-datatype-money/pull/103) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 265 | - Bump lombok from 1.16.20 to 1.16.22 [\#102](https://github.com/zalando/jackson-datatype-money/pull/102) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 266 | - Bump dependency-check-maven from 3.2.0 to 3.2.1 [\#101](https://github.com/zalando/jackson-datatype-money/pull/101) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 267 | - Bump dependency-check-maven from 3.1.2 to 3.2.0 [\#100](https://github.com/zalando/jackson-datatype-money/pull/100) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 268 | - Bump org.codehaus.mojo:versions-maven-plugin from 2.2 to 2.5 [\#98](https://github.com/zalando/jackson-datatype-money/pull/98) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 269 | - Bump money-api.version from 1.0.1 to 1.0.3 [\#97](https://github.com/zalando/jackson-datatype-money/pull/97) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 270 | - Bump org.jacoco:jacoco-maven-plugin from 0.7.6.201602180812 to 0.8.1 [\#96](https://github.com/zalando/jackson-datatype-money/pull/96) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 271 | - Bump org.projectlombok:lombok from 1.16.18 to 1.16.20 [\#95](https://github.com/zalando/jackson-datatype-money/pull/95) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 272 | - Bump org.eluder.coveralls:coveralls-maven-plugin from 4.1.0 to 4.3.0 [\#94](https://github.com/zalando/jackson-datatype-money/pull/94) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 273 | - Bump org.sonatype.plugins:nexus-staging-maven-plugin from 1.6.7 to 1.6.8 [\#93](https://github.com/zalando/jackson-datatype-money/pull/93) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 274 | - Bump org.apache.maven.plugins:maven-source-plugin from 3.0.0 to 3.0.1 [\#92](https://github.com/zalando/jackson-datatype-money/pull/92) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 275 | - Bump org.owasp:dependency-check-maven from 3.1.1 to 3.1.2 [\#91](https://github.com/zalando/jackson-datatype-money/pull/91) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 276 | - Bump org.apache.maven.plugins:maven-javadoc-plugin from 2.10.3 to 3.0.0 [\#90](https://github.com/zalando/jackson-datatype-money/pull/90) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 277 | - Bump org.mockito:mockito-core from 2.8.47 to 2.18.3 [\#89](https://github.com/zalando/jackson-datatype-money/pull/89) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 278 | - Bump org.apache.maven.plugins:maven-compiler-plugin from 3.5.1 to 3.7.0 [\#88](https://github.com/zalando/jackson-datatype-money/pull/88) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 279 | - Bump moneta.version from 1.1 to 1.2 [\#87](https://github.com/zalando/jackson-datatype-money/pull/87) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 280 | - Bump org.apache.maven.plugins:maven-resources-plugin from 2.7 to 3.1.0 [\#86](https://github.com/zalando/jackson-datatype-money/pull/86) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 281 | - Bump org.apache.maven.plugins:maven-surefire-plugin from 2.19.1 to 2.21.0 [\#85](https://github.com/zalando/jackson-datatype-money/pull/85) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 282 | - Added SECURITY file [\#84](https://github.com/zalando/jackson-datatype-money/pull/84) ([whiskeysierra](https://github.com/whiskeysierra)) 283 | - Made surefire print test failures to console [\#83](https://github.com/zalando/jackson-datatype-money/pull/83) ([whiskeysierra](https://github.com/whiskeysierra)) 284 | 285 | ## [1.0.2](https://github.com/zalando/jackson-datatype-money/tree/1.0.2) (2018-04-23) 286 | 287 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.0.1...1.0.2) 288 | 289 | **Closed issues:** 290 | 291 | - Introduce API Guardian [\#79](https://github.com/zalando/jackson-datatype-money/issues/79) 292 | 293 | **Merged pull requests:** 294 | 295 | - Annotated public API with @API [\#81](https://github.com/zalando/jackson-datatype-money/pull/81) ([whiskeysierra](https://github.com/whiskeysierra)) 296 | - Moved to semantic release script [\#80](https://github.com/zalando/jackson-datatype-money/pull/80) ([whiskeysierra](https://github.com/whiskeysierra)) 297 | 298 | ## [1.0.1](https://github.com/zalando/jackson-datatype-money/tree/1.0.1) (2018-04-11) 299 | 300 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.0.0...1.0.1) 301 | 302 | **Closed issues:** 303 | 304 | - CurrencyUnitDeserializer throws UnknownCurrencyException if empty string is passed [\#76](https://github.com/zalando/jackson-datatype-money/issues/76) 305 | - Adjust No-Args Constructor in CurrencyUnitSerializer to be public? [\#75](https://github.com/zalando/jackson-datatype-money/issues/75) 306 | - Create LocaleProvider to resolve correctly current locale [\#71](https://github.com/zalando/jackson-datatype-money/issues/71) 307 | 308 | **Merged pull requests:** 309 | 310 | - Bumped Jackson version due to CVE-2018-7489 [\#78](https://github.com/zalando/jackson-datatype-money/pull/78) ([whiskeysierra](https://github.com/whiskeysierra)) 311 | - Enabled CVE check [\#77](https://github.com/zalando/jackson-datatype-money/pull/77) ([whiskeysierra](https://github.com/whiskeysierra)) 312 | - Renamed locale parameter [\#74](https://github.com/zalando/jackson-datatype-money/pull/74) ([whiskeysierra](https://github.com/whiskeysierra)) 313 | 314 | ## [1.0.0](https://github.com/zalando/jackson-datatype-money/tree/1.0.0) (2017-11-17) 315 | 316 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.0.0-RC2...1.0.0) 317 | 318 | **Closed issues:** 319 | 320 | - RestTemplate Integration [\#70](https://github.com/zalando/jackson-datatype-money/issues/70) 321 | - SpringFox Generation [\#69](https://github.com/zalando/jackson-datatype-money/issues/69) 322 | 323 | **Merged pull requests:** 324 | 325 | - Enrich MonetaryAmount and CurrencyUnit serializer with json schema [\#73](https://github.com/zalando/jackson-datatype-money/pull/73) ([aboivin](https://github.com/aboivin)) 326 | 327 | ## [1.0.0-RC2](https://github.com/zalando/jackson-datatype-money/tree/1.0.0-RC2) (2017-09-20) 328 | 329 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/1.0.0-RC1...1.0.0-RC2) 330 | 331 | **Closed issues:** 332 | 333 | - Restore CurrencyUnitDeserializer? [\#67](https://github.com/zalando/jackson-datatype-money/issues/67) 334 | 335 | **Merged pull requests:** 336 | 337 | - Re-added support for CurrencyUnit [\#68](https://github.com/zalando/jackson-datatype-money/pull/68) ([whiskeysierra](https://github.com/whiskeysierra)) 338 | 339 | ## [1.0.0-RC1](https://github.com/zalando/jackson-datatype-money/tree/1.0.0-RC1) (2017-09-04) 340 | 341 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.13.0...1.0.0-RC1) 342 | 343 | **Closed issues:** 344 | 345 | - MonetaryAmount serialization [\#64](https://github.com/zalando/jackson-datatype-money/issues/64) 346 | 347 | **Merged pull requests:** 348 | 349 | - Made use of default fraction digits when serializing amounts [\#66](https://github.com/zalando/jackson-datatype-money/pull/66) ([whiskeysierra](https://github.com/whiskeysierra)) 350 | - Support big decimal plain strings [\#65](https://github.com/zalando/jackson-datatype-money/pull/65) ([whiskeysierra](https://github.com/whiskeysierra)) 351 | - Updated dependencies [\#63](https://github.com/zalando/jackson-datatype-money/pull/63) ([whiskeysierra](https://github.com/whiskeysierra)) 352 | - Release preparation 0.20.0 [\#62](https://github.com/zalando/jackson-datatype-money/pull/62) ([whiskeysierra](https://github.com/whiskeysierra)) 353 | 354 | ## [0.13.0](https://github.com/zalando/jackson-datatype-money/tree/0.13.0) (2017-08-14) 355 | 356 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.12.0...0.13.0) 357 | 358 | **Closed issues:** 359 | 360 | - Provide number value serializer factory [\#59](https://github.com/zalando/jackson-datatype-money/issues/59) 361 | - Drop support for java.util.Currency [\#54](https://github.com/zalando/jackson-datatype-money/issues/54) 362 | - Hide de/serializer implementations [\#53](https://github.com/zalando/jackson-datatype-money/issues/53) 363 | - Change amount parameter type from BigDecimal to Number [\#51](https://github.com/zalando/jackson-datatype-money/issues/51) 364 | - Remove deprecated elements [\#50](https://github.com/zalando/jackson-datatype-money/issues/50) 365 | - Type Id Handling not supported [\#46](https://github.com/zalando/jackson-datatype-money/issues/46) 366 | - Link in README to SerializationConfig is broken [\#44](https://github.com/zalando/jackson-datatype-money/issues/44) 367 | - Amount is sent as number, consider string instead [\#43](https://github.com/zalando/jackson-datatype-money/issues/43) 368 | 369 | **Merged pull requests:** 370 | 371 | - Jackson 2.9.0 [\#61](https://github.com/zalando/jackson-datatype-money/pull/61) ([sullis](https://github.com/sullis)) 372 | - Adds support for DecimalNumberValueSerializer [\#52](https://github.com/zalando/jackson-datatype-money/pull/52) ([whiskeysierra](https://github.com/whiskeysierra)) 373 | - Added special readme about ways to represent money [\#49](https://github.com/zalando/jackson-datatype-money/pull/49) ([whiskeysierra](https://github.com/whiskeysierra)) 374 | - Added support for typing of monetary amounts [\#47](https://github.com/zalando/jackson-datatype-money/pull/47) ([whiskeysierra](https://github.com/whiskeysierra)) 375 | 376 | ## [0.12.0](https://github.com/zalando/jackson-datatype-money/tree/0.12.0) (2017-05-02) 377 | 378 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.11.0...0.12.0) 379 | 380 | **Merged pull requests:** 381 | 382 | - Add support for string amounts [\#42](https://github.com/zalando/jackson-datatype-money/pull/42) ([bountin](https://github.com/bountin)) 383 | 384 | ## [0.11.0](https://github.com/zalando/jackson-datatype-money/tree/0.11.0) (2016-10-04) 385 | 386 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.10.0...0.11.0) 387 | 388 | **Closed issues:** 389 | 390 | - Custom naming for currency and amount fields [\#40](https://github.com/zalando/jackson-datatype-money/issues/40) 391 | 392 | **Merged pull requests:** 393 | 394 | - Added support for configurable field names [\#41](https://github.com/zalando/jackson-datatype-money/pull/41) ([whiskeysierra](https://github.com/whiskeysierra)) 395 | 396 | ## [0.10.0](https://github.com/zalando/jackson-datatype-money/tree/0.10.0) (2016-09-20) 397 | 398 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.9.0...0.10.0) 399 | 400 | **Fixed bugs:** 401 | 402 | - Concrete RI type Money not accepted for serialization [\#38](https://github.com/zalando/jackson-datatype-money/issues/38) 403 | 404 | **Merged pull requests:** 405 | 406 | - Added support for deserializing into Money/FastMoney/RoundedMoney [\#39](https://github.com/zalando/jackson-datatype-money/pull/39) ([whiskeysierra](https://github.com/whiskeysierra)) 407 | - Switched to MIT license [\#37](https://github.com/zalando/jackson-datatype-money/pull/37) ([whiskeysierra](https://github.com/whiskeysierra)) 408 | 409 | ## [0.9.0](https://github.com/zalando/jackson-datatype-money/tree/0.9.0) (2016-08-15) 410 | 411 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.8.0...0.9.0) 412 | 413 | **Merged pull requests:** 414 | 415 | - Use deserializationContext.readValue instead of parser.readValueAs in MonetaryAmountDeserializer [\#36](https://github.com/zalando/jackson-datatype-money/pull/36) ([msparer](https://github.com/msparer)) 416 | 417 | ## [0.8.0](https://github.com/zalando/jackson-datatype-money/tree/0.8.0) (2016-06-23) 418 | 419 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.7.0...0.8.0) 420 | 421 | **Fixed bugs:** 422 | 423 | - CurrencyUnitDeserializer deserializes invalid currencies [\#34](https://github.com/zalando/jackson-datatype-money/issues/34) 424 | 425 | **Closed issues:** 426 | 427 | - Fix zappr configuration [\#30](https://github.com/zalando/jackson-datatype-money/issues/30) 428 | 429 | **Merged pull requests:** 430 | 431 | - Fixed deserialization of invalid currencies [\#35](https://github.com/zalando/jackson-datatype-money/pull/35) ([whiskeysierra](https://github.com/whiskeysierra)) 432 | - Updated contribution guidelines [\#33](https://github.com/zalando/jackson-datatype-money/pull/33) ([whiskeysierra](https://github.com/whiskeysierra)) 433 | - Update and rename .zappr.yml to .zappr.yaml [\#32](https://github.com/zalando/jackson-datatype-money/pull/32) ([whiskeysierra](https://github.com/whiskeysierra)) 434 | - Replaced "Java Money" with JavaMoney [\#31](https://github.com/zalando/jackson-datatype-money/pull/31) ([LappleApple](https://github.com/LappleApple)) 435 | - Fixed zapper config name [\#29](https://github.com/zalando/jackson-datatype-money/pull/29) ([whiskeysierra](https://github.com/whiskeysierra)) 436 | - Added zappr config [\#28](https://github.com/zalando/jackson-datatype-money/pull/28) ([whiskeysierra](https://github.com/whiskeysierra)) 437 | - Release 0.7.0 [\#27](https://github.com/zalando/jackson-datatype-money/pull/27) ([whiskeysierra](https://github.com/whiskeysierra)) 438 | 439 | ## [0.7.0](https://github.com/zalando/jackson-datatype-money/tree/0.7.0) (2016-04-21) 440 | 441 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.6.0...0.7.0) 442 | 443 | **Closed issues:** 444 | 445 | - Strange behaviour in case of 100.00 EUR value [\#24](https://github.com/zalando/jackson-datatype-money/issues/24) 446 | - Unwanted transitive dependency to jdk8 version of money api and ri [\#20](https://github.com/zalando/jackson-datatype-money/issues/20) 447 | - Add support for RoundedMoney [\#17](https://github.com/zalando/jackson-datatype-money/issues/17) 448 | 449 | **Merged pull requests:** 450 | 451 | - Extracted test script based on jEnv [\#26](https://github.com/zalando/jackson-datatype-money/pull/26) ([whiskeysierra](https://github.com/whiskeysierra)) 452 | - Refined readme [\#25](https://github.com/zalando/jackson-datatype-money/pull/25) ([whiskeysierra](https://github.com/whiskeysierra)) 453 | - Refactor maven profiles [\#23](https://github.com/zalando/jackson-datatype-money/pull/23) ([jhorstmann](https://github.com/jhorstmann)) 454 | - Update README.md [\#21](https://github.com/zalando/jackson-datatype-money/pull/21) ([LappleApple](https://github.com/LappleApple)) 455 | - Update LICENSE [\#19](https://github.com/zalando/jackson-datatype-money/pull/19) ([LappleApple](https://github.com/LappleApple)) 456 | - Added support for RoundedMoney [\#18](https://github.com/zalando/jackson-datatype-money/pull/18) ([whiskeysierra](https://github.com/whiskeysierra)) 457 | - Added formatting support [\#16](https://github.com/zalando/jackson-datatype-money/pull/16) ([whiskeysierra](https://github.com/whiskeysierra)) 458 | 459 | ## [0.6.0](https://github.com/zalando/jackson-datatype-money/tree/0.6.0) (2015-10-07) 460 | 461 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.5.0...0.6.0) 462 | 463 | **Merged pull requests:** 464 | 465 | - Added FastMoney support [\#14](https://github.com/zalando/jackson-datatype-money/pull/14) ([whiskeysierra](https://github.com/whiskeysierra)) 466 | 467 | ## [0.5.0](https://github.com/zalando/jackson-datatype-money/tree/0.5.0) (2015-09-24) 468 | 469 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.4.0...0.5.0) 470 | 471 | **Closed issues:** 472 | 473 | - Add syntax hints to code blocks in readme [\#11](https://github.com/zalando/jackson-datatype-money/issues/11) 474 | - Improve readme to include Java 7 and 8 compatibility [\#10](https://github.com/zalando/jackson-datatype-money/issues/10) 475 | - MonetaryAmountDeserializer currency [\#6](https://github.com/zalando/jackson-datatype-money/issues/6) 476 | - Added a link from main jackson page [\#3](https://github.com/zalando/jackson-datatype-money/issues/3) 477 | 478 | **Merged pull requests:** 479 | 480 | - Update README.md [\#12](https://github.com/zalando/jackson-datatype-money/pull/12) ([whiskeysierra](https://github.com/whiskeysierra)) 481 | - Added JDK7 support [\#9](https://github.com/zalando/jackson-datatype-money/pull/9) ([whiskeysierra](https://github.com/whiskeysierra)) 482 | 483 | ## [0.4.0](https://github.com/zalando/jackson-datatype-money/tree/0.4.0) (2015-09-10) 484 | 485 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.3.0...0.4.0) 486 | 487 | **Merged pull requests:** 488 | 489 | - Update to release version of jackson [\#8](https://github.com/zalando/jackson-datatype-money/pull/8) ([jhorstmann](https://github.com/jhorstmann)) 490 | 491 | ## [0.3.0](https://github.com/zalando/jackson-datatype-money/tree/0.3.0) (2015-09-01) 492 | 493 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.2.0...0.3.0) 494 | 495 | **Closed issues:** 496 | 497 | - Make deserialization working without jackson-module-parameter-names [\#5](https://github.com/zalando/jackson-datatype-money/issues/5) 498 | 499 | **Merged pull requests:** 500 | 501 | - Issue 1 [\#4](https://github.com/zalando/jackson-datatype-money/pull/4) ([c00ler](https://github.com/c00ler)) 502 | - Feature/property order [\#2](https://github.com/zalando/jackson-datatype-money/pull/2) ([whiskeysierra](https://github.com/whiskeysierra)) 503 | 504 | ## [0.2.0](https://github.com/zalando/jackson-datatype-money/tree/0.2.0) (2015-06-30) 505 | 506 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/0.1.0...0.2.0) 507 | 508 | **Merged pull requests:** 509 | 510 | - Prepared release scripts/configuration [\#1](https://github.com/zalando/jackson-datatype-money/pull/1) ([whiskeysierra](https://github.com/whiskeysierra)) 511 | 512 | ## [0.1.0](https://github.com/zalando/jackson-datatype-money/tree/0.1.0) (2015-06-23) 513 | 514 | [Full Changelog](https://github.com/zalando/jackson-datatype-money/compare/d18e8e86d3f4a0fa8d59d90b446c0270c20c75e1...0.1.0) 515 | 516 | 517 | 518 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 519 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2016 Zalando SE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | Willi Schönborn 2 | -------------------------------------------------------------------------------- /MONEY.md: -------------------------------------------------------------------------------- 1 | # Representing Money in JSON 2 | 3 | > A large proportion of the computers in this world manipulate money, so it's always puzzled me that money isn't actually a first class data type in any mainstream programming language. 4 | > 5 | > [Martin Fowler](https://martinfowler.com/eaaCatalog/money.html) 6 | 7 | Unfortunately JSON is no different. This document tries to change that by proposing and comparing different styles to represent money, some inspired by external sources and some based on our own experience. 8 | 9 | ## ⚠️ Monetary amounts ≠ floats 10 | 11 | Before we dive into details, always keep the following in mind. However you desire to format money in JSON, nothing changes the fact that you should... 12 | 13 | > **Never hold monetary values [..] in a float variable.** Floating point is not suitable for this work, and you must use either [fixed-point](#fixed-point) or [decimal](#decimal) values. 14 | > 15 | > [Coinkite: Common Terms and Data Objects](https://web.archive.org/web/20150924073850/https://docs.coinkite.com/api/common.html) 16 | 17 | ## Styles 18 | 19 | We identified the following styles that all of different advantages and disadvantages that are discussed in their respective section. 20 | 21 | | Style | Expressive | Arithmetic | Pitfalls / Misuses | 22 | |------------------------------------|------------|------------|--------------------| 23 | | [Decimal](#decimal) | ✔ | ✔ | Precision | 24 | | [Quoted Decimal](#quoted-decimal) | ✔ | ✘ | Parsing | 25 | | [Fixed Point](#fixed-point) | ✘ | ✔ | Mixed scales | 26 | | [Mixed](#mixed) | ✘ | ✔ | Consistency | 27 | 28 | ### Decimal 29 | 30 | The most straightforward way to represent a monetary amount would be a base-10 decimal number: 31 | 32 | ```json 33 | { 34 | "amount": 49.95, 35 | "currency": "EUR" 36 | } 37 | ``` 38 | 39 | It's expressive, readable and allows arithmetic operations. The downside is that most [JSON decoders will treat it as a floating point](https://tools.ietf.org/html/rfc7159#section-6) number which is very much undesirable. 40 | 41 | Most programming languages have support for arbitrary-precision [decimals](#decimal-implementations) and JSON decoders that can be configured to use them. In general it can be considered to be a problem of the implementation, not the format itself. 42 | 43 | ### Quoted Decimal 44 | 45 | Same as [Decimal](#decimal) but quoted so your JSON decoder treats it as a string: 46 | 47 | ```json 48 | { 49 | "amount": "49.95", 50 | "currency": "EUR" 51 | } 52 | ``` 53 | 54 | It solves the precision problem of decimals on the expense of performing arithmetic operations on it. It also requires a two-phase parsing, i.e. parsing the JSON text into a data structure and then parsing quoted amounts into decimals. 55 | 56 | ### Fixed Point 57 | 58 | > A value of a fixed-point data type is essentially an integer that is scaled by an implicit specific factor determined by the type. 59 | > 60 | > [Wikipedia: Fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic) 61 | 62 | ```json 63 | { 64 | "amount": 4995, 65 | "currency": "EUR" 66 | } 67 | ``` 68 | 69 | The implicit scaling factor is defined as (0.1 raised to the power of) the currency's [default number of fraction digits](http://www.localeplanet.com/icu/currency.html). 70 | 71 | In rare cases one might need a higher precision, e.g. to have sub-cent. In this case the scale can be defined explicitly: 72 | 73 | ```json 74 | { 75 | "amount": 499599, 76 | "currency": "EUR", 77 | "scale": 4 78 | } 79 | ``` 80 | 81 | The downside with fixed-point amounts is that reading them is a bit harder and arithmetic with mixed scale amounts can be tricky and error-prone. 82 | 83 | ### Mixed 84 | 85 | As a way to counter all negative aspects of the styles above one idea would be to have a single object that contains all of the formats: 86 | 87 | ```json 88 | { 89 | "decimal": 49.95, 90 | "quoted_decimal": "49.95", 91 | "fixed_point": 4995, 92 | "scale": 2, 93 | "currency": "EUR" 94 | } 95 | ``` 96 | 97 | Decoders can choose the representation that fits them the best. Encoders on the other hand have the harder task by providing all of them and making sure that all values are in fact consistent. 98 | 99 | ## Decimal Implementations 100 | 101 | | Language | Implementation | 102 | |------------|---------------------------------------------------------------------------------------------| 103 | | C# | [decimal](https://msdn.microsoft.com/en-us/library/364x0z75.aspx) | 104 | | Java | [java.math.BigDecimal](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html) | 105 | | JavaScript | [decimal.js](https://github.com/MikeMcl/decimal.js/) | 106 | | Python | [decimal.Decimal](https://docs.python.org/2/library/decimal.html) | 107 | 108 | ## Credits and References 109 | 110 | - [Coinkite: Currency Amounts](https://web.archive.org/web/20150924073850/https://docs.coinkite.com/api/common.html#currency-amounts) 111 | - [Culttt: How to handle money and currency in web applications](http://culttt.com/2014/05/28/handle-money-currency-web-applications/) 112 | - [Currency codes - ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) 113 | - [LocalePlanet: ICU Currencies](http://www.localeplanet.com/icu/currency.html) 114 | - [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159#section-6) 115 | - [Stackoverflow: What is the standard for formatting currency values in JSON?](http://stackoverflow.com/questions/30249406/what-is-the-standard-for-formatting-currency-values-in-json) 116 | - [Stackoverflow: Why not use Double or Float to represent currency?](http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency/3730040#3730040) 117 | - [TechEmpower: Mangling JSON numbers](https://www.techempower.com/blog/2016/07/05/mangling-json-numbers/) 118 | - [Wikipedia: Fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic) 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jackson Datatype Money 2 | 3 | [![Stability: Sustained](https://masterminds.github.io/stability/sustained.svg)](https://masterminds.github.io/stability/sustained.html) 4 | ![Build Status](https://github.com/zalando/jackson-datatype-money/workflows/build/badge.svg) 5 | [![Coverage Status](https://img.shields.io/coveralls/zalando/jackson-datatype-money/main.svg)](https://coveralls.io/r/zalando/jackson-datatype-money) 6 | [![Code Quality](https://img.shields.io/codacy/grade/7fdac4ae509b403eb837b246e288856f/main.svg)](https://www.codacy.com/app/whiskeysierra/jackson-datatype-money) 7 | [![Javadoc](http://javadoc.io/badge/org.zalando/jackson-datatype-money.svg)](http://www.javadoc.io/doc/org.zalando/jackson-datatype-money) 8 | [![Release](https://img.shields.io/github/release/zalando/jackson-datatype-money.svg)](https://github.com/zalando/jackson-datatype-money/releases) 9 | [![Maven Central](https://img.shields.io/maven-central/v/org.zalando/jackson-datatype-money.svg)](https://maven-badges.herokuapp.com/maven-central/org.zalando/jackson-datatype-money) 10 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/zalando/jackson-datatype-money/main/LICENSE) 11 | 12 | 13 | *Jackson Datatype Money* is a [Jackson](https://github.com/codehaus/jackson) module to support JSON serialization and 14 | deserialization of [JavaMoney](https://github.com/JavaMoney/jsr354-api) data types. It fills a niche, in that it 15 | integrates JavaMoney and Jackson so that they work seamlessly together, without requiring additional 16 | developer effort. In doing so, it aims to perform a small but repetitive task — once and for all. 17 | 18 | This library reflects our API preferences for [representing monetary amounts in JSON](MONEY.md): 19 | 20 | ```json 21 | { 22 | "amount": 29.95, 23 | "currency": "EUR" 24 | } 25 | ``` 26 | 27 | ## Features 28 | - enables you to express monetary amounts in JSON 29 | - can be used in a REST APIs 30 | - customized field names 31 | - localization of formatted monetary amounts 32 | - allows you to implement RESTful API endpoints that format monetary amounts based on the Accept-Language header 33 | - is unique and flexible 34 | 35 | ## Dependencies 36 | - Java 8 or higher 37 | - Any build tool using Maven Central, or direct download 38 | - Jackson 39 | - JavaMoney 40 | 41 | ## Installation 42 | 43 | Add the following dependency to your project: 44 | 45 | ```xml 46 | 47 | org.zalando 48 | jackson-datatype-money 49 | ${jackson-datatype-money.version} 50 | 51 | ``` 52 | For ultimate flexibility, this module is compatible with the official version as well as the backport of JavaMoney. The actual version will be selected by a profile based on the current JDK version. 53 | 54 | ## Configuration 55 | 56 | Register the module with your `ObjectMapper`: 57 | 58 | ```java 59 | ObjectMapper mapper = new ObjectMapper() 60 | .registerModule(new MoneyModule()); 61 | ``` 62 | 63 | Alternatively, you can use the SPI capabilities: 64 | 65 | ```java 66 | ObjectMapper mapper = new ObjectMapper() 67 | .findAndRegisterModules(); 68 | ``` 69 | 70 | ### Serialization 71 | 72 | For serialization this module currently supports 73 | [`javax.money.MonetaryAmount`](https://github.com/JavaMoney/jsr354-api/blob/master/src/main/java/javax/money/MonetaryAmount.java) 74 | and will, by default, serialize it as: 75 | 76 | ```json 77 | { 78 | "amount": 99.95, 79 | "currency": "EUR" 80 | } 81 | ``` 82 | 83 | To serialize number as a JSON string, you have to configure the quoted decimal number value serializer: 84 | 85 | ```java 86 | ObjectMapper mapper = new ObjectMapper() 87 | .registerModule(new MoneyModule().withQuotedDecimalNumbers()); 88 | ``` 89 | 90 | ```json 91 | { 92 | "amount": "99.95", 93 | "currency": "EUR" 94 | } 95 | ``` 96 | 97 | ### Formatting 98 | 99 | A special feature for serializing monetary amounts is *formatting*, which is **disabled by default**. To enable it, you 100 | have to either enable default formatting: 101 | 102 | ```java 103 | ObjectMapper mapper = new ObjectMapper() 104 | .registerModule(new MoneyModule().withDefaultFormatting()); 105 | ``` 106 | 107 | ... or pass in a `MonetaryAmountFormatFactory` implementation to the `MoneyModule`: 108 | 109 | ```java 110 | ObjectMapper mapper = new ObjectMapper() 111 | .registerModule(new MoneyModule() 112 | .withFormatting(new CustomMonetaryAmountFormatFactory())); 113 | ``` 114 | 115 | The default formatting delegates directly to `MonetaryFormats.getAmountFormat(Locale, String...)`. 116 | 117 | Formatting only affects the serialization and can be customized based on the *current* locale, as defined by the 118 | [`SerializationConfig`](https://fasterxml.github.io/jackson-databind/javadoc/2.0.0/com/fasterxml/jackson/databind/SerializationConfig.html#with\(java.util.Locale\)). This allows to implement RESTful API endpoints 119 | that format monetary amounts based on the `Accept-Language` header. 120 | 121 | The first example serializes a monetary amount using the `de_DE` locale: 122 | 123 | ```java 124 | ObjectWriter writer = mapper.writer().with(Locale.GERMANY); 125 | writer.writeValueAsString(Money.of(29.95, "EUR")); 126 | ``` 127 | 128 | ```json 129 | { 130 | "amount": 29.95, 131 | "currency": "EUR", 132 | "formatted": "29,95 EUR" 133 | } 134 | ``` 135 | 136 | The following example uses `en_US`: 137 | 138 | ```java 139 | ObjectWriter writer = mapper.writer().with(Locale.US); 140 | writer.writeValueAsString(Money.of(29.95, "USD")); 141 | ``` 142 | 143 | ```json 144 | { 145 | "amount": 29.95, 146 | "currency": "USD", 147 | "formatted": "USD29.95" 148 | } 149 | ``` 150 | 151 | More sophisticated formatting rules can be supported by implementing `MonetaryAmountFormatFactory` directly. 152 | 153 | ### Deserialization 154 | 155 | This module will use `org.javamoney.moneta.Money` as an implementation for `javax.money.MonetaryAmount` by default when 156 | deserializing money values. If you need a different implementation, you can pass a different `MonetaryAmountFactory` 157 | to the `MoneyModule`: 158 | 159 | ```java 160 | ObjectMapper mapper = new ObjectMapper() 161 | .registerModule(new MoneyModule() 162 | .withMonetaryAmount(new CustomMonetaryAmountFactory())); 163 | ``` 164 | 165 | You can also pass in a method reference: 166 | 167 | ```java 168 | ObjectMapper mapper = new ObjectMapper() 169 | .registerModule(new MoneyModule() 170 | .withMonetaryAmount(FastMoney::of)); 171 | ``` 172 | 173 | *Jackson Datatype Money* comes with support for all `MonetaryAmount` implementations from Moneta, the reference 174 | implementation of JavaMoney: 175 | 176 | | `MonetaryAmount` Implementation | Factory | 177 | |-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| 178 | | `org.javamoney.moneta.FastMoney` | [`new MoneyModule().withFastMoney()`](src/main/java/org/zalando/jackson/datatype/money/FastMoneyFactory.java) | 179 | | `org.javamoney.moneta.Money` | [`new MoneyModule().withMoney()`](src/main/java/org/zalando/jackson/datatype/money/MoneyFactory.java) | 180 | | `org.javamoney.moneta.RoundedMoney` | [`new MoneyModule().withRoundedMoney()`](src/main/java/org/zalando/jackson/datatype/money/RoundedMoneyFactory.java) | | 181 | 182 | Module supports deserialization of amount number from JSON number as well as from JSON string without any special configuration required. 183 | 184 | ### Custom Field Names 185 | 186 | As you have seen in the previous examples the `MoneyModule` uses the field names `amount`, `currency` and `formatted` 187 | by default. Those names can be overridden if desired: 188 | 189 | ```java 190 | ObjectMapper mapper = new ObjectMapper() 191 | .registerModule(new MoneyModule() 192 | .withAmountFieldName("value") 193 | .withCurrencyFieldName("unit") 194 | .withFormattedFieldName("pretty")); 195 | ``` 196 | 197 | ## Usage 198 | 199 | After registering and configuring the module you're now free to directly use `MonetaryAmount` in your data types: 200 | 201 | ```java 202 | import javax.money.MonetaryAmount; 203 | 204 | public class Product { 205 | private String sku; 206 | private MonetaryAmount price; 207 | ... 208 | } 209 | ``` 210 | 211 | ## Getting help 212 | 213 | If you have questions, concerns, bug reports, etc, please file an issue in this repository's Issue Tracker. 214 | 215 | ## Getting involved 216 | 217 | To contribute, simply make a pull request and add a brief description (1-2 sentences) of your addition or change. 218 | Please note that we aim to keep this project straightforward and focused. We are not looking to add lots of features; 219 | we just want it to keep doing what it does, as well and as powerfully as possible. For more details check the 220 | [contribution guidelines](.github/CONTRIBUTING.md). 221 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | We acknowledge that every line of code that we write may potentially contain security issues. 2 | 3 | We are trying to deal with it responsibly and provide patches as quickly as possible. If you have anything to report to 4 | us please use any of the following channels: 5 | 6 | - open an [issue](../../issues) 7 | - use our [security form](https://corporate.zalando.com/en/services-and-contact#security-form) 8 | -------------------------------------------------------------------------------- /cve-suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.slf4j:slf4j-api:1.7.25 5 | CVE-2018-8088 6 | 7 | 8 | CVE-2019-12814 9 | 10 | 11 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.zalando 8 | jackson-datatype-money 9 | 1.4.0-SNAPSHOT 10 | 11 | Jackson-datatype-Money 12 | Extension module to properly support datatypes of javax.money. 13 | https://github.com/zalando/jackson-datatype-money 14 | 15 | 16 | Zalando SE 17 | 18 | 19 | 2015 20 | 21 | 22 | 23 | MIT License 24 | https://opensource.org/licenses/MIT 25 | repo 26 | 27 | 28 | 29 | 30 | 31 | Willi Schönborn 32 | willi.schoenborn@zalando.de 33 | Zalando SE 34 | https://tech.zalando.com/ 35 | 36 | 37 | 38 | 39 | https://github.com/zalando/jackson-datatype-money 40 | scm:git:git@github.com:zalando/jackson-datatype-money.git 41 | scm:git:git@github.com:zalando/jackson-datatype-money.git 42 | 43 | 44 | 45 | UTF-8 46 | 1.8 47 | 1.8 48 | 2.0.6 49 | 5.9.2 50 | 51 | 52 | 53 | 54 | 55 | com.fasterxml.jackson 56 | jackson-bom 57 | 2.14.2 58 | pom 59 | import 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.apiguardian 67 | apiguardian-api 68 | 1.1.2 69 | 70 | 71 | com.google.code.findbugs 72 | jsr305 73 | 3.0.2 74 | provided 75 | 76 | 77 | org.projectlombok 78 | lombok 79 | 1.18.26 80 | provided 81 | 82 | 83 | org.slf4j 84 | slf4j-api 85 | ${slf4j.version} 86 | 87 | 88 | com.fasterxml.jackson.core 89 | jackson-databind 90 | 91 | 92 | javax.money 93 | money-api 94 | 1.1 95 | 96 | 97 | org.javamoney.moneta 98 | moneta-core 99 | 1.4.2 100 | 101 | 102 | 103 | 104 | org.slf4j 105 | slf4j-nop 106 | ${slf4j.version} 107 | test 108 | 109 | 110 | org.junit.jupiter 111 | junit-jupiter-engine 112 | ${junit-jupiter.version} 113 | test 114 | 115 | 116 | org.junit.jupiter 117 | junit-jupiter-params 118 | ${junit-jupiter.version} 119 | test 120 | 121 | 122 | org.assertj 123 | assertj-core 124 | 3.24.2 125 | test 126 | 127 | 128 | org.mockito 129 | mockito-core 130 | 4.5.1 131 | test 132 | 133 | 134 | com.fasterxml.jackson.module 135 | jackson-module-jsonSchema 136 | test 137 | 138 | 139 | com.kjetland 140 | mbknor-jackson-jsonschema_2.12 141 | 1.0.39 142 | test 143 | 144 | 145 | javax.validation 146 | validation-api 147 | 2.0.1.Final 148 | test 149 | 150 | 151 | 152 | 153 | 154 | 155 | org.apache.maven.plugins 156 | maven-enforcer-plugin 157 | 3.2.1 158 | 159 | 160 | enforce-maven 161 | 162 | enforce 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | org.owasp 174 | dependency-check-maven 175 | 8.1.1 176 | 177 | 178 | 179 | check 180 | 181 | 182 | 183 | 184 | true 185 | 186 | cve-suppressions.xml 187 | 188 | 189 | 190 | 191 | org.basepom.maven 192 | duplicate-finder-maven-plugin 193 | 1.5.1 194 | 195 | 196 | validate 197 | 198 | check 199 | 200 | 201 | true 202 | false 203 | 204 | module-info 205 | .*\.module-info 206 | 207 | 208 | .* 209 | 210 | 211 | 212 | 213 | 214 | 215 | org.apache.maven.plugins 216 | maven-resources-plugin 217 | 3.3.0 218 | 219 | 220 | org.apache.maven.plugins 221 | maven-compiler-plugin 222 | 3.11.0 223 | 224 | 225 | -Xlint:unchecked,deprecation 226 | -Werror 227 | 228 | 229 | 230 | 231 | org.apache.maven.plugins 232 | maven-surefire-plugin 233 | 2.22.2 234 | 235 | classesAndMethods 236 | 1 237 | true 238 | false 239 | 240 | 241 | 242 | org.jacoco 243 | jacoco-maven-plugin 244 | 0.8.8 245 | 246 | 247 | prepare-agent 248 | 249 | prepare-agent 250 | 251 | 252 | 253 | report 254 | 255 | report 256 | 257 | 258 | 259 | check 260 | 261 | check 262 | 263 | 264 | 265 | 266 | CLASS 267 | 268 | 269 | LINE 270 | COVEREDRATIO 271 | 1.0 272 | 273 | 274 | BRANCH 275 | COVEREDRATIO 276 | 1.0 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | org.eluder.coveralls 287 | coveralls-maven-plugin 288 | 4.3.0 289 | 290 | 291 | org.codehaus.mojo 292 | versions-maven-plugin 293 | 2.15.0 294 | 295 | false 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | ossrh 304 | https://oss.sonatype.org/content/repositories/snapshots 305 | 306 | 307 | ossrh 308 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 309 | 310 | 311 | 312 | 313 | 314 | release 315 | 316 | 317 | 318 | org.apache.maven.plugins 319 | maven-source-plugin 320 | 3.2.1 321 | 322 | 323 | attach-sources 324 | 325 | jar-no-fork 326 | 327 | 328 | 329 | 330 | 331 | org.apache.maven.plugins 332 | maven-javadoc-plugin 333 | 3.5.0 334 | 335 | 336 | attach-javadocs 337 | 338 | jar 339 | 340 | 341 | 342 | 343 | 344 | org.apache.maven.plugins 345 | maven-gpg-plugin 346 | 3.0.1 347 | 348 | 349 | sign-artifacts 350 | verify 351 | 352 | sign 353 | 354 | 355 | 356 | 357 | 358 | org.sonatype.plugins 359 | nexus-staging-maven-plugin 360 | 1.6.13 361 | true 362 | 363 | ossrh 364 | https://oss.sonatype.org/ 365 | true 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | : "${1?"Usage: $0 <[pre]major|[pre]minor|[pre]patch|prerelease>"}" 6 | : "${CHANGELOG_GITHUB_TOKEN?"Needs CHANGELOG_GITHUB_TOKEN env var"}" 7 | 8 | ./mvnw scm:check-local-modification 9 | 10 | current=$({ echo 0.0.0; git tag --list --sort=version:refname; } | tail -n1) 11 | release=$(semver "${current}" -i "$1" --preid RC) 12 | next=$(semver "${release}" -i minor) 13 | 14 | git checkout -b "release/${release}" 15 | 16 | ./mvnw versions:set -D newVersion="${release}" 17 | git commit -am "Release ${release}" 18 | ./mvnw clean deploy scm:tag -P release -D tag="${release}" -D pushChanges=false -D skipTests -D dependency-check.skip 19 | 20 | git push --tags 21 | 22 | ./mvnw versions:set -D newVersion="${next}-SNAPSHOT" 23 | docker run -it --rm -e CHANGELOG_GITHUB_TOKEN -v "$(pwd)":/usr/local/src/your-app \ 24 | githubchangeloggenerator/github-changelog-generator -u zalando -p jackson-datatype-money 25 | git commit -am "Development ${next}-SNAPSHOT" 26 | 27 | git push 28 | 29 | git checkout main 30 | git branch -D "release/${release}" 31 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/AmountWriter.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import org.apiguardian.api.API; 4 | 5 | import javax.money.MonetaryAmount; 6 | 7 | import static org.apiguardian.api.API.Status.EXPERIMENTAL; 8 | 9 | @API(status = EXPERIMENTAL) 10 | public interface AmountWriter { 11 | 12 | Class getType(); 13 | 14 | T write(MonetaryAmount amount); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/BigDecimalAmountWriter.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import org.apiguardian.api.API; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import static org.apiguardian.api.API.Status.EXPERIMENTAL; 8 | 9 | @API(status = EXPERIMENTAL) 10 | public interface BigDecimalAmountWriter extends AmountWriter { 11 | 12 | @Override 13 | default Class getType() { 14 | return BigDecimal.class; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/CurrencyUnitDeserializer.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.core.JsonParser; 4 | import com.fasterxml.jackson.databind.DeserializationContext; 5 | import com.fasterxml.jackson.databind.JsonDeserializer; 6 | import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; 7 | import org.apiguardian.api.API; 8 | 9 | import javax.money.CurrencyUnit; 10 | import javax.money.Monetary; 11 | import java.io.IOException; 12 | 13 | import static org.apiguardian.api.API.Status.MAINTAINED; 14 | 15 | @API(status = MAINTAINED) 16 | public final class CurrencyUnitDeserializer extends JsonDeserializer { 17 | 18 | @Override 19 | public Object deserializeWithType(final JsonParser parser, final DeserializationContext context, 20 | final TypeDeserializer deserializer) throws IOException { 21 | 22 | // effectively assuming no type information at all 23 | return deserialize(parser, context); 24 | } 25 | 26 | @Override 27 | public CurrencyUnit deserialize(final JsonParser parser, final DeserializationContext context) throws IOException { 28 | final String currencyCode = parser.getValueAsString(); 29 | return Monetary.getCurrency(currencyCode); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/CurrencyUnitSerializer.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator; 4 | import com.fasterxml.jackson.databind.JavaType; 5 | import com.fasterxml.jackson.databind.JsonMappingException; 6 | import com.fasterxml.jackson.databind.SerializerProvider; 7 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; 8 | import com.fasterxml.jackson.databind.ser.std.StdSerializer; 9 | import org.apiguardian.api.API; 10 | 11 | import javax.money.CurrencyUnit; 12 | import java.io.IOException; 13 | 14 | import static org.apiguardian.api.API.Status.MAINTAINED; 15 | 16 | @API(status = MAINTAINED) 17 | public final class CurrencyUnitSerializer extends StdSerializer { 18 | 19 | CurrencyUnitSerializer() { 20 | super(CurrencyUnit.class); 21 | } 22 | 23 | @Override 24 | public void serialize(final CurrencyUnit value, final JsonGenerator generator, final SerializerProvider serializers) 25 | throws IOException { 26 | generator.writeString(value.getCurrencyCode()); 27 | } 28 | 29 | @Override 30 | public void acceptJsonFormatVisitor(final JsonFormatVisitorWrapper visitor, final JavaType hint) 31 | throws JsonMappingException { 32 | visitor.expectStringFormat(hint); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/DecimalAmountWriter.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import javax.annotation.Nonnull; 4 | import javax.money.MonetaryAmount; 5 | import java.math.BigDecimal; 6 | import java.math.RoundingMode; 7 | 8 | final class DecimalAmountWriter implements BigDecimalAmountWriter { 9 | 10 | @Override 11 | public BigDecimal write(@Nonnull final MonetaryAmount amount) { 12 | final BigDecimal decimal = amount.getNumber().numberValueExact(BigDecimal.class); 13 | final int defaultFractionDigits = amount.getCurrency().getDefaultFractionDigits(); 14 | final int scale = Math.max(decimal.scale(), defaultFractionDigits); 15 | 16 | return decimal.setScale(scale, RoundingMode.UNNECESSARY); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/FieldNames.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.With; 6 | 7 | @AllArgsConstructor(staticName = "valueOf") 8 | @Getter 9 | final class FieldNames { 10 | 11 | static final FieldNames DEFAULT = FieldNames.valueOf("amount", "currency", "formatted"); 12 | 13 | @With 14 | private final String amount; 15 | 16 | @With 17 | private final String currency; 18 | 19 | @With 20 | private final String formatted; 21 | 22 | static FieldNames defaults() { 23 | return DEFAULT; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/MonetaryAmountDeserializer.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.core.JsonParseException; 4 | import com.fasterxml.jackson.core.JsonParser; 5 | import com.fasterxml.jackson.core.JsonToken; 6 | import com.fasterxml.jackson.databind.DeserializationContext; 7 | import com.fasterxml.jackson.databind.JsonDeserializer; 8 | import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; 9 | import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; 10 | 11 | import javax.annotation.Nullable; 12 | import javax.money.CurrencyUnit; 13 | import javax.money.MonetaryAmount; 14 | import java.io.IOException; 15 | import java.math.BigDecimal; 16 | import java.util.Arrays; 17 | 18 | import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; 19 | import static java.lang.String.format; 20 | 21 | final class MonetaryAmountDeserializer extends JsonDeserializer { 22 | 23 | private final MonetaryAmountFactory factory; 24 | private final FieldNames names; 25 | 26 | MonetaryAmountDeserializer(final MonetaryAmountFactory factory, final FieldNames names) { 27 | this.factory = factory; 28 | this.names = names; 29 | } 30 | 31 | @Override 32 | public Object deserializeWithType(final JsonParser parser, final DeserializationContext context, 33 | final TypeDeserializer deserializer) throws IOException { 34 | 35 | // effectively assuming no type information at all 36 | return deserialize(parser, context); 37 | } 38 | 39 | @Override 40 | public M deserialize(final JsonParser parser, final DeserializationContext context) throws IOException { 41 | BigDecimal amount = null; 42 | CurrencyUnit currency = null; 43 | 44 | while (parser.nextToken() != JsonToken.END_OBJECT) { 45 | final String field = parser.getCurrentName(); 46 | 47 | parser.nextToken(); 48 | 49 | if (field.equals(names.getAmount())) { 50 | amount = context.readValue(parser, BigDecimal.class); 51 | } else if (field.equals(names.getCurrency())) { 52 | currency = context.readValue(parser, CurrencyUnit.class); 53 | } else if (field.equals(names.getFormatted())) { 54 | //noinspection UnnecessaryContinue 55 | continue; 56 | } else if (context.isEnabled(FAIL_ON_UNKNOWN_PROPERTIES)) { 57 | throw UnrecognizedPropertyException.from(parser, MonetaryAmount.class, field, 58 | Arrays.asList(names.getAmount(), names.getCurrency(), names.getFormatted())); 59 | } else { 60 | parser.skipChildren(); 61 | } 62 | } 63 | 64 | checkPresent(parser, amount, names.getAmount()); 65 | checkPresent(parser, currency, names.getCurrency()); 66 | 67 | return factory.create(amount, currency); 68 | } 69 | 70 | private void checkPresent(final JsonParser parser, @Nullable final Object value, final String name) 71 | throws JsonParseException { 72 | if (value == null) { 73 | throw new JsonParseException(parser, format("Missing property: '%s'", name)); 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/MonetaryAmountFactory.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import org.apiguardian.api.API; 4 | 5 | import javax.money.CurrencyUnit; 6 | import javax.money.MonetaryAmount; 7 | 8 | import java.math.BigDecimal; 9 | 10 | import static org.apiguardian.api.API.Status.STABLE; 11 | 12 | @API(status = STABLE) 13 | @FunctionalInterface 14 | public interface MonetaryAmountFactory { 15 | 16 | M create(BigDecimal amount, CurrencyUnit currency); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/MonetaryAmountFormatFactory.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import org.apiguardian.api.API; 4 | 5 | import javax.annotation.Nullable; 6 | import javax.money.format.MonetaryAmountFormat; 7 | import java.util.Locale; 8 | 9 | import static org.apiguardian.api.API.Status.STABLE; 10 | 11 | @API(status = STABLE) 12 | @FunctionalInterface 13 | public interface MonetaryAmountFormatFactory { 14 | 15 | MonetaryAmountFormatFactory NONE = locale -> null; 16 | 17 | @Nullable 18 | MonetaryAmountFormat create(final Locale defaultLocale); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/MonetaryAmountSerializer.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator; 4 | import com.fasterxml.jackson.databind.JavaType; 5 | import com.fasterxml.jackson.databind.JsonMappingException; 6 | import com.fasterxml.jackson.databind.JsonSerializer; 7 | import com.fasterxml.jackson.databind.SerializerProvider; 8 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; 9 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor; 10 | import com.fasterxml.jackson.databind.jsontype.TypeSerializer; 11 | import com.fasterxml.jackson.databind.ser.std.StdSerializer; 12 | import com.fasterxml.jackson.databind.util.NameTransformer; 13 | 14 | import javax.annotation.Nullable; 15 | import javax.money.CurrencyUnit; 16 | import javax.money.MonetaryAmount; 17 | import javax.money.format.MonetaryAmountFormat; 18 | import java.io.IOException; 19 | import java.util.Locale; 20 | 21 | final class MonetaryAmountSerializer extends StdSerializer { 22 | 23 | private final FieldNames names; 24 | private final AmountWriter writer; 25 | private final MonetaryAmountFormatFactory factory; 26 | private final boolean isUnwrapping; 27 | private final NameTransformer nameTransformer; 28 | 29 | MonetaryAmountSerializer(final FieldNames names, final AmountWriter writer, 30 | final MonetaryAmountFormatFactory factory, boolean isUnwrapping, @Nullable final NameTransformer nameTransformer) { 31 | super(MonetaryAmount.class); 32 | this.writer = writer; 33 | this.factory = factory; 34 | this.names = names; 35 | this.isUnwrapping = isUnwrapping; 36 | this.nameTransformer = nameTransformer; 37 | } 38 | 39 | MonetaryAmountSerializer(final FieldNames names, final AmountWriter writer, 40 | final MonetaryAmountFormatFactory factory) { 41 | this(names, writer, factory, false, null); 42 | } 43 | 44 | @Override 45 | public void acceptJsonFormatVisitor(final JsonFormatVisitorWrapper wrapper, final JavaType hint) 46 | throws JsonMappingException { 47 | 48 | @Nullable final JsonObjectFormatVisitor visitor = wrapper.expectObjectFormat(hint); 49 | 50 | if (visitor == null) { 51 | return; 52 | } 53 | 54 | final SerializerProvider provider = wrapper.getProvider(); 55 | 56 | visitor.property(names.getAmount(), 57 | provider.findValueSerializer(writer.getType()), 58 | provider.constructType(writer.getType())); 59 | 60 | visitor.property(names.getCurrency(), 61 | provider.findValueSerializer(CurrencyUnit.class), 62 | provider.constructType(CurrencyUnit.class)); 63 | 64 | visitor.optionalProperty(names.getFormatted(), 65 | provider.findValueSerializer(String.class), 66 | provider.constructType(String.class)); 67 | } 68 | 69 | @Override 70 | public void serializeWithType(final MonetaryAmount value, final JsonGenerator generator, 71 | final SerializerProvider provider, final TypeSerializer serializer) throws IOException { 72 | 73 | // effectively assuming no type information at all 74 | serialize(value, generator, provider); 75 | } 76 | 77 | @Override 78 | public void serialize(final MonetaryAmount value, final JsonGenerator json, final SerializerProvider provider) 79 | throws IOException { 80 | 81 | final CurrencyUnit currency = value.getCurrency(); 82 | @Nullable final String formatted = format(value, provider); 83 | 84 | if (!isUnwrapping) { 85 | json.writeStartObject(); 86 | } 87 | 88 | { 89 | provider.defaultSerializeField(transformName(names.getAmount()), writer.write(value), json); 90 | provider.defaultSerializeField(transformName(names.getCurrency()), currency, json); 91 | 92 | if (formatted != null) { 93 | provider.defaultSerializeField(transformName(names.getFormatted()), formatted, json); 94 | } 95 | } 96 | 97 | if (!isUnwrapping) { 98 | json.writeEndObject(); 99 | } 100 | } 101 | 102 | private String transformName(String name) { 103 | return (nameTransformer != null) ? nameTransformer.transform(name) : name; 104 | } 105 | 106 | @Nullable 107 | private String format(final MonetaryAmount value, final SerializerProvider provider) { 108 | final Locale locale = provider.getConfig().getLocale(); 109 | final MonetaryAmountFormat format = factory.create(locale); 110 | return format == null ? null : format.format(value); 111 | } 112 | 113 | @Override 114 | public boolean isUnwrappingSerializer() { 115 | return isUnwrapping; 116 | } 117 | 118 | @Override 119 | public JsonSerializer unwrappingSerializer(@Nullable final NameTransformer nameTransformer) { 120 | return new MonetaryAmountSerializer(names, writer, factory, true, nameTransformer); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/MoneyModule.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.core.Version; 4 | import com.fasterxml.jackson.core.util.VersionUtil; 5 | import com.fasterxml.jackson.databind.Module; 6 | import com.fasterxml.jackson.databind.module.SimpleDeserializers; 7 | import com.fasterxml.jackson.databind.module.SimpleSerializers; 8 | import org.apiguardian.api.API; 9 | import org.javamoney.moneta.FastMoney; 10 | import org.javamoney.moneta.Money; 11 | import org.javamoney.moneta.RoundedMoney; 12 | 13 | import javax.money.CurrencyUnit; 14 | import javax.money.MonetaryAmount; 15 | import javax.money.MonetaryOperator; 16 | import javax.money.MonetaryRounding; 17 | import javax.money.format.MonetaryFormats; 18 | 19 | import static org.apiguardian.api.API.Status.EXPERIMENTAL; 20 | import static org.apiguardian.api.API.Status.STABLE; 21 | 22 | @API(status = STABLE) 23 | public final class MoneyModule extends Module { 24 | 25 | private final AmountWriter writer; 26 | private final FieldNames names; 27 | private final MonetaryAmountFormatFactory formatFactory; 28 | private final MonetaryAmountFactory amountFactory; 29 | private final MonetaryAmountFactory fastMoneyFactory; 30 | private final MonetaryAmountFactory moneyFactory; 31 | private final MonetaryAmountFactory roundedMoneyFactory; 32 | 33 | public MoneyModule() { 34 | this(new DecimalAmountWriter(), FieldNames.defaults(), MonetaryAmountFormatFactory.NONE, 35 | Money::of, FastMoney::of, Money::of, RoundedMoney::of); 36 | } 37 | 38 | private MoneyModule(final AmountWriter writer, 39 | final FieldNames names, 40 | final MonetaryAmountFormatFactory formatFactory, 41 | final MonetaryAmountFactory amountFactory, 42 | final MonetaryAmountFactory fastMoneyFactory, 43 | final MonetaryAmountFactory moneyFactory, 44 | final MonetaryAmountFactory roundedMoneyFactory) { 45 | 46 | this.writer = writer; 47 | this.names = names; 48 | this.formatFactory = formatFactory; 49 | this.amountFactory = amountFactory; 50 | this.fastMoneyFactory = fastMoneyFactory; 51 | this.moneyFactory = moneyFactory; 52 | this.roundedMoneyFactory = roundedMoneyFactory; 53 | } 54 | 55 | @Override 56 | public String getModuleName() { 57 | return MoneyModule.class.getSimpleName(); 58 | } 59 | 60 | @Override 61 | @SuppressWarnings("deprecation") 62 | public Version version() { 63 | final ClassLoader loader = MoneyModule.class.getClassLoader(); 64 | return VersionUtil.mavenVersionFor(loader, "org.zalando", "jackson-datatype-money"); 65 | } 66 | 67 | @Override 68 | public void setupModule(final SetupContext context) { 69 | final SimpleSerializers serializers = new SimpleSerializers(); 70 | serializers.addSerializer(CurrencyUnit.class, new CurrencyUnitSerializer()); 71 | serializers.addSerializer(MonetaryAmount.class, new MonetaryAmountSerializer(names, writer, formatFactory)); 72 | context.addSerializers(serializers); 73 | 74 | final SimpleDeserializers deserializers = new SimpleDeserializers(); 75 | deserializers.addDeserializer(CurrencyUnit.class, new CurrencyUnitDeserializer()); 76 | deserializers.addDeserializer(MonetaryAmount.class, new MonetaryAmountDeserializer<>(amountFactory, names)); 77 | // for reading into concrete implementation types 78 | deserializers.addDeserializer(Money.class, new MonetaryAmountDeserializer<>(moneyFactory, names)); 79 | deserializers.addDeserializer(FastMoney.class, new MonetaryAmountDeserializer<>(fastMoneyFactory, names)); 80 | deserializers.addDeserializer(RoundedMoney.class, new MonetaryAmountDeserializer<>(roundedMoneyFactory, names)); 81 | context.addDeserializers(deserializers); 82 | } 83 | 84 | public MoneyModule withDecimalNumbers() { 85 | return withNumbers(new DecimalAmountWriter()); 86 | } 87 | 88 | public MoneyModule withQuotedDecimalNumbers() { 89 | return withNumbers(new QuotedDecimalAmountWriter()); 90 | } 91 | 92 | @API(status = EXPERIMENTAL) 93 | public MoneyModule withNumbers(final AmountWriter writer) { 94 | return new MoneyModule(writer, names, formatFactory, amountFactory, 95 | fastMoneyFactory, moneyFactory, roundedMoneyFactory); 96 | } 97 | 98 | /** 99 | * @see FastMoney 100 | * @return new {@link MoneyModule} using {@link FastMoney} 101 | */ 102 | public MoneyModule withFastMoney() { 103 | return withMonetaryAmount(fastMoneyFactory); 104 | } 105 | 106 | /** 107 | * @see Money 108 | * @return new {@link MoneyModule} using {@link Money} 109 | */ 110 | public MoneyModule withMoney() { 111 | return withMonetaryAmount(moneyFactory); 112 | } 113 | 114 | /** 115 | * @see RoundedMoney 116 | * @return new {@link MoneyModule} using {@link RoundedMoney} 117 | */ 118 | public MoneyModule withRoundedMoney() { 119 | return withMonetaryAmount(roundedMoneyFactory); 120 | } 121 | 122 | /** 123 | * @see RoundedMoney 124 | * @param rounding the rounding operator 125 | * @return new {@link MoneyModule} using {@link RoundedMoney} with the given {@link MonetaryRounding} 126 | */ 127 | public MoneyModule withRoundedMoney(final MonetaryOperator rounding) { 128 | final MonetaryAmountFactory factory = (amount, currency) -> 129 | RoundedMoney.of(amount, currency, rounding); 130 | 131 | return new MoneyModule(writer, names, formatFactory, factory, 132 | fastMoneyFactory, moneyFactory, factory); 133 | } 134 | 135 | public MoneyModule withMonetaryAmount(final MonetaryAmountFactory amountFactory) { 136 | return new MoneyModule(writer, names, formatFactory, amountFactory, 137 | fastMoneyFactory, moneyFactory, roundedMoneyFactory); 138 | } 139 | 140 | public MoneyModule withoutFormatting() { 141 | return withFormatting(MonetaryAmountFormatFactory.NONE); 142 | } 143 | 144 | public MoneyModule withDefaultFormatting() { 145 | return withFormatting(MonetaryFormats::getAmountFormat); 146 | } 147 | 148 | public MoneyModule withFormatting(final MonetaryAmountFormatFactory formatFactory) { 149 | return new MoneyModule(writer, names, formatFactory, amountFactory, 150 | fastMoneyFactory, moneyFactory, roundedMoneyFactory); 151 | } 152 | 153 | public MoneyModule withAmountFieldName(final String name) { 154 | return withFieldNames(names.withAmount(name)); 155 | } 156 | 157 | public MoneyModule withCurrencyFieldName(final String name) { 158 | return withFieldNames(names.withCurrency(name)); 159 | } 160 | 161 | public MoneyModule withFormattedFieldName(final String name) { 162 | return withFieldNames(names.withFormatted(name)); 163 | } 164 | 165 | private MoneyModule withFieldNames(final FieldNames names) { 166 | return new MoneyModule(writer, names, formatFactory, amountFactory, 167 | fastMoneyFactory, moneyFactory, roundedMoneyFactory); 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/QuotedDecimalAmountWriter.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import javax.money.MonetaryAmount; 4 | import java.math.BigDecimal; 5 | 6 | final class QuotedDecimalAmountWriter implements AmountWriter { 7 | 8 | private final AmountWriter delegate = new DecimalAmountWriter(); 9 | 10 | @Override 11 | public Class getType() { 12 | return String.class; 13 | } 14 | 15 | @Override 16 | public String write(final MonetaryAmount amount) { 17 | return delegate.write(amount).toPlainString(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/zalando/jackson/datatype/money/package-info.java: -------------------------------------------------------------------------------- 1 | @ParametersAreNonnullByDefault 2 | package org.zalando.jackson.datatype.money; 3 | 4 | import javax.annotation.ParametersAreNonnullByDefault; -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module: -------------------------------------------------------------------------------- 1 | org.zalando.jackson.datatype.money.MoneyModule -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/CurrencyUnitDeserializerTest.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; 5 | import org.javamoney.moneta.CurrencyUnitBuilder; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import javax.money.CurrencyUnit; 9 | import javax.money.UnknownCurrencyException; 10 | import java.io.IOException; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | import static org.junit.jupiter.api.Assertions.assertThrows; 14 | 15 | final class CurrencyUnitDeserializerTest { 16 | 17 | private final ObjectMapper unit = new ObjectMapper().findAndRegisterModules(); 18 | 19 | @Test 20 | void shouldDeserialize() throws IOException { 21 | final CurrencyUnit actual = unit.readValue("\"EUR\"", CurrencyUnit.class); 22 | final CurrencyUnit expected = CurrencyUnitBuilder.of("EUR", "default").build(); 23 | 24 | assertThat(actual).isEqualTo(expected); 25 | } 26 | 27 | @Test 28 | void shouldNotDeserializeInvalidCurrency() { 29 | assertThrows(UnknownCurrencyException.class, () -> 30 | unit.readValue("\"FOO\"", CurrencyUnit.class)); 31 | } 32 | 33 | @Test 34 | void shouldDeserializeWithTyping() throws IOException { 35 | unit.activateDefaultTyping(BasicPolymorphicTypeValidator.builder().build()); 36 | 37 | final CurrencyUnit actual = unit.readValue("\"EUR\"", CurrencyUnit.class); 38 | final CurrencyUnit expected = CurrencyUnitBuilder.of("EUR", "default").build(); 39 | 40 | assertThat(actual).isEqualTo(expected); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/CurrencyUnitSchemaSerializerTest.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.module.jsonSchema.JsonSchema; 5 | import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import javax.money.CurrencyUnit; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | final class CurrencyUnitSchemaSerializerTest { 13 | 14 | private final ObjectMapper unit = new ObjectMapper().findAndRegisterModules(); 15 | 16 | @Test 17 | void shouldSerializeJsonSchema() throws Exception { 18 | JsonSchemaGenerator generator = new JsonSchemaGenerator(unit); 19 | JsonSchema jsonSchema = generator.generateSchema(CurrencyUnit.class); 20 | final String actual = unit.writeValueAsString(jsonSchema); 21 | final String expected = "{\"type\":\"string\"}"; 22 | 23 | assertThat(actual).isEqualTo(expected); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/CurrencyUnitSerializerTest.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import org.javamoney.moneta.CurrencyUnitBuilder; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import javax.money.CurrencyUnit; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | 13 | final class CurrencyUnitSerializerTest { 14 | 15 | private final ObjectMapper unit = new ObjectMapper().findAndRegisterModules(); 16 | 17 | @Test 18 | void shouldSerialize() throws JsonProcessingException { 19 | final String expected = "EUR"; 20 | final CurrencyUnit currency = CurrencyUnitBuilder.of(expected, "default").build(); 21 | 22 | final String actual = unit.writeValueAsString(currency); 23 | 24 | assertThat(actual).isEqualTo('"' + expected + '"'); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/FieldNamesTest.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | final class FieldNamesTest { 8 | 9 | @Test 10 | void shouldOptimizeWithMethods() { 11 | final FieldNames expected = FieldNames.defaults(); 12 | final FieldNames actual = expected 13 | .withAmount(expected.getAmount()) 14 | .withCurrency(expected.getCurrency()) 15 | .withFormatted(expected.getFormatted()); 16 | 17 | assertThat(actual).isSameAs(expected); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/MonetaryAmountDeserializerTest.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 4 | import com.fasterxml.jackson.core.JsonProcessingException; 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import com.fasterxml.jackson.databind.Module; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; 9 | import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; 10 | import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; 11 | import org.javamoney.moneta.FastMoney; 12 | import org.javamoney.moneta.Money; 13 | import org.javamoney.moneta.RoundedMoney; 14 | import org.junit.jupiter.params.ParameterizedTest; 15 | import org.junit.jupiter.params.provider.Arguments; 16 | import org.junit.jupiter.params.provider.MethodSource; 17 | 18 | import javax.money.Monetary; 19 | import javax.money.MonetaryAmount; 20 | import java.io.IOException; 21 | import java.math.BigDecimal; 22 | import java.util.Arrays; 23 | 24 | import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | import static org.junit.jupiter.api.Assertions.assertThrows; 27 | 28 | final class MonetaryAmountDeserializerTest { 29 | 30 | static Iterable data() { 31 | return Arrays.asList( 32 | of(MonetaryAmount.class, module -> module), 33 | of(FastMoney.class, MoneyModule::withFastMoney), 34 | of(Money.class, MoneyModule::withMoney), 35 | of(RoundedMoney.class, MoneyModule::withRoundedMoney), 36 | of(RoundedMoney.class, module -> module.withRoundedMoney(Monetary.getDefaultRounding())) 37 | ); 38 | } 39 | 40 | private static Arguments of(final Class type, final Configurer configurer) { 41 | return Arguments.of(type, configurer); 42 | } 43 | 44 | private interface Configurer { 45 | MoneyModule configure(MoneyModule module); 46 | } 47 | 48 | private ObjectMapper unit(final Configurer configurer) { 49 | return unit(module(configurer)); 50 | } 51 | 52 | private ObjectMapper unit(final Module module) { 53 | return new ObjectMapper().registerModule(module); 54 | } 55 | 56 | private MoneyModule module(final Configurer configurer) { 57 | return configurer.configure(new MoneyModule()); 58 | } 59 | 60 | @ParameterizedTest 61 | @MethodSource("data") 62 | void shouldDeserializeMoneyByDefault() throws IOException { 63 | final ObjectMapper unit = new ObjectMapper().findAndRegisterModules(); 64 | 65 | final String content = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 66 | final MonetaryAmount amount = unit.readValue(content, MonetaryAmount.class); 67 | 68 | assertThat(amount).isInstanceOf(Money.class); 69 | } 70 | 71 | @ParameterizedTest 72 | @MethodSource("data") 73 | void shouldDeserializeToCorrectType(final Class type, final Configurer configurer) throws IOException { 74 | final ObjectMapper unit = unit(configurer); 75 | 76 | final String content = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 77 | final MonetaryAmount amount = unit.readValue(content, type); 78 | 79 | assertThat(amount).isInstanceOf(type); 80 | } 81 | 82 | @ParameterizedTest 83 | @MethodSource("data") 84 | void shouldDeserialize(final Class type, final Configurer configurer) throws IOException { 85 | final ObjectMapper unit = unit(configurer); 86 | 87 | final String content = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 88 | final MonetaryAmount amount = unit.readValue(content, type); 89 | 90 | assertThat(amount.getNumber().numberValueExact(BigDecimal.class)).isEqualTo(new BigDecimal("29.95")); 91 | assertThat(amount.getCurrency().getCurrencyCode()).isEqualTo("EUR"); 92 | } 93 | 94 | @ParameterizedTest 95 | @MethodSource("data") 96 | void shouldDeserializeWithHighNumberOfFractionDigits(final Class type, 97 | final Configurer configurer) throws IOException { 98 | final ObjectMapper unit = unit(configurer); 99 | 100 | final String content = "{\"amount\":29.9501,\"currency\":\"EUR\"}"; 101 | final MonetaryAmount amount = unit.readValue(content, type); 102 | 103 | assertThat(amount.getNumber().numberValueExact(BigDecimal.class)).isEqualTo(new BigDecimal("29.9501")); 104 | assertThat(amount.getCurrency().getCurrencyCode()).isEqualTo("EUR"); 105 | } 106 | 107 | @ParameterizedTest 108 | @MethodSource("data") 109 | void shouldDeserializeCorrectlyWhenAmountIsAStringValue(final Class type, 110 | final Configurer configurer) throws IOException { 111 | final ObjectMapper unit = unit(configurer); 112 | 113 | final String content = "{\"currency\":\"EUR\",\"amount\":\"29.95\"}"; 114 | final MonetaryAmount amount = unit.readValue(content, type); 115 | 116 | assertThat(amount.getNumber().numberValueExact(BigDecimal.class)).isEqualTo(new BigDecimal("29.95")); 117 | assertThat(amount.getCurrency().getCurrencyCode()).isEqualTo(("EUR")); 118 | } 119 | 120 | @ParameterizedTest 121 | @MethodSource("data") 122 | void shouldDeserializeCorrectlyWhenPropertiesAreInDifferentOrder(final Class type, 123 | final Configurer configurer) throws IOException { 124 | final ObjectMapper unit = unit(configurer); 125 | 126 | final String content = "{\"currency\":\"EUR\",\"amount\":29.95}"; 127 | final MonetaryAmount amount = unit.readValue(content, type); 128 | 129 | assertThat(amount.getNumber().numberValueExact(BigDecimal.class)).isEqualTo((new BigDecimal("29.95"))); 130 | assertThat(amount.getCurrency().getCurrencyCode()).isEqualTo(("EUR")); 131 | } 132 | 133 | @ParameterizedTest 134 | @MethodSource("data") 135 | void shouldDeserializeWithCustomNames(final Class type, final Configurer configurer) throws IOException { 136 | final ObjectMapper unit = unit(module(configurer) 137 | .withAmountFieldName("value") 138 | .withCurrencyFieldName("unit")); 139 | 140 | final String content = "{\"value\":29.95,\"unit\":\"EUR\"}"; 141 | final MonetaryAmount amount = unit.readValue(content, type); 142 | 143 | assertThat(amount.getNumber().numberValueExact(BigDecimal.class)).isEqualTo((new BigDecimal("29.95"))); 144 | assertThat(amount.getCurrency().getCurrencyCode()).isEqualTo(("EUR")); 145 | } 146 | 147 | @ParameterizedTest 148 | @MethodSource("data") 149 | void shouldIgnoreFormattedValue(final Class type, final Configurer configurer) throws IOException { 150 | final ObjectMapper unit = unit(configurer); 151 | 152 | final String content = "{\"amount\":29.95,\"currency\":\"EUR\",\"formatted\":\"30.00 EUR\"}"; 153 | final MonetaryAmount amount = unit.readValue(content, type); 154 | 155 | assertThat(amount.getNumber().numberValueExact(BigDecimal.class)).isEqualTo((new BigDecimal("29.95"))); 156 | assertThat(amount.getCurrency().getCurrencyCode()).isEqualTo(("EUR")); 157 | } 158 | 159 | @ParameterizedTest 160 | @MethodSource("data") 161 | void shouldUpdateExistingValueUsingTreeTraversingParser(final Class type, 162 | final Configurer configurer) throws IOException { 163 | final ObjectMapper unit = unit(configurer); 164 | 165 | final String content = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 166 | final MonetaryAmount amount = unit.readValue(content, type); 167 | 168 | assertThat(amount).isNotNull(); 169 | 170 | // we need a json node to get a TreeTraversingParser with codec of type ObjectReader 171 | final JsonNode ownerNode = 172 | unit.readTree("{\"value\":{\"amount\":29.95,\"currency\":\"EUR\",\"formatted\":\"30.00EUR\"}}"); 173 | 174 | final Owner owner = new Owner(); 175 | owner.setValue(amount); 176 | 177 | // try to update 178 | final Owner result = unit.readerForUpdating(owner).readValue(ownerNode); 179 | assertThat(result).isNotNull(); 180 | assertThat(result.getValue()).isEqualTo((amount)); 181 | } 182 | 183 | private static class Owner { 184 | 185 | private MonetaryAmount value; 186 | 187 | MonetaryAmount getValue() { 188 | return value; 189 | } 190 | 191 | void setValue(final MonetaryAmount value) { 192 | this.value = value; 193 | } 194 | 195 | } 196 | 197 | @ParameterizedTest 198 | @MethodSource("data") 199 | void shouldFailToDeserializeWithoutAmount(final Class type, final Configurer configurer) { 200 | final ObjectMapper unit = unit(configurer); 201 | 202 | final String content = "{\"currency\":\"EUR\"}"; 203 | 204 | final JsonProcessingException exception = assertThrows( 205 | JsonProcessingException.class, () -> unit.readValue(content, type)); 206 | 207 | assertThat(exception.getMessage()).contains("Missing property: 'amount'"); 208 | } 209 | 210 | @ParameterizedTest 211 | @MethodSource("data") 212 | void shouldFailToDeserializeWithoutCurrency(final Class type, final Configurer configurer) { 213 | final ObjectMapper unit = unit(configurer); 214 | 215 | final String content = "{\"amount\":29.95}"; 216 | 217 | final JsonProcessingException exception = assertThrows( 218 | JsonProcessingException.class, () -> unit.readValue(content, type)); 219 | 220 | assertThat(exception.getMessage()).contains("Missing property: 'currency'"); 221 | } 222 | 223 | @ParameterizedTest 224 | @MethodSource("data") 225 | void shouldFailToDeserializeWithAdditionalProperties(final Class type, 226 | final Configurer configurer) { 227 | final ObjectMapper unit = unit(configurer); 228 | 229 | final String content = "{\"amount\":29.95,\"currency\":\"EUR\",\"version\":\"1\"}"; 230 | 231 | final JsonProcessingException exception = assertThrows( 232 | UnrecognizedPropertyException.class, () -> unit.readValue(content, type)); 233 | 234 | assertThat(exception.getMessage()).startsWith( 235 | "Unrecognized field \"version\" (class javax.money.MonetaryAmount), " + 236 | "not marked as ignorable (3 known properties: \"amount\", \"currency\", \"formatted\"])"); 237 | } 238 | 239 | @ParameterizedTest 240 | @MethodSource("data") 241 | void shouldNotFailToDeserializeWithAdditionalProperties(final Class type, 242 | final Configurer configurer) throws IOException { 243 | final ObjectMapper unit = unit(configurer).disable(FAIL_ON_UNKNOWN_PROPERTIES); 244 | 245 | final String content = "{\"source\":{\"provider\":\"ECB\",\"date\":\"2016-09-29\"},\"amount\":29.95,\"currency\":\"EUR\",\"version\":\"1\"}"; 246 | unit.readValue(content, type); 247 | } 248 | 249 | @ParameterizedTest 250 | @MethodSource("data") 251 | void shouldDeserializeWithTypeInformation(final Class type, final Configurer configurer) throws IOException { 252 | final ObjectMapper unit = unit(configurer) 253 | .activateDefaultTyping( 254 | BasicPolymorphicTypeValidator.builder().build(), 255 | DefaultTyping.OBJECT_AND_NON_CONCRETE, 256 | JsonTypeInfo.As.EXISTING_PROPERTY) 257 | .disable(FAIL_ON_UNKNOWN_PROPERTIES); 258 | 259 | final String content = "{\"type\":\"org.javamoney.moneta.Money\",\"amount\":29.95,\"currency\":\"EUR\"}"; 260 | final M amount = unit.readValue(content, type); 261 | 262 | // type information is ignored?! 263 | assertThat(amount).isInstanceOf(type); 264 | } 265 | 266 | @ParameterizedTest 267 | @MethodSource("data") 268 | void shouldDeserializeWithoutTypeInformation(final Class type, final Configurer configurer) throws IOException { 269 | final ObjectMapper unit = unit(configurer).activateDefaultTyping( 270 | BasicPolymorphicTypeValidator.builder().build()); 271 | 272 | final String content = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 273 | final M amount = unit.readValue(content, type); 274 | 275 | assertThat(amount).isInstanceOf(type); 276 | } 277 | 278 | } 279 | -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/MonetaryAmountSchemaSerializerTest.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.Module; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import com.fasterxml.jackson.module.jsonSchema.JsonSchema; 7 | import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import javax.money.MonetaryAmount; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | 14 | final class MonetaryAmountSchemaSerializerTest { 15 | 16 | @Test 17 | void shouldSerializeJsonSchema() throws Exception { 18 | final ObjectMapper unit = unit(module()); 19 | final JsonSchemaGenerator generator = new JsonSchemaGenerator(unit); 20 | final JsonSchema jsonSchema = generator.generateSchema(MonetaryAmount.class); 21 | final String actual = unit.writeValueAsString(jsonSchema); 22 | final String expected = "{\"type\":\"object\",\"id\":\"urn:jsonschema:javax:money:MonetaryAmount\",\"properties\":" + 23 | "{\"amount\":{\"type\":\"number\",\"required\":true}," + 24 | "\"currency\":{\"type\":\"string\",\"required\":true}," + 25 | "\"formatted\":{\"type\":\"string\"}}}"; 26 | 27 | assertThat(actual).isEqualTo(expected); 28 | } 29 | 30 | @Test 31 | void shouldSerializeJsonSchemaWithCustomFieldNames() throws Exception { 32 | final ObjectMapper unit = unit(module().withAmountFieldName("value") 33 | .withCurrencyFieldName("unit") 34 | .withFormattedFieldName("pretty")); 35 | final JsonSchemaGenerator generator = new JsonSchemaGenerator(unit); 36 | final JsonSchema jsonSchema = generator.generateSchema(MonetaryAmount.class); 37 | final String actual = unit.writeValueAsString(jsonSchema); 38 | final String expected = "{\"type\":\"object\",\"id\":\"urn:jsonschema:javax:money:MonetaryAmount\",\"properties\":" + 39 | "{\"value\":{\"type\":\"number\",\"required\":true}," + 40 | "\"unit\":{\"type\":\"string\",\"required\":true}," + 41 | "\"pretty\":{\"type\":\"string\"}}}"; 42 | 43 | assertThat(actual).isEqualTo(expected); 44 | } 45 | 46 | @Test 47 | void shouldSerializeJsonSchemaWithQuotedDecimalNumbers() throws Exception { 48 | final ObjectMapper unit = unit(module().withQuotedDecimalNumbers()); 49 | final JsonSchemaGenerator generator = new JsonSchemaGenerator(unit); 50 | final JsonSchema jsonSchema = generator.generateSchema(MonetaryAmount.class); 51 | final String actual = unit.writeValueAsString(jsonSchema); 52 | final String expected = "{\"type\":\"object\",\"id\":\"urn:jsonschema:javax:money:MonetaryAmount\",\"properties\":" + 53 | "{\"amount\":{\"type\":\"string\",\"required\":true}," + 54 | "\"currency\":{\"type\":\"string\",\"required\":true}," + 55 | "\"formatted\":{\"type\":\"string\"}}}"; 56 | 57 | assertThat(actual).isEqualTo(expected); 58 | } 59 | 60 | @Test 61 | void shouldSerializeJsonSchemaWithMultipleMonetayAmountsAndAlternativeGenerator() throws Exception { 62 | final ObjectMapper unit = unit(module()); 63 | final com.kjetland.jackson.jsonSchema.JsonSchemaGenerator generator = 64 | new com.kjetland.jackson.jsonSchema.JsonSchemaGenerator(unit); 65 | 66 | final JsonNode jsonSchema = generator.generateJsonSchema(SchemaTestClass.class); 67 | 68 | final String actual = unit.writeValueAsString(jsonSchema); 69 | final String expected = "{\"$schema\":\"http://json-schema.org/draft-04/schema#\",\"title\":\"Schema Test Class\"," + 70 | "\"type\":\"object\",\"additionalProperties\":false,\"properties\":{\"moneyOne\":{\"$ref\":" + 71 | "\"#/definitions/MonetaryAmount\"},\"moneyTwo\":{\"$ref\":\"#/definitions/MonetaryAmount\"}}," + 72 | "\"definitions\":{\"MonetaryAmount\":{\"type\":\"object\",\"additionalProperties\":false,\"properties\"" + 73 | ":{\"amount\":{\"type\":\"number\"},\"currency\":{\"type\":\"string\"},\"formatted\":" + 74 | "{\"type\":\"string\"}},\"required\":[\"amount\",\"currency\"]}}}"; 75 | 76 | assertThat(actual).isEqualTo(expected); 77 | } 78 | 79 | private ObjectMapper unit(final Module module) { 80 | return new ObjectMapper().registerModule(module); 81 | } 82 | 83 | private MoneyModule module() { 84 | return new MoneyModule(); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/MonetaryAmountSerializerTest.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import com.fasterxml.jackson.annotation.JsonUnwrapped; 4 | import com.fasterxml.jackson.core.JsonGenerator; 5 | import com.fasterxml.jackson.core.JsonProcessingException; 6 | import com.fasterxml.jackson.core.json.JsonWriteFeature; 7 | import com.fasterxml.jackson.databind.Module; 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | import com.fasterxml.jackson.databind.ObjectWriter; 10 | import com.fasterxml.jackson.databind.SerializationFeature; 11 | import com.fasterxml.jackson.databind.json.JsonMapper; 12 | import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; 13 | import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; 14 | import com.fasterxml.jackson.databind.type.SimpleType; 15 | import lombok.Value; 16 | import org.javamoney.moneta.FastMoney; 17 | import org.javamoney.moneta.Money; 18 | import org.javamoney.moneta.RoundedMoney; 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.params.ParameterizedTest; 21 | import org.junit.jupiter.params.provider.MethodSource; 22 | 23 | import javax.money.MonetaryAmount; 24 | import java.io.IOException; 25 | import java.math.BigDecimal; 26 | import java.util.Arrays; 27 | import java.util.Locale; 28 | 29 | import static javax.money.Monetary.getDefaultRounding; 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | import static org.mockito.Mockito.mock; 32 | 33 | final class MonetaryAmountSerializerTest { 34 | 35 | static Iterable amounts() { 36 | return Arrays.asList( 37 | FastMoney.of(29.95, "EUR"), 38 | Money.of(29.95, "EUR"), 39 | RoundedMoney.of(29.95, "EUR", getDefaultRounding())); 40 | } 41 | 42 | static Iterable hundreds() { 43 | return Arrays.asList( 44 | FastMoney.of(100, "EUR"), 45 | Money.of(100, "EUR"), 46 | RoundedMoney.of(100, "EUR", getDefaultRounding())); 47 | } 48 | 49 | static Iterable fractions() { 50 | return Arrays.asList( 51 | FastMoney.of(0.0001, "EUR"), 52 | Money.of(0.0001, "EUR"), 53 | RoundedMoney.of(0.0001, "EUR", getDefaultRounding())); 54 | } 55 | 56 | private ObjectMapper unit() { 57 | return unit(module()); 58 | } 59 | 60 | private ObjectMapper unit(final Module module) { 61 | return build(module).build(); 62 | } 63 | 64 | private JsonMapper.Builder build() { 65 | return build(module()); 66 | } 67 | 68 | private JsonMapper.Builder build(final Module module) { 69 | return JsonMapper.builder() 70 | .addModule(module); 71 | } 72 | 73 | private MoneyModule module() { 74 | return new MoneyModule(); 75 | } 76 | 77 | @ParameterizedTest 78 | @MethodSource("amounts") 79 | void shouldSerialize(final MonetaryAmount amount) throws JsonProcessingException { 80 | final ObjectMapper unit = unit(); 81 | 82 | final String expected = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 83 | final String actual = unit.writeValueAsString(amount); 84 | 85 | assertThat(actual).isEqualTo(expected); 86 | } 87 | 88 | @ParameterizedTest 89 | @MethodSource("amounts") 90 | void shouldSerializeWithoutFormattedValueIfFactoryProducesNull( 91 | final MonetaryAmount amount) throws JsonProcessingException { 92 | final ObjectMapper unit = unit(module().withoutFormatting()); 93 | 94 | final String expected = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 95 | final String actual = unit.writeValueAsString(amount); 96 | 97 | assertThat(actual).isEqualTo(expected); 98 | } 99 | 100 | @ParameterizedTest 101 | @MethodSource("amounts") 102 | void shouldSerializeWithFormattedGermanValue(final MonetaryAmount amount) throws JsonProcessingException { 103 | final ObjectMapper unit = unit(new MoneyModule().withDefaultFormatting()); 104 | 105 | final String expected = "{\"amount\":29.95,\"currency\":\"EUR\",\"formatted\":\"29,95 EUR\"}"; 106 | 107 | final ObjectWriter writer = unit.writer().with(Locale.GERMANY); 108 | final String actual = writer.writeValueAsString(amount); 109 | 110 | assertThat(actual).isEqualTo(expected); 111 | } 112 | 113 | @ParameterizedTest 114 | @MethodSource("amounts") 115 | void shouldSerializeWithFormattedAmericanValue(final MonetaryAmount amount) throws JsonProcessingException { 116 | final ObjectMapper unit = unit(module().withDefaultFormatting()); 117 | 118 | final String expected = "{\"amount\":29.95,\"currency\":\"USD\",\"formatted\":\"USD29.95\"}"; 119 | 120 | final ObjectWriter writer = unit.writer().with(Locale.US); 121 | final String actual = writer.writeValueAsString(amount.getFactory().setCurrency("USD").create()); 122 | 123 | assertThat(actual).isEqualTo(expected); 124 | } 125 | 126 | @ParameterizedTest 127 | @MethodSource("amounts") 128 | void shouldSerializeWithCustomName(final MonetaryAmount amount) throws IOException { 129 | final ObjectMapper unit = unit(module().withDefaultFormatting() 130 | .withAmountFieldName("value") 131 | .withCurrencyFieldName("unit") 132 | .withFormattedFieldName("pretty")); 133 | 134 | final String expected = "{\"value\":29.95,\"unit\":\"EUR\",\"pretty\":\"29,95 EUR\"}"; 135 | 136 | final ObjectWriter writer = unit.writer().with(Locale.GERMANY); 137 | final String actual = writer.writeValueAsString(amount); 138 | 139 | assertThat(actual).isEqualTo(expected); 140 | } 141 | 142 | @ParameterizedTest 143 | @MethodSource("amounts") 144 | void shouldSerializeAmountAsDecimal(final MonetaryAmount amount) throws JsonProcessingException { 145 | final ObjectMapper unit = unit(module().withDecimalNumbers()); 146 | 147 | final String expected = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 148 | final String actual = unit.writeValueAsString(amount); 149 | 150 | assertThat(actual).isEqualTo(expected); 151 | } 152 | 153 | @ParameterizedTest 154 | @MethodSource("hundreds") 155 | void shouldSerializeAmountAsDecimalWithDefaultFractionDigits( 156 | final MonetaryAmount hundred) throws JsonProcessingException { 157 | final ObjectMapper unit = unit(module().withDecimalNumbers()); 158 | 159 | final String expected = "{\"amount\":100.00,\"currency\":\"EUR\"}"; 160 | final String actual = unit.writeValueAsString(hundred); 161 | 162 | assertThat(actual).isEqualTo(expected); 163 | } 164 | 165 | @ParameterizedTest 166 | @MethodSource("fractions") 167 | void shouldSerializeAmountAsDecimalWithHigherNumberOfFractionDigits( 168 | final MonetaryAmount fraction) throws JsonProcessingException { 169 | final ObjectMapper unit = unit(module().withDecimalNumbers()); 170 | 171 | final String expected = "{\"amount\":0.0001,\"currency\":\"EUR\"}"; 172 | final String actual = unit.writeValueAsString(fraction); 173 | 174 | assertThat(actual).isEqualTo(expected); 175 | } 176 | 177 | @ParameterizedTest 178 | @MethodSource("hundreds") 179 | void shouldSerializeAmountAsDecimalWithLowerNumberOfFractionDigits( 180 | final MonetaryAmount hundred) throws JsonProcessingException { 181 | final ObjectMapper unit = unit(module().withNumbers(new AmountWriter() { 182 | @Override 183 | public Class getType() { 184 | return BigDecimal.class; 185 | } 186 | 187 | @Override 188 | public BigDecimal write(final MonetaryAmount amount) { 189 | return amount.getNumber().numberValueExact(BigDecimal.class).stripTrailingZeros(); 190 | } 191 | })); 192 | 193 | final String expected = "{\"amount\":1E+2,\"currency\":\"EUR\"}"; 194 | final String actual = unit.writeValueAsString(hundred); 195 | 196 | assertThat(actual).isEqualTo(expected); 197 | } 198 | 199 | @ParameterizedTest 200 | @MethodSource("amounts") 201 | void shouldSerializeAmountAsQuotedDecimal(final MonetaryAmount amount) throws JsonProcessingException { 202 | final ObjectMapper unit = unit(module().withQuotedDecimalNumbers()); 203 | 204 | final String expected = "{\"amount\":\"29.95\",\"currency\":\"EUR\"}"; 205 | final String actual = unit.writeValueAsString(amount); 206 | 207 | assertThat(actual).isEqualTo(expected); 208 | } 209 | 210 | @ParameterizedTest 211 | @MethodSource("hundreds") 212 | void shouldSerializeAmountAsQuotedDecimalWithDefaultFractionDigits( 213 | final MonetaryAmount hundred) throws JsonProcessingException { 214 | final ObjectMapper unit = unit(module().withQuotedDecimalNumbers()); 215 | 216 | final String expected = "{\"amount\":\"100.00\",\"currency\":\"EUR\"}"; 217 | final String actual = unit.writeValueAsString(hundred); 218 | 219 | assertThat(actual).isEqualTo(expected); 220 | } 221 | 222 | @ParameterizedTest 223 | @MethodSource("fractions") 224 | void shouldSerializeAmountAsQuotedDecimalWithHigherNumberOfFractionDigits( 225 | final MonetaryAmount fraction) throws JsonProcessingException { 226 | final ObjectMapper unit = unit(module().withQuotedDecimalNumbers()); 227 | 228 | final String expected = "{\"amount\":\"0.0001\",\"currency\":\"EUR\"}"; 229 | final String actual = unit.writeValueAsString(fraction); 230 | 231 | assertThat(actual).isEqualTo(expected); 232 | } 233 | 234 | @ParameterizedTest 235 | @MethodSource("hundreds") 236 | void shouldSerializeAmountAsQuotedDecimalWithLowerNumberOfFractionDigits( 237 | final MonetaryAmount hundred) throws JsonProcessingException { 238 | final ObjectMapper unit = unit(module().withNumbers(new AmountWriter() { 239 | @Override 240 | public Class getType() { 241 | return String.class; 242 | } 243 | 244 | @Override 245 | public String write(final MonetaryAmount amount) { 246 | return amount.getNumber().numberValueExact(BigDecimal.class).stripTrailingZeros().toPlainString(); 247 | } 248 | })); 249 | 250 | final String expected = "{\"amount\":\"100\",\"currency\":\"EUR\"}"; 251 | final String actual = unit.writeValueAsString(hundred); 252 | 253 | assertThat(actual).isEqualTo(expected); 254 | } 255 | 256 | @ParameterizedTest 257 | @MethodSource("hundreds") 258 | void shouldSerializeAmountAsQuotedDecimalPlainString(final MonetaryAmount hundred) throws JsonProcessingException { 259 | final ObjectMapper unit = unit(module().withQuotedDecimalNumbers()); 260 | unit.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); 261 | 262 | final String expected = "{\"amount\":\"100.00\",\"currency\":\"EUR\"}"; 263 | final String actual = unit.writeValueAsString(hundred); 264 | 265 | assertThat(actual).isEqualTo(expected); 266 | } 267 | 268 | @ParameterizedTest 269 | @MethodSource("amounts") 270 | void shouldWriteNumbersAsStrings(final MonetaryAmount amount) throws JsonProcessingException { 271 | final ObjectMapper unit = build() 272 | .enable(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS) 273 | .build(); 274 | 275 | final String expected = "{\"amount\":\"29.95\",\"currency\":\"EUR\"}"; 276 | final String actual = unit.writeValueAsString(amount); 277 | 278 | assertThat(actual).isEqualTo(expected); 279 | } 280 | 281 | @ParameterizedTest 282 | @MethodSource("hundreds") 283 | void shouldWriteNumbersAsPlainStrings(final MonetaryAmount hundred) throws JsonProcessingException { 284 | final ObjectMapper unit = build() 285 | .enable(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS) 286 | .enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN) 287 | .build(); 288 | 289 | final String expected = "{\"amount\":\"100.00\",\"currency\":\"EUR\"}"; 290 | final String actual = unit.writeValueAsString(hundred); 291 | 292 | assertThat(actual).isEqualTo(expected); 293 | } 294 | 295 | @Value 296 | private static class Price { 297 | MonetaryAmount amount; 298 | } 299 | 300 | @ParameterizedTest 301 | @MethodSource("amounts") 302 | void shouldSerializeWithType(final MonetaryAmount amount) throws JsonProcessingException { 303 | final ObjectMapper unit = unit(module()).activateDefaultTyping(BasicPolymorphicTypeValidator.builder().build()); 304 | 305 | final String expected = "{\"amount\":{\"amount\":29.95,\"currency\":\"EUR\"}}"; 306 | final String actual = unit.writeValueAsString(new Price(amount)); 307 | 308 | assertThat(actual).isEqualTo(expected); 309 | } 310 | 311 | @Value 312 | private static class PriceUnwrapped { 313 | @JsonUnwrapped 314 | MonetaryAmount amount; 315 | } 316 | 317 | @ParameterizedTest 318 | @MethodSource("amounts") 319 | void shouldSerializeWithTypeUnwrapped(final MonetaryAmount amount) throws JsonProcessingException { 320 | final ObjectMapper unit = unit(module()).activateDefaultTyping(BasicPolymorphicTypeValidator.builder().build()); 321 | 322 | final String expected = "{\"amount\":29.95,\"currency\":\"EUR\"}"; 323 | final String actual = unit.writeValueAsString(new PriceUnwrapped(amount)); 324 | 325 | assertThat(actual).isEqualTo(expected); 326 | } 327 | 328 | @Value 329 | private static class PriceUnwrappedTransformedNames { 330 | @JsonUnwrapped(prefix = "Price-", suffix = "-Field") 331 | MonetaryAmount amount; 332 | } 333 | 334 | @ParameterizedTest 335 | @MethodSource("amounts") 336 | void shouldSerializeWithTypeUnwrappedAndNamesTransformed(final MonetaryAmount amount) throws JsonProcessingException { 337 | final ObjectMapper unit = unit(module()).activateDefaultTyping(BasicPolymorphicTypeValidator.builder().build()); 338 | 339 | final String expected = "{\"Price-amount-Field\":29.95,\"Price-currency-Field\":\"EUR\"}"; 340 | final String actual = unit.writeValueAsString(new PriceUnwrappedTransformedNames(amount)); 341 | 342 | assertThat(actual).isEqualTo(expected); 343 | } 344 | 345 | @Test 346 | void shouldHandleNullValueFromExpectObjectFormatInSchemaVisitor() throws Exception { 347 | final MonetaryAmountSerializer unit = new MonetaryAmountSerializer(FieldNames.defaults(), 348 | new DecimalAmountWriter(), MonetaryAmountFormatFactory.NONE); 349 | 350 | final JsonFormatVisitorWrapper wrapper = mock(JsonFormatVisitorWrapper.class); 351 | unit.acceptJsonFormatVisitor(wrapper, SimpleType.constructUnsafe(MonetaryAmount.class)); 352 | } 353 | 354 | /** 355 | * Fixes a bug that caused the amount field to be written as 356 | * 357 | * "amount": {"BigDecimal":12.34} 358 | * 359 | * @param amount 360 | * @throws JsonProcessingException 361 | */ 362 | @ParameterizedTest 363 | @MethodSource("amounts") 364 | void shouldSerializeWithWrapRootValue(final MonetaryAmount amount) throws JsonProcessingException { 365 | final ObjectMapper unit = unit(module()) 366 | .configure(SerializationFeature.WRAP_ROOT_VALUE, true); 367 | 368 | final String expected = "{\"Price\":{\"amount\":{\"amount\":29.95,\"currency\":\"EUR\"}}}"; 369 | final String actual = unit.writeValueAsString(new Price(amount)); 370 | 371 | assertThat(actual).isEqualTo(expected); 372 | } 373 | 374 | } 375 | -------------------------------------------------------------------------------- /src/test/java/org/zalando/jackson/datatype/money/SchemaTestClass.java: -------------------------------------------------------------------------------- 1 | package org.zalando.jackson.datatype.money; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | import javax.money.MonetaryAmount; 7 | 8 | @AllArgsConstructor 9 | @Getter 10 | public class SchemaTestClass { 11 | 12 | private final MonetaryAmount moneyOne; 13 | private final MonetaryAmount moneyTwo; 14 | 15 | } 16 | --------------------------------------------------------------------------------